builtin/clone: propagate ref storage format to submodules

When recursively cloning a repository with a non-default ref storage format, e.g. by passing the `--ref-format=` option, then only the top-level repository will end up using that ref storage format, and all recursively cloned submodules will instead use the default format. While mixed-format constellations are expected to work alright, the outcome still is somewhat surprising as we have essentially ignored the user's request. Fix this by propagating the requested ref format to cloned submodules. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Aug 8, 2024 at 09:35 UTC 69814846aba19f864e8140c2de982ea345f4ce1b
2 files changed +31 -2
builtin/clone.c
+8 -2
@@ -729,7 +729,8 @@ static int git_sparse_checkout_init(const char *repo)
729 return result;
730 }
731
732 -static int checkout(int submodule_progress, int filter_submodules)
732 +static int checkout(int submodule_progress, int filter_submodules,
733 + enum ref_storage_format ref_storage_format)
734 {
735 struct object_id oid;
736 char *head;
@@ -813,6 +814,10 @@ static int checkout(int submodule_progress, int filter_submodules)
814 strvec_push(&cmd.args, "--no-fetch");
815 }
816
817 + if (ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
818 + strvec_pushf(&cmd.args, "--ref-format=%s",
819 + ref_storage_format_to_name(ref_storage_format));
820 +
821 if (filter_submodules && filter_options.choice)
822 strvec_pushf(&cmd.args, "--filter=%s",
823 expand_list_objects_filter_spec(&filter_options));
@@ -1536,7 +1541,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1541 return 1;
1542
1543 junk_mode = JUNK_LEAVE_REPO;
1539 - err = checkout(submodule_progress, filter_submodules);
1544 + err = checkout(submodule_progress, filter_submodules,
1545 + ref_storage_format);
1546
1547 free(remote_name);
1548 strbuf_release(&reflog_msg);
t/t7424-submodule-mixed-ref-formats.sh
+23
@@ -21,6 +21,29 @@ test_expect_success 'setup' '
21 git config set --global protocol.file.allow always
22 '
23
24 +test_expect_success 'recursive clone propagates ref storage format' '
25 + test_when_finished "rm -rf submodule upstream downstream" &&
26 +
27 + git init submodule &&
28 + test_commit -C submodule submodule-initial &&
29 + git init upstream &&
30 + git -C upstream submodule add "file://$(pwd)/submodule" &&
31 + git -C upstream commit -am "add submodule" &&
32 +
33 + # The upstream repository and its submodule should be using the default
34 + # ref format.
35 + test_ref_format upstream "$GIT_DEFAULT_REF_FORMAT" &&
36 + test_ref_format upstream/submodule "$GIT_DEFAULT_REF_FORMAT" &&
37 +
38 + # The cloned repositories should use the other ref format that we have
39 + # specified via `--ref-format`. The option should propagate to cloned
40 + # submodules.
41 + git clone --ref-format=$OTHER_FORMAT --recurse-submodules \
42 + upstream downstream &&
43 + test_ref_format downstream "$OTHER_FORMAT" &&
44 + test_ref_format downstream/submodule "$OTHER_FORMAT"
45 +'
46 +
47 test_expect_success 'clone submodules with different ref storage format' '
48 test_when_finished "rm -rf submodule upstream downstream" &&
49