builtin/submodule: allow "add" to use different ref storage format

Same as with "clone", users may want to add a submodule to a repository with a non-default ref storage format. Wire up a new `--ref-format=` option that works the same as for `git submodule clone`. 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 c369fc46d079447d216f7ef309ff60abe493cdb6
4 files changed +39 -2
Documentation/git-submodule.txt
+4 -1
@@ -34,7 +34,7 @@ COMMANDS
34 With no arguments, shows the status of existing submodules. Several
35 subcommands are available to perform operations on the submodules.
36
37 -add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]::
37 +add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--ref-format <format>] [--depth <depth>] [--] <repository> [<path>]::
38 Add the given repository as a submodule at the given path
39 to the changeset to be committed next to the current
40 project: the current project is termed the "superproject".
@@ -71,6 +71,9 @@ submodule repositories will be kept together in the same relative
71 location, and only the superproject's URL needs to be provided.
72 git-submodule will correctly locate the submodule using the relative
73 URL in `.gitmodules`.
74 ++
75 +If `--ref-format <format>` is specified, the ref storage format of newly
76 +cloned submodules will be set accordingly.
77
78 status [--cached] [--recursive] [--] [<path>...]::
79 Show the status of the submodules. This will print the SHA-1 of the
builtin/submodule--helper.c
+15 -1
@@ -3128,13 +3128,17 @@ struct add_data {
3128 const char *sm_name;
3129 const char *repo;
3130 const char *realrepo;
3131 + enum ref_storage_format ref_storage_format;
3132 int depth;
3133 unsigned int force: 1;
3134 unsigned int quiet: 1;
3135 unsigned int progress: 1;
3136 unsigned int dissociate: 1;
3137 };
3137 -#define ADD_DATA_INIT { .depth = -1 }
3138 +#define ADD_DATA_INIT { \
3139 + .depth = -1, \
3140 + .ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN, \
3141 +}
3142
3143 static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path)
3144 {
@@ -3228,6 +3232,7 @@ static int add_submodule(const struct add_data *add_data)
3232
3233 string_list_append(&reference, p)->util = p;
3234 }
3235 + clone_data.ref_storage_format = add_data->ref_storage_format;
3236 clone_data.dissociate = add_data->dissociate;
3237 if (add_data->depth >= 0)
3238 clone_data.depth = xstrfmt("%d", add_data->depth);
@@ -3392,6 +3397,7 @@ static int module_add(int argc, const char **argv, const char *prefix)
3397 {
3398 int force = 0, quiet = 0, progress = 0, dissociate = 0;
3399 struct add_data add_data = ADD_DATA_INIT;
3400 + const char *ref_storage_format = NULL;
3401 char *to_free = NULL;
3402 struct option options[] = {
3403 OPT_STRING('b', "branch", &add_data.branch, N_("branch"),
@@ -3402,6 +3408,8 @@ static int module_add(int argc, const char **argv, const char *prefix)
3408 OPT_BOOL(0, "progress", &progress, N_("force cloning progress")),
3409 OPT_STRING(0, "reference", &add_data.reference_path, N_("repository"),
3410 N_("reference repository")),
3411 + OPT_STRING(0, "ref-format", &ref_storage_format, N_("format"),
3412 + N_("specify the reference format to use")),
3413 OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
3414 OPT_STRING(0, "name", &add_data.sm_name, N_("name"),
3415 N_("sets the submodule's name to the given string "
@@ -3428,6 +3436,12 @@ static int module_add(int argc, const char **argv, const char *prefix)
3436 if (argc == 0 || argc > 2)
3437 usage_with_options(usage, options);
3438
3439 + if (ref_storage_format) {
3440 + add_data.ref_storage_format = ref_storage_format_by_name(ref_storage_format);
3441 + if (add_data.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
3442 + die(_("unknown ref storage format '%s'"), ref_storage_format);
3443 + }
3444 +
3445 add_data.repo = argv[0];
3446 if (argc == 1)
3447 add_data.sm_path = git_url_basename(add_data.repo, 0, 0);
git-submodule.sh
+9
@@ -94,6 +94,14 @@ cmd_add()
94 --reference=*)
95 reference_path="${1#--reference=}"
96 ;;
97 + --ref-format)
98 + case "$2" in '') usage ;; esac
99 + ref_format="--ref-format=$2"
100 + shift
101 + ;;
102 + --ref-format=*)
103 + ref_format="$1"
104 + ;;
105 --dissociate)
106 dissociate=1
107 ;;
@@ -135,6 +143,7 @@ cmd_add()
143 ${progress:+"--progress"} \
144 ${branch:+--branch "$branch"} \
145 ${reference_path:+--reference "$reference_path"} \
146 + ${ref_format:+"$ref_format"} \
147 ${dissociate:+--dissociate} \
148 ${custom_name:+--name "$custom_name"} \
149 ${depth:+"$depth"} \
t/t7424-submodule-mixed-ref-formats.sh
+11
@@ -37,6 +37,17 @@ test_expect_success 'add existing repository with different ref storage format'
37 )
38 '
39
40 +test_expect_success 'add submodules with different ref storage format' '
41 + test_when_finished "rm -rf submodule upstream" &&
42 +
43 + git init submodule &&
44 + test_commit -C submodule submodule-initial &&
45 + git init upstream &&
46 + test_ref_format upstream "$GIT_DEFAULT_REF_FORMAT" &&
47 + git -C upstream submodule add --ref-format="$OTHER_FORMAT" "file://$(pwd)/submodule" &&
48 + test_ref_format upstream/submodule "$OTHER_FORMAT"
49 +'
50 +
51 test_expect_success 'recursive clone propagates ref storage format' '
52 test_when_finished "rm -rf submodule upstream downstream" &&
53