git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 6/6] clone: reference flag is used for submodules as well

From
Stefan Beller <sbeller@google.com>
Date
Aug 4, 2016, 19:51 UTC
Message-ID
<20160804195159.7788-7-sbeller@google.com>
In-Reply-To
<20160804195159.7788-1-sbeller@google.com>

When giving a --reference while also giving --recurse, the alternates for the submodules are assumed to be in the superproject as well.

In case they are not, we error out when cloning the submodule. However the update command succeeds as usual (with no alternates).

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/clone.c                | 22 ++++++++++++++++++----
 t/t7408-submodule-reference.sh | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index f044a8c..f586df5 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -51,6 +51,7 @@ static int option_progress = -1;
 static enum transport_family family;
 static struct string_list option_config = STRING_LIST_INIT_NODUP;
 static struct string_list option_reference = STRING_LIST_INIT_NODUP;
+static struct string_list superreferences = STRING_LIST_INIT_DUP;
 static int option_dissociate;
 static int max_jobs = -1;
 
@@ -280,10 +281,11 @@ static void strip_trailing_slashes(char *dir)
 	*end = '\0';
 }
 
-static int add_one_reference(struct string_list_item *item, void *cb_data)
+static int add_one_reference(struct string_list_item *item, void *cb_dir)
 {
 	char *ref_git;
 	const char *repo;
+	const char *dir = cb_dir;
 	struct strbuf alternate = STRBUF_INIT;
 
 	/* Beware: read_gitfile(), real_path() and mkpath() return static buffer */
@@ -316,6 +318,13 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
 	if (!access(mkpath("%s/info/grafts", ref_git), F_OK))
 		die(_("reference repository '%s' is grafted"), item->string);
 
+	if (option_recursive) {
+		struct strbuf sb = STRBUF_INIT;
+		char *rel = xstrdup(relative_path(item->string, dir, &sb));
+		string_list_append(&superreferences, rel);
+		strbuf_reset(&sb);
+	}
+
 	strbuf_addf(&alternate, "%s/objects", ref_git);
 	add_to_alternates_file(alternate.buf);
 	strbuf_release(&alternate);
@@ -323,9 +332,9 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
 	return 0;
 }
 
-static void setup_reference(void)
+static void setup_reference(char *dir)
 {
-	for_each_string_list(&option_reference, add_one_reference, NULL);
+	for_each_string_list(&option_reference, add_one_reference, dir);
 }
 
 static void copy_alternates(struct strbuf *src, struct strbuf *dst,
@@ -736,6 +745,7 @@ static int checkout(void)
 
 	if (!err && option_recursive) {
 		struct argv_array args = ARGV_ARRAY_INIT;
+		static struct string_list_item *item;
 		argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL);
 
 		if (option_shallow_submodules == 1)
@@ -744,6 +754,10 @@ static int checkout(void)
 		if (max_jobs != -1)
 			argv_array_pushf(&args, "--jobs=%d", max_jobs);
 
+		if (superreferences.nr)
+			for_each_string_list_item(item, &superreferences)
+				argv_array_pushf(&args, "--super-reference=%s", item->string);
+
 		err = run_command_v_opt(args.argv, RUN_GIT_CMD);
 		argv_array_clear(&args);
 	}
@@ -978,7 +992,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	strbuf_reset(&key);
 
 	if (option_reference.nr)
-		setup_reference();
+		setup_reference(dir);
 
 	fetch_pattern = value.buf;
 	refspec = parse_fetch_refspec(1, &fetch_pattern);
diff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh
index 1416cbd..2652cfe 100755
--- a/t/t7408-submodule-reference.sh
+++ b/t/t7408-submodule-reference.sh
@@ -56,7 +56,8 @@ test_expect_success 'submodule add --reference uses alternates' '
 	(
 		cd super &&
 		git submodule add --reference ../B "file://$base_dir/A" sub &&
-		git commit -m B-super-added
+		git commit -m B-super-added &&
+		git repack -ad
 	) &&
 	test_alternate_usage super/.git/modules/sub/objects/info/alternates super/sub
 '
@@ -68,4 +69,32 @@ test_expect_success 'updating superproject keeps alternates' '
 	test_alternate_usage super-clone/.git/modules/sub/objects/info/alternates super-clone/sub
 '
 
+test_expect_success 'submodules use alternates when cloning a superproject' '
+	test_when_finished "rm -rf super-clone" &&
+	git clone --reference super --recursive super super-clone &&
+	(
+		cd super-clone &&
+		# test superproject has alternates setup correctly
+		test_alternate_usage .git/objects/info/alternates . &&
+		# test submodule has correct setup
+		test_alternate_usage .git/modules/sub/objects/info/alternates sub
+	)
+'
+
+test_expect_success 'cloning superproject, missing submodule alternates' '
+	test_when_finished "rm -rf super-clone" &&
+	git clone super super2 &&
+	test_must_fail git clone --recursive --reference super2 super2 super-clone &&
+	(
+		cd super-clone &&
+		# test superproject has alternates setup correctly
+		test_alternate_usage .git/objects/info/alternates . &&
+		# update of the submodule succeeds
+		git submodule update --init &&
+		# and we have no alternates:
+		test_must_fail test_alternate_usage .git/modules/sub/objects/info/alternates sub &&
+		test_path_is_file sub/file1
+	)
+'
+
 test_done
-- 
2.9.2.572.g9d9644e.dirty
Previous: Junio C HamanoNext: Junio C Hamano
Message 19 of 25 in “git clone: Marry --recursive and --reference”
  1. 0/6 git clone: Marry --recursive and --referenceStefan Beller, Aug 4, 2016
  2. 2/6 t7408: merge short tests, factor out testing methodStefan Beller, Aug 4, 2016
  3. Junio C HamanoAug 5, 2016
  4. Stefan BellerAug 5, 2016
  5. Junio C HamanoAug 5, 2016
  6. 4/6 submodule--helper update-clone: allow multiple referencesStefan Beller, Aug 4, 2016
  7. Stefan BellerAug 5, 2016
  8. Junio C HamanoAug 5, 2016
  9. Stefan BellerAug 5, 2016
  10. Junio C HamanoAug 5, 2016
  11. Stefan BellerAug 5, 2016
  12. 5/6 submodule update: add super-reference flagStefan Beller, Aug 4, 2016
  13. Junio C HamanoAug 5, 2016
  14. Stefan BellerAug 6, 2016
  15. 1/6 t7408: modernize styleStefan Beller, Aug 4, 2016
  16. Junio C HamanoAug 5, 2016
  17. 3/6 submodule--helper module-clone: allow multiple referencesStefan Beller, Aug 4, 2016
  18. Junio C HamanoAug 5, 2016
  19. 6/6 clone: reference flag is used for submodules as wellStefan Beller, Aug 4, 2016
  20. Junio C HamanoAug 5, 2016
  21. Junio C HamanoAug 5, 2016
  22. Stefan BellerAug 5, 2016
  23. Junio C HamanoAug 5, 2016
  24. Rename detection within in files WAS: [PATCH 2/6] t7408: merge short tests, factor out testing methodStefan Beller, Aug 5, 2016
  25. René ScharfeAug 7, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.