Skip to content

Commit 1123026

Browse files
committed
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
2 parents 3c9979b + bf03b79 commit 1123026

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

builtin/submodule--helper.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,9 @@ static int add_possible_reference_from_superproject(
498498

499499
/*
500500
* If the alternate object store is another repository, try the
501-
* standard layout with .git/modules/<name>/objects
501+
* standard layout with .git/(modules/<name>)+/objects
502502
*/
503-
if (ends_with(alt->path, ".git/objects")) {
503+
if (ends_with(alt->path, "/objects")) {
504504
char *sm_alternate;
505505
struct strbuf sb = STRBUF_INIT;
506506
struct strbuf err = STRBUF_INIT;
@@ -583,6 +583,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
583583
struct strbuf rel_path = STRBUF_INIT;
584584
struct strbuf sb = STRBUF_INIT;
585585
struct string_list reference = STRING_LIST_INIT_NODUP;
586+
char *sm_alternate = NULL, *error_strategy = NULL;
586587

587588
struct option module_clone_options[] = {
588589
OPT_STRING(0, "prefix", &prefix,
@@ -672,6 +673,20 @@ static int module_clone(int argc, const char **argv, const char *prefix)
672673
die(_("could not get submodule directory for '%s'"), path);
673674
git_config_set_in_file(p, "core.worktree",
674675
relative_path(path, sm_gitdir, &rel_path));
676+
677+
/* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */
678+
git_config_get_string("submodule.alternateLocation", &sm_alternate);
679+
if (sm_alternate)
680+
git_config_set_in_file(p, "submodule.alternateLocation",
681+
sm_alternate);
682+
git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
683+
if (error_strategy)
684+
git_config_set_in_file(p, "submodule.alternateErrorStrategy",
685+
error_strategy);
686+
687+
free(sm_alternate);
688+
free(error_strategy);
689+
675690
strbuf_release(&sb);
676691
strbuf_release(&rel_path);
677692
free(sm_gitdir);

t/t7408-submodule-reference.sh

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,70 @@ test_expect_success 'ignoring missing submodule alternates passes clone and subm
125125
)
126126
'
127127

128+
test_expect_success 'preparing second superproject with a nested submodule plus partial clone' '
129+
test_create_repo supersuper &&
130+
(
131+
cd supersuper &&
132+
echo "I am super super." >file &&
133+
git add file &&
134+
git commit -m B-super-super-initial
135+
git submodule add "file://$base_dir/super" subwithsub &&
136+
git commit -m B-super-super-added &&
137+
git submodule update --init --recursive &&
138+
git repack -ad
139+
) &&
140+
git clone supersuper supersuper2 &&
141+
(
142+
cd supersuper2 &&
143+
git submodule update --init
144+
)
145+
'
146+
147+
# At this point there are three root-level positories: A, B, super and super2
148+
149+
test_expect_success 'nested submodule alternate in works and is actually used' '
150+
test_when_finished "rm -rf supersuper-clone" &&
151+
git clone --recursive --reference supersuper supersuper supersuper-clone &&
152+
(
153+
cd supersuper-clone &&
154+
# test superproject has alternates setup correctly
155+
test_alternate_is_used .git/objects/info/alternates . &&
156+
# immediate submodule has alternate:
157+
test_alternate_is_used .git/modules/subwithsub/objects/info/alternates subwithsub &&
158+
# nested submodule also has alternate:
159+
test_alternate_is_used .git/modules/subwithsub/modules/sub/objects/info/alternates subwithsub/sub
160+
)
161+
'
162+
163+
check_that_two_of_three_alternates_are_used() {
164+
test_alternate_is_used .git/objects/info/alternates . &&
165+
# immediate submodule has alternate:
166+
test_alternate_is_used .git/modules/subwithsub/objects/info/alternates subwithsub &&
167+
# but nested submodule has no alternate:
168+
test_must_fail test_alternate_is_used .git/modules/subwithsub/modules/sub/objects/info/alternates subwithsub/sub
169+
}
170+
171+
172+
test_expect_success 'missing nested submodule alternate fails clone and submodule update' '
173+
test_when_finished "rm -rf supersuper-clone" &&
174+
test_must_fail git clone --recursive --reference supersuper2 supersuper2 supersuper-clone &&
175+
(
176+
cd supersuper-clone &&
177+
check_that_two_of_three_alternates_are_used &&
178+
# update of the submodule fails
179+
test_must_fail git submodule update --init --recursive
180+
)
181+
'
182+
183+
test_expect_success 'missing nested submodule alternate in --reference-if-able mode' '
184+
test_when_finished "rm -rf supersuper-clone" &&
185+
git clone --recursive --reference-if-able supersuper2 supersuper2 supersuper-clone &&
186+
(
187+
cd supersuper-clone &&
188+
check_that_two_of_three_alternates_are_used &&
189+
# update of the submodule succeeds
190+
git submodule update --init --recursive
191+
)
192+
'
193+
128194
test_done

0 commit comments

Comments
 (0)