Teach ctest_update about Git submodules

Git does not automatically checkout the matching version of a submodule
when it checks out a new version of the parent project in the work tree.
If the submodule reference changed in the parent project then we were
reporting the submodule path as a local modification.  Work around the
problem in ctest_update using "git submodule update" after "git pull".
For projects with no submodules this is a no-op.  See issue #10662.
Also add a submodule to the test project for CTest.UpdateGIT to test the
work-around.
This commit is contained in:
Brad King 2010-05-04 09:35:27 -04:00
parent f20fd583d8
commit 67277bacca
3 changed files with 82 additions and 4 deletions

View File

@ -87,9 +87,11 @@ void cmCTestGIT::NoteNewRevision()
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmCTestGIT::UpdateImpl() bool cmCTestGIT::UpdateImpl()
{ {
const char* git = this->CommandLineTool.c_str();
// Use "git pull" to update the working tree. // Use "git pull" to update the working tree.
std::vector<char const*> git_pull; std::vector<char const*> git_pull;
git_pull.push_back(this->CommandLineTool.c_str()); git_pull.push_back(git);
git_pull.push_back("pull"); git_pull.push_back("pull");
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY) // TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
@ -112,7 +114,14 @@ bool cmCTestGIT::UpdateImpl()
OutputLogger out(this->Log, "pull-out> "); OutputLogger out(this->Log, "pull-out> ");
OutputLogger err(this->Log, "pull-err> "); OutputLogger err(this->Log, "pull-err> ");
return this->RunUpdateCommand(&git_pull[0], &out, &err); if(this->RunUpdateCommand(&git_pull[0], &out, &err))
{
char const* git_submodule[] = {git, "submodule", "update", 0};
OutputLogger out2(this->Log, "submodule-out> ");
OutputLogger err2(this->Log, "submodule-err> ");
return this->RunChild(git_submodule, &out, &err);
}
return false;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -41,8 +41,8 @@ function(check_updates build)
# Compare expected and actual entries # Compare expected and actual entries
set(EXTRA "${UPDATE_XML_ENTRIES}") set(EXTRA "${UPDATE_XML_ENTRIES}")
list(REMOVE_ITEM EXTRA ${ARGN} ${UPDATE_MAYBE}) list(REMOVE_ITEM EXTRA ${ARGN} ${UPDATE_EXTRA} ${UPDATE_MAYBE})
set(MISSING "${ARGN}") set(MISSING "${ARGN}" ${UPDATE_EXTRA})
list(REMOVE_ITEM MISSING ${UPDATE_XML_ENTRIES}) list(REMOVE_ITEM MISSING ${UPDATE_XML_ENTRIES})
if(NOT UPDATE_NOT_GLOBAL) if(NOT UPDATE_NOT_GLOBAL)

View File

@ -5,6 +5,7 @@
# Test in a directory next to this script. # Test in a directory next to this script.
get_filename_component(TOP "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component(TOP "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(TOP "${TOP}/@CTestUpdateGIT_DIR@") set(TOP "${TOP}/@CTestUpdateGIT_DIR@")
set(UPDATE_EXTRA Updated{module})
# Include code common to all update tests. # Include code common to all update tests.
include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake") include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
@ -42,6 +43,35 @@ run_child(
file(REMOVE_RECURSE ${TOP}/repo.git/hooks) file(REMOVE_RECURSE ${TOP}/repo.git/hooks)
set(REPO file://${TOP}/repo.git) set(REPO file://${TOP}/repo.git)
# Create submodule repository.
message("Creating submodule...")
file(MAKE_DIRECTORY ${TOP}/module.git)
run_child(
WORKING_DIRECTORY ${TOP}/module.git
COMMAND ${GIT} --bare init
)
file(REMOVE_RECURSE ${TOP}/module.git/hooks)
set(MOD_REPO file://${TOP}/module.git)
create_content(module)
run_child(WORKING_DIRECTORY ${TOP}/module
COMMAND ${GIT} init
)
file(REMOVE_RECURSE ${TOP}/module/.git/hooks)
file(APPEND ${TOP}/module/.git/config "
[remote \"origin\"]
\turl = ${MOD_REPO}
\tfetch = +refs/heads/*:refs/remotes/origin/*
${AUTHOR_CONFIG}")
run_child(WORKING_DIRECTORY ${TOP}/module
COMMAND ${GIT} add .
)
run_child(WORKING_DIRECTORY ${TOP}/module
COMMAND ${GIT} commit -m "Initial content"
)
run_child(WORKING_DIRECTORY ${TOP}/module
COMMAND ${GIT} push origin master:refs/heads/master
)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Import initial content into the repository. # Import initial content into the repository.
message("Importing content...") message("Importing content...")
@ -60,6 +90,9 @@ ${AUTHOR_CONFIG}")
run_child(WORKING_DIRECTORY ${TOP}/import run_child(WORKING_DIRECTORY ${TOP}/import
COMMAND ${GIT} add . COMMAND ${GIT} add .
) )
run_child(WORKING_DIRECTORY ${TOP}/import
COMMAND ${GIT} submodule add ${MOD_REPO} module
)
run_child(WORKING_DIRECTORY ${TOP}/import run_child(WORKING_DIRECTORY ${TOP}/import
COMMAND ${GIT} commit -m "Initial content" COMMAND ${GIT} commit -m "Initial content"
) )
@ -67,6 +100,19 @@ run_child(WORKING_DIRECTORY ${TOP}/import
COMMAND ${GIT} push origin master:refs/heads/master COMMAND ${GIT} push origin master:refs/heads/master
) )
#-----------------------------------------------------------------------------
# Modify the submodule.
change_content(module)
run_child(WORKING_DIRECTORY ${TOP}/module
COMMAND ${GIT} add -u
)
run_child(WORKING_DIRECTORY ${TOP}/module
COMMAND ${GIT} commit -m "Changed content"
)
run_child(WORKING_DIRECTORY ${TOP}/module
COMMAND ${GIT} push origin master:refs/heads/master
)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Create a working tree. # Create a working tree.
message("Checking out revision 1...") message("Checking out revision 1...")
@ -76,6 +122,14 @@ run_child(
) )
file(REMOVE_RECURSE ${TOP}/user-source/.git/hooks) file(REMOVE_RECURSE ${TOP}/user-source/.git/hooks)
file(APPEND ${TOP}/user-source/.git/config "${AUTHOR_CONFIG}") file(APPEND ${TOP}/user-source/.git/config "${AUTHOR_CONFIG}")
run_child(
WORKING_DIRECTORY ${TOP}/user-source
COMMAND ${GIT} submodule init
)
run_child(
WORKING_DIRECTORY ${TOP}/user-source
COMMAND ${GIT} submodule update
)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Make changes in the working tree. # Make changes in the working tree.
@ -95,6 +149,9 @@ run_child(
WORKING_DIRECTORY ${TOP}/user-source WORKING_DIRECTORY ${TOP}/user-source
COMMAND ${GIT} rm ${files_removed} COMMAND ${GIT} rm ${files_removed}
) )
run_child(WORKING_DIRECTORY ${TOP}/user-source/module
COMMAND ${GIT} checkout master
)
run_child( run_child(
WORKING_DIRECTORY ${TOP}/user-source WORKING_DIRECTORY ${TOP}/user-source
COMMAND ${GIT} add -u COMMAND ${GIT} add -u
@ -140,6 +197,10 @@ run_child(
WORKING_DIRECTORY ${TOP}/user-source WORKING_DIRECTORY ${TOP}/user-source
COMMAND ${GIT} reset --hard master~2 COMMAND ${GIT} reset --hard master~2
) )
run_child(
WORKING_DIRECTORY ${TOP}/user-source
COMMAND ${GIT} submodule update
)
# Make sure pull does not try to rebase (which does not work with # Make sure pull does not try to rebase (which does not work with
# modified files) even if ~/.gitconfig sets "branch.master.rebase". # modified files) even if ~/.gitconfig sets "branch.master.rebase".
@ -181,6 +242,14 @@ execute_process(
WORKING_DIRECTORY \"${TOP}/dash-source\" WORKING_DIRECTORY \"${TOP}/dash-source\"
COMMAND \"${GIT}\" reset --hard master~2 COMMAND \"${GIT}\" reset --hard master~2
) )
execute_process(
WORKING_DIRECTORY \"${TOP}/dash-source\"
COMMAND \"${GIT}\" submodule init
)
execute_process(
WORKING_DIRECTORY \"${TOP}/dash-source\"
COMMAND \"${GIT}\" submodule update
)
") ")
# Run the dashboard script with CTest. # Run the dashboard script with CTest.