diff --git a/scm/Mercurial.cpp b/scm/Mercurial.cpp index b911b5336198..8e37d80814a5 100644 --- a/scm/Mercurial.cpp +++ b/scm/Mercurial.cpp @@ -293,4 +293,29 @@ time_point Mercurial::convertCommitDate(const char* commitDate) { } return system_clock::from_time_t(date); } + +std::vector Mercurial::getCommitsPriorToAndIncluding( + w_string_piece commitId, + int numCommits, + w_string requestId) const { + auto revset = to( + "reverse(last(_firstancestors(", commitId, "), ", numCommits, "))\n"); + ChildProcess proc( + {hgExecutablePath(), "log", "-r", revset, "-T", "{node}\n"}, + makeHgOptions(requestId)); + auto outputs = proc.communicate(); + auto status = proc.wait(); + if (status) { + throw std::runtime_error(to( + "failed query for hg log; command returned with status ", + status, + " out=", + outputs.first, + " err=", + outputs.second)); + } + std::vector lines; + w_string_piece(outputs.first).split(lines, '\n'); + return lines; +} } // namespace watchman diff --git a/scm/Mercurial.h b/scm/Mercurial.h index 7b228da1d997..c31a1b40cd54 100644 --- a/scm/Mercurial.h +++ b/scm/Mercurial.h @@ -30,6 +30,10 @@ class Mercurial : public SCM { // public for testing static std::chrono::time_point convertCommitDate( const char* commitDate); + std::vector getCommitsPriorToAndIncluding( + w_string_piece commitId, + int numCommits, + w_string requestId = nullptr) const override; private: // Returns options for invoking hg diff --git a/scm/SCM.h b/scm/SCM.h index 1b7b83a4bd29..d1f7e0b0cb37 100644 --- a/scm/SCM.h +++ b/scm/SCM.h @@ -69,6 +69,14 @@ class SCM { w_string_piece commitId, w_string requestId = nullptr) const = 0; + // Compute the numCommits commits prior to and including the specified commit + // in source control history. Returns an ordered list with the most recent + // commit (the one specified) first. + virtual std::vector getCommitsPriorToAndIncluding( + w_string_piece commitId, + int numCommits, + w_string requestId = nullptr) const = 0; + private: w_string rootPath_; w_string scmRoot_; diff --git a/watcher/eden.cpp b/watcher/eden.cpp index 20cd988891b6..5d62b19a4bfc 100644 --- a/watcher/eden.cpp +++ b/watcher/eden.cpp @@ -567,6 +567,14 @@ class EdenWrappedSCM : public SCM { return inner_->getCommitDate(commitId, requestId); } + std::vector getCommitsPriorToAndIncluding( + w_string_piece commitId, + int numCommits, + w_string requestId = nullptr) const override { + return inner_->getCommitsPriorToAndIncluding( + commitId, numCommits, requestId); + } + static std::unique_ptr wrap(std::unique_ptr inner) { if (!inner) { return nullptr;