All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] fetch: support "--super-prefix"
@ 2022-11-11 23:55 Glen Choo via GitGitGadget
  0 siblings, 0 replies; only message in thread
From: Glen Choo via GitGitGadget @ 2022-11-11 23:55 UTC (permalink / raw)
  To: git; +Cc: Ævar Arnfjörð Bjarmason, Glen Choo, Glen Choo

From: Glen Choo <chooglen@google.com>

In a repo with partially cloned submodules, "git restore
--recurse-submodules" from the superproject can fail with "fatal: fetch
doesn't support --super-prefix". This error is encountered when the
super prefix is set (either by passing "--super-prefix" or by setting
the GIT_INTERNAL_SUPER_PREFIX env var) on a command that isn't marked
SUPPORT_SUPER_PREFIX. In this case, "git restore --recurse-submodules"
invokes "git read-tree --super-prefix=<path to submodule>", which in
turn, invokes a "git fetch" to fetch promisor objects.

The usefulness of this "--super-prefix" check is up for debate, and
there is WIP to get rid of the option altogether [1], but we can't just
leave "git restore" broken in the meantime, so let's do the barest
minimum to fix this without causing too much trouble for that effort.

Mark cmd_fetch as SUPPORT_SUPER_PREFIX, and add a test that shows that
this fixes the bug described above.

There is precedent for using SUPPORT_SUPER_PREFIX solely as a workaround
for the super prefix check (c.f. [2]), which is all the more reason to
get rid of this check.

[1] https://lore.kernel.org/git/Y27D8QUl3I2d4xNe@nand.local/
[2] 53fcfbc84f (fsmonitor--daemon: allow --super-prefix argument,
    2022-05-26)

Suggested-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Glen Choo <chooglen@google.com>
---
    fetch: support "--super-prefix"
    
    Since "git read-tree" is seriously broken at the moment, let's not keep
    it hostage to the work on [1]. This is Ævar's suggested change from [2]
    combined with my partial clone test case from [3].
    
    I think we can take this regardless of where we are with the RFCs; it's
    simple and obvious enough that it adds virtually no churn to the RFCs.
    
    [1] https://lore.kernel.org/git/Y27D8QUl3I2d4xNe@nand.local/ [2]
    https://lore.kernel.org/git/221109.86y1skq08e.gmgdl@evledraar.gmail.com
    [3]
    https://lore.kernel.org/git/20221109004708.97668-4-chooglen@google.com

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1378%2Fchooglen%2Ffetch%2Fsupport-super-prefix-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1378/chooglen/fetch/support-super-prefix-v1
Pull-Request: https://github.com/git/git/pull/1378

 builtin/fetch.c          |  6 ++++++
 git.c                    |  2 +-
 t/t5616-partial-clone.sh | 43 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 7378cafeec9..9fd64e2f409 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -2114,6 +2114,12 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 	int result = 0;
 	int prune_tags_ok = 1;
 
+	/*
+	 * NEEDSWORK: we don't actually use "--super-prefix". Unset it
+	 * so that we don't accidentally use it or pass it down.
+	 */
+	unsetenv(GIT_SUPER_PREFIX_ENVIRONMENT);
+
 	packet_trace_identity("fetch");
 
 	/* Record the command line for the reflog */
diff --git a/git.c b/git.c
index 6662548986f..b971752f6f0 100644
--- a/git.c
+++ b/git.c
@@ -531,7 +531,7 @@ static struct cmd_struct commands[] = {
 	{ "env--helper", cmd_env__helper },
 	{ "fast-export", cmd_fast_export, RUN_SETUP },
 	{ "fast-import", cmd_fast_import, RUN_SETUP | NO_PARSEOPT },
-	{ "fetch", cmd_fetch, RUN_SETUP },
+	{ "fetch", cmd_fetch, RUN_SETUP | SUPPORT_SUPER_PREFIX },
 	{ "fetch-pack", cmd_fetch_pack, RUN_SETUP | NO_PARSEOPT },
 	{ "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP },
 	{ "for-each-ref", cmd_for_each_ref, RUN_SETUP },
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 037941b95d2..9bec57a0476 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -644,6 +644,49 @@ test_expect_success 'repack does not loosen promisor objects' '
 	grep "loosen_unused_packed_objects/loosened:0" trace
 '
 
+test_expect_success 'setup src repo with submodules' '
+	test_config_global protocol.file.allow always &&
+
+	git init src-sub &&
+	git -C src-sub config uploadpack.allowfilter 1 &&
+	git -C src-sub config uploadpack.allowanysha1inwant 1 &&
+
+	# This blob must be missing in the subsequent commit.
+	echo foo >src-sub/file &&
+	git -C src-sub add file &&
+	git -C src-sub commit -m "submodule one" &&
+	SUB_ONE=$(git -C src-sub rev-parse HEAD) &&
+
+	echo bar >src-sub/file &&
+	git -C src-sub add file &&
+	git -C src-sub commit -m "submodule two" &&
+	SUB_TWO=$(git -C src-sub rev-parse HEAD) &&
+
+	git init src-super &&
+	git -C src-super config uploadpack.allowfilter 1 &&
+	git -C src-super config uploadpack.allowanysha1inwant 1 &&
+	git -C src-super submodule add ../src-sub src-sub &&
+
+	git -C src-super/src-sub checkout $SUB_ONE &&
+	git -C src-super add src-sub &&
+	git -C src-super commit -m "superproject one" &&
+
+	git -C src-super/src-sub checkout $SUB_TWO &&
+	git -C src-super add src-sub &&
+	git -C src-super commit -m "superproject two"
+'
+
+test_expect_success 'lazy-fetch in submodule succeeds' '
+	test_when_finished "rm -rf src-super src-sub client" &&
+
+	test_config_global protocol.file.allow always &&
+	git clone --filter=blob:none --also-filter-submodules \
+		--recurse-submodules "file://$(pwd)/src-super" client &&
+
+	# Trigger lazy-fetch from the superproject
+	git -C client restore --recurse-submodules --source=HEAD^ :/
+'
+
 . "$TEST_DIRECTORY"/lib-httpd.sh
 start_httpd
 

base-commit: 319605f8f00e402f3ea758a02c63534ff800a711
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2022-11-11 23:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-11 23:55 [PATCH] fetch: support "--super-prefix" Glen Choo via GitGitGadget

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.