diff options
author | Brad King <brad.king@kitware.com> | 2010-06-08 20:37:04 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2010-06-08 20:50:17 (GMT) |
commit | c3781efb28a35f54ed6306354330734994f2c8b1 (patch) | |
tree | 3612ad00fb1dc19bf6e216fc19288c993f222765 /Source/CTest/cmCTestGIT.cxx | |
parent | 2eae651acc45c303008d9870a6a4f9da3d8bcf19 (diff) | |
download | CMake-c3781efb28a35f54ed6306354330734994f2c8b1.zip CMake-c3781efb28a35f54ed6306354330734994f2c8b1.tar.gz CMake-c3781efb28a35f54ed6306354330734994f2c8b1.tar.bz2 |
ctest_update: Support Git upstream branch rewrites
Use 'git fetch' followed by 'git reset' to update the source tree. This
is better than 'git pull' because it can handle a rewritten upstream
branch and does not leave local modifications. After fetch, parse
FETCH_HEAD to find the merge head that 'git pull' would choose to track
the upstream branch. Then reset to the selected head.
In the normal fast-forward case the behavior remains unchanged.
However, now local modifications and commits will be erased, and
upstream rewrites are handled smoothly. This ensures that the upstream
branch is tested as expected.
Diffstat (limited to 'Source/CTest/cmCTestGIT.cxx')
-rw-r--r-- | Source/CTest/cmCTestGIT.cxx | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 5972d39..6c3631c 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -85,16 +85,14 @@ void cmCTestGIT::NoteNewRevision() } //---------------------------------------------------------------------------- -bool cmCTestGIT::UpdateByPull() +bool cmCTestGIT::UpdateByFetchAndReset() { const char* git = this->CommandLineTool.c_str(); - // Use "git pull" to update the working tree. - std::vector<char const*> git_pull; - git_pull.push_back(git); - git_pull.push_back("pull"); - - // TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY) + // Use "git fetch" to get remote commits. + std::vector<char const*> git_fetch; + git_fetch.push_back(git); + git_fetch.push_back("fetch"); // Add user-specified update options. std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions"); @@ -106,15 +104,44 @@ bool cmCTestGIT::UpdateByPull() for(std::vector<cmStdString>::const_iterator ai = args.begin(); ai != args.end(); ++ai) { - git_pull.push_back(ai->c_str()); + git_fetch.push_back(ai->c_str()); } // Sentinel argument. - git_pull.push_back(0); + git_fetch.push_back(0); + + // Fetch upstream refs. + OutputLogger fetch_out(this->Log, "fetch-out> "); + OutputLogger fetch_err(this->Log, "fetch-err> "); + if(!this->RunUpdateCommand(&git_fetch[0], &fetch_out, &fetch_err)) + { + return false; + } + + // Identify the merge head that would be used by "git pull". + std::string sha1; + { + std::string fetch_head = this->SourceDirectory + "/.git/FETCH_HEAD"; + std::ifstream fin(fetch_head.c_str(), std::ios::in | std::ios::binary); + std::string line; + while(sha1.empty() && cmSystemTools::GetLineFromStream(fin, line)) + { + if(line.find("\tnot-for-merge\t") == line.npos) + { + std::string::size_type pos = line.find('\t'); + if(pos != line.npos) + { + sha1 = line.substr(0, pos); + } + } + } + } - OutputLogger out(this->Log, "pull-out> "); - OutputLogger err(this->Log, "pull-err> "); - return this->RunUpdateCommand(&git_pull[0], &out, &err); + // Reset the local branch to point at that tracked from upstream. + char const* git_reset[] = {git, "reset", "--hard", sha1.c_str(), 0}; + OutputLogger reset_out(this->Log, "reset-out> "); + OutputLogger reset_err(this->Log, "reset-err> "); + return this->RunChild(&git_reset[0], &reset_out, &reset_err); } //---------------------------------------------------------------------------- @@ -143,7 +170,7 @@ bool cmCTestGIT::UpdateInternal() { return this->UpdateByCustom(custom); } - return this->UpdateByPull(); + return this->UpdateByFetchAndReset(); } //---------------------------------------------------------------------------- |