Merge topic 'ctest-git-flexibility'

a7319cf ctest_update: Run 'git submodule' at top level
7bf8dc1 ctest_update: Support ".git file" work trees
65cb72f ctest_update: Abort if Git FETCH_HEAD has no candidates
This commit is contained in:
Brad King 2010-08-03 16:07:31 -04:00 committed by CMake Topic Stage
commit e6067ca969
3 changed files with 92 additions and 2 deletions

View File

@ -84,6 +84,75 @@ void cmCTestGIT::NoteNewRevision()
<< this->NewRevision << "\n"); << this->NewRevision << "\n");
} }
//----------------------------------------------------------------------------
std::string cmCTestGIT::FindGitDir()
{
std::string git_dir;
// Run "git rev-parse --git-dir" to locate the real .git directory.
const char* git = this->CommandLineTool.c_str();
char const* git_rev_parse[] = {git, "rev-parse", "--git-dir", 0};
std::string git_dir_line;
OneLineParser rev_parse_out(this, "rev-parse-out> ", git_dir_line);
OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
if(this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err))
{
git_dir = git_dir_line;
}
if(git_dir.empty())
{
git_dir = ".git";
}
// Git reports a relative path only when the .git directory is in
// the current directory.
if(git_dir[0] == '.')
{
git_dir = this->SourceDirectory + "/" + git_dir;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
else if(git_dir[0] == '/')
{
// Cygwin Git reports a full path that Cygwin understands, but we
// are a Windows application. Run "cygpath" to get Windows path.
std::string cygpath_exe = cmSystemTools::GetFilenamePath(git);
cygpath_exe += "/cygpath.exe";
if(cmSystemTools::FileExists(cygpath_exe.c_str()))
{
char const* cygpath[] = {cygpath_exe.c_str(), "-w", git_dir.c_str(), 0};
OneLineParser cygpath_out(this, "cygpath-out> ", git_dir_line);
OutputLogger cygpath_err(this->Log, "cygpath-err> ");
if(this->RunChild(cygpath, &cygpath_out, &cygpath_err))
{
git_dir = git_dir_line;
}
}
}
#endif
return git_dir;
}
//----------------------------------------------------------------------------
std::string cmCTestGIT::FindTopDir()
{
std::string top_dir = this->SourceDirectory;
// Run "git rev-parse --show-cdup" to locate the top of the tree.
const char* git = this->CommandLineTool.c_str();
char const* git_rev_parse[] = {git, "rev-parse", "--show-cdup", 0};
std::string cdup;
OneLineParser rev_parse_out(this, "rev-parse-out> ", cdup);
OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
if(this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err) &&
!cdup.empty())
{
top_dir += "/";
top_dir += cdup;
top_dir = cmSystemTools::CollapseFullPath(top_dir.c_str());
}
return top_dir;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmCTestGIT::UpdateByFetchAndReset() bool cmCTestGIT::UpdateByFetchAndReset()
{ {
@ -121,11 +190,17 @@ bool cmCTestGIT::UpdateByFetchAndReset()
// Identify the merge head that would be used by "git pull". // Identify the merge head that would be used by "git pull".
std::string sha1; std::string sha1;
{ {
std::string fetch_head = this->SourceDirectory + "/.git/FETCH_HEAD"; std::string fetch_head = this->FindGitDir() + "/FETCH_HEAD";
std::ifstream fin(fetch_head.c_str(), std::ios::in | std::ios::binary); std::ifstream fin(fetch_head.c_str(), std::ios::in | std::ios::binary);
if(!fin)
{
this->Log << "Unable to open " << fetch_head << "\n";
return false;
}
std::string line; std::string line;
while(sha1.empty() && cmSystemTools::GetLineFromStream(fin, line)) while(sha1.empty() && cmSystemTools::GetLineFromStream(fin, line))
{ {
this->Log << "FETCH_HEAD> " << line << "\n";
if(line.find("\tnot-for-merge\t") == line.npos) if(line.find("\tnot-for-merge\t") == line.npos)
{ {
std::string::size_type pos = line.find('\t'); std::string::size_type pos = line.find('\t');
@ -135,6 +210,11 @@ bool cmCTestGIT::UpdateByFetchAndReset()
} }
} }
} }
if(sha1.empty())
{
this->Log << "FETCH_HEAD has no upstream branch candidate!\n";
return false;
}
} }
// Reset the local branch to point at that tracked from upstream. // Reset the local branch to point at that tracked from upstream.
@ -181,11 +261,13 @@ bool cmCTestGIT::UpdateImpl()
return false; return false;
} }
std::string top_dir = this->FindTopDir();
const char* git = this->CommandLineTool.c_str(); const char* git = this->CommandLineTool.c_str();
char const* git_submodule[] = {git, "submodule", "update", 0}; char const* git_submodule[] = {git, "submodule", "update", 0};
OutputLogger submodule_out(this->Log, "submodule-out> "); OutputLogger submodule_out(this->Log, "submodule-out> ");
OutputLogger submodule_err(this->Log, "submodule-err> "); OutputLogger submodule_err(this->Log, "submodule-err> ");
return this->RunChild(git_submodule, &submodule_out, &submodule_err); return this->RunChild(git_submodule, &submodule_out, &submodule_err,
top_dir.c_str());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -32,6 +32,9 @@ private:
virtual void NoteNewRevision(); virtual void NoteNewRevision();
virtual bool UpdateImpl(); virtual bool UpdateImpl();
std::string FindGitDir();
std::string FindTopDir();
bool UpdateByFetchAndReset(); bool UpdateByFetchAndReset();
bool UpdateByCustom(std::string const& custom); bool UpdateByCustom(std::string const& custom);
bool UpdateInternal(); bool UpdateInternal();

View File

@ -275,6 +275,11 @@ execute_process(
WORKING_DIRECTORY \"${TOP}\" WORKING_DIRECTORY \"${TOP}\"
COMMAND \"${GIT}\" clone \"${REPO}\" dash-source COMMAND \"${GIT}\" clone \"${REPO}\" dash-source
) )
# Test .git file.
file(RENAME \"${TOP}/dash-source/.git\" \"${TOP}/dash-source/repo.git\")
file(WRITE \"${TOP}/dash-source/.git\" \"gitdir: repo.git\n\")
execute_process( execute_process(
WORKING_DIRECTORY \"${TOP}/dash-source\" WORKING_DIRECTORY \"${TOP}/dash-source\"
COMMAND \"${GIT}\" reset --hard ${revision1} COMMAND \"${GIT}\" reset --hard ${revision1}