Merge branch 'vs/submodule-clone-nested-submodules-alternates'

"git clone --reference $there --recurse-submodules $super" has been
taught to guess repositories usable as references for submodules of
$super that are embedded in $there while making a clone of the
superproject borrow objects from $there; extend the mechanism to
also allow submodules of these submodules to borrow repositories
embedded in these clones of the submodules embedded in the clone of
the superproject.

* vs/submodule-clone-nested-submodules-alternates:
  submodule--helper: set alternateLocation for cloned submodules
This commit is contained in:
Junio C Hamano 2016-12-21 14:55:02 -08:00
commit 1123026f0b
2 changed files with 83 additions and 2 deletions

View File

@ -498,9 +498,9 @@ static int add_possible_reference_from_superproject(
/*
* If the alternate object store is another repository, try the
* standard layout with .git/modules/<name>/objects
* standard layout with .git/(modules/<name>)+/objects
*/
if (ends_with(alt->path, ".git/objects")) {
if (ends_with(alt->path, "/objects")) {
char *sm_alternate;
struct strbuf sb = STRBUF_INIT;
struct strbuf err = STRBUF_INIT;
@ -583,6 +583,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
struct strbuf rel_path = STRBUF_INIT;
struct strbuf sb = STRBUF_INIT;
struct string_list reference = STRING_LIST_INIT_NODUP;
char *sm_alternate = NULL, *error_strategy = NULL;
struct option module_clone_options[] = {
OPT_STRING(0, "prefix", &prefix,
@ -672,6 +673,20 @@ static int module_clone(int argc, const char **argv, const char *prefix)
die(_("could not get submodule directory for '%s'"), path);
git_config_set_in_file(p, "core.worktree",
relative_path(path, sm_gitdir, &rel_path));
/* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */
git_config_get_string("submodule.alternateLocation", &sm_alternate);
if (sm_alternate)
git_config_set_in_file(p, "submodule.alternateLocation",
sm_alternate);
git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
if (error_strategy)
git_config_set_in_file(p, "submodule.alternateErrorStrategy",
error_strategy);
free(sm_alternate);
free(error_strategy);
strbuf_release(&sb);
strbuf_release(&rel_path);
free(sm_gitdir);

View File

@ -125,4 +125,70 @@ test_expect_success 'ignoring missing submodule alternates passes clone and subm
)
'
test_expect_success 'preparing second superproject with a nested submodule plus partial clone' '
test_create_repo supersuper &&
(
cd supersuper &&
echo "I am super super." >file &&
git add file &&
git commit -m B-super-super-initial
git submodule add "file://$base_dir/super" subwithsub &&
git commit -m B-super-super-added &&
git submodule update --init --recursive &&
git repack -ad
) &&
git clone supersuper supersuper2 &&
(
cd supersuper2 &&
git submodule update --init
)
'
# At this point there are three root-level positories: A, B, super and super2
test_expect_success 'nested submodule alternate in works and is actually used' '
test_when_finished "rm -rf supersuper-clone" &&
git clone --recursive --reference supersuper supersuper supersuper-clone &&
(
cd supersuper-clone &&
# test superproject has alternates setup correctly
test_alternate_is_used .git/objects/info/alternates . &&
# immediate submodule has alternate:
test_alternate_is_used .git/modules/subwithsub/objects/info/alternates subwithsub &&
# nested submodule also has alternate:
test_alternate_is_used .git/modules/subwithsub/modules/sub/objects/info/alternates subwithsub/sub
)
'
check_that_two_of_three_alternates_are_used() {
test_alternate_is_used .git/objects/info/alternates . &&
# immediate submodule has alternate:
test_alternate_is_used .git/modules/subwithsub/objects/info/alternates subwithsub &&
# but nested submodule has no alternate:
test_must_fail test_alternate_is_used .git/modules/subwithsub/modules/sub/objects/info/alternates subwithsub/sub
}
test_expect_success 'missing nested submodule alternate fails clone and submodule update' '
test_when_finished "rm -rf supersuper-clone" &&
test_must_fail git clone --recursive --reference supersuper2 supersuper2 supersuper-clone &&
(
cd supersuper-clone &&
check_that_two_of_three_alternates_are_used &&
# update of the submodule fails
test_must_fail git submodule update --init --recursive
)
'
test_expect_success 'missing nested submodule alternate in --reference-if-able mode' '
test_when_finished "rm -rf supersuper-clone" &&
git clone --recursive --reference-if-able supersuper2 supersuper2 supersuper-clone &&
(
cd supersuper-clone &&
check_that_two_of_three_alternates_are_used &&
# update of the submodule succeeds
git submodule update --init --recursive
)
'
test_done