diff mbox series

[v2,5/8] builtin/submodule: allow "add" to use different ref storage format

Message ID 4ce17e44a16335adf9423a227047d3810608aae4.1723102259.git.ps@pks.im (mailing list archive)
State Accepted
Commit c369fc46d079447d216f7ef309ff60abe493cdb6
Headers show
Series Improvements for ref storage formats with submodules | expand

Commit Message

Patrick Steinhardt Aug. 8, 2024, 7:35 a.m. UTC
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>
---
 Documentation/git-submodule.txt        |  5 ++++-
 builtin/submodule--helper.c            | 16 +++++++++++++++-
 git-submodule.sh                       |  9 +++++++++
 t/t7424-submodule-mixed-ref-formats.sh | 11 +++++++++++
 4 files changed, 39 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 73ef8b9696..87d8e0f0c5 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -34,7 +34,7 @@  COMMANDS
 With no arguments, shows the status of existing submodules.  Several
 subcommands are available to perform operations on the submodules.
 
-add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]::
+add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--ref-format <format>] [--depth <depth>] [--] <repository> [<path>]::
 	Add the given repository as a submodule at the given path
 	to the changeset to be committed next to the current
 	project: the current project is termed the "superproject".
@@ -71,6 +71,9 @@  submodule repositories will be kept together in the same relative
 location, and only the superproject's URL needs to be provided.
 git-submodule will correctly locate the submodule using the relative
 URL in `.gitmodules`.
++
+If `--ref-format <format>`  is specified, the ref storage format of newly
+cloned submodules will be set accordingly.
 
 status [--cached] [--recursive] [--] [<path>...]::
 	Show the status of the submodules. This will print the SHA-1 of the
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 42a36bc2f7..48f4577b53 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -3128,13 +3128,17 @@  struct add_data {
 	const char *sm_name;
 	const char *repo;
 	const char *realrepo;
+	enum ref_storage_format ref_storage_format;
 	int depth;
 	unsigned int force: 1;
 	unsigned int quiet: 1;
 	unsigned int progress: 1;
 	unsigned int dissociate: 1;
 };
-#define ADD_DATA_INIT { .depth = -1 }
+#define ADD_DATA_INIT { \
+	.depth = -1, \
+	.ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN, \
+}
 
 static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path)
 {
@@ -3228,6 +3232,7 @@  static int add_submodule(const struct add_data *add_data)
 
 			string_list_append(&reference, p)->util = p;
 		}
+		clone_data.ref_storage_format = add_data->ref_storage_format;
 		clone_data.dissociate = add_data->dissociate;
 		if (add_data->depth >= 0)
 			clone_data.depth = xstrfmt("%d", add_data->depth);
@@ -3392,6 +3397,7 @@  static int module_add(int argc, const char **argv, const char *prefix)
 {
 	int force = 0, quiet = 0, progress = 0, dissociate = 0;
 	struct add_data add_data = ADD_DATA_INIT;
+	const char *ref_storage_format = NULL;
 	char *to_free = NULL;
 	struct option options[] = {
 		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)
 		OPT_BOOL(0, "progress", &progress, N_("force cloning progress")),
 		OPT_STRING(0, "reference", &add_data.reference_path, N_("repository"),
 			   N_("reference repository")),
+		OPT_STRING(0, "ref-format", &ref_storage_format, N_("format"),
+			   N_("specify the reference format to use")),
 		OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
 		OPT_STRING(0, "name", &add_data.sm_name, N_("name"),
 			   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)
 	if (argc == 0 || argc > 2)
 		usage_with_options(usage, options);
 
+	if (ref_storage_format) {
+		add_data.ref_storage_format = ref_storage_format_by_name(ref_storage_format);
+		if (add_data.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
+			die(_("unknown ref storage format '%s'"), ref_storage_format);
+	}
+
 	add_data.repo = argv[0];
 	if (argc == 1)
 		add_data.sm_path = git_url_basename(add_data.repo, 0, 0);
diff --git a/git-submodule.sh b/git-submodule.sh
index 448d58b18b..03c5a220a2 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -94,6 +94,14 @@  cmd_add()
 		--reference=*)
 			reference_path="${1#--reference=}"
 			;;
+		--ref-format)
+			case "$2" in '') usage ;; esac
+			ref_format="--ref-format=$2"
+			shift
+			;;
+		--ref-format=*)
+			ref_format="$1"
+			;;
 		--dissociate)
 			dissociate=1
 			;;
@@ -135,6 +143,7 @@  cmd_add()
 		${progress:+"--progress"} \
 		${branch:+--branch "$branch"} \
 		${reference_path:+--reference "$reference_path"} \
+		${ref_format:+"$ref_format"} \
 		${dissociate:+--dissociate} \
 		${custom_name:+--name "$custom_name"} \
 		${depth:+"$depth"} \
diff --git a/t/t7424-submodule-mixed-ref-formats.sh b/t/t7424-submodule-mixed-ref-formats.sh
index d4e184970a..559713b607 100755
--- a/t/t7424-submodule-mixed-ref-formats.sh
+++ b/t/t7424-submodule-mixed-ref-formats.sh
@@ -37,6 +37,17 @@  test_expect_success 'add existing repository with different ref storage format'
 	)
 '
 
+test_expect_success 'add submodules with different ref storage format' '
+	test_when_finished "rm -rf submodule upstream" &&
+
+	git init submodule &&
+	test_commit -C submodule submodule-initial &&
+	git init upstream &&
+	test_ref_format upstream "$GIT_DEFAULT_REF_FORMAT" &&
+	git -C upstream submodule add --ref-format="$OTHER_FORMAT" "file://$(pwd)/submodule" &&
+	test_ref_format upstream/submodule "$OTHER_FORMAT"
+'
+
 test_expect_success 'recursive clone propagates ref storage format' '
 	test_when_finished "rm -rf submodule upstream downstream" &&