diff mbox series

[v3,4/5] fetch: respect --server-option when fetching multiple remotes

Message ID 420b15d9f37d2510d0e4f5390a4b93a5ead7c966.1728358699.git.gitgitgadget@gmail.com (mailing list archive)
State Accepted
Commit 148bc7bf4b482edd7919e3071542abeb5d7ea4af
Headers show
Series Support server option from configuration | expand

Commit Message

Xing Xin Oct. 8, 2024, 3:38 a.m. UTC
From: Xing Xin <xingxin.xx@bytedance.com>

Fix an issue where server options specified via the command line
(`--server-option` or `-o`) were not sent when fetching from multiple
remotes using Git protocol v2.

To reproduce the issue with a repository containing multiple remotes:

  GIT_TRACE_PACKET=1 git -c protocol.version=2 fetch --server-option=demo --all

Observe that no server options are sent to any remote.

The root cause was identified in `builtin/fetch.c:fetch_multiple`, which
is invoked when fetching from more than one remote. This function forks
a `git-fetch` subprocess for each remote but did not include the
specified server options in the subprocess arguments.

This commit ensures that command-line specified server options are
properly passed to each subprocess. Relevant tests have been added.

Signed-off-by: Xing Xin <xingxin.xx@bytedance.com>
---
 builtin/fetch.c        |  2 ++
 t/t5702-protocol-v2.sh | 10 ++++++++++
 2 files changed, 12 insertions(+)

Comments

Junio C Hamano Oct. 8, 2024, 5:57 p.m. UTC | #1
"Xing Xin via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Xing Xin <xingxin.xx@bytedance.com>
>
> Fix an issue where server options specified via the command line
> (`--server-option` or `-o`) were not sent when fetching from multiple
> remotes using Git protocol v2.
>
> To reproduce the issue with a repository containing multiple remotes:
>
>   GIT_TRACE_PACKET=1 git -c protocol.version=2 fetch --server-option=demo --all
>
> Observe that no server options are sent to any remote.
>
> The root cause was identified in `builtin/fetch.c:fetch_multiple`, which
> is invoked when fetching from more than one remote. This function forks
> a `git-fetch` subprocess for each remote but did not include the
> specified server options in the subprocess arguments.
>
> This commit ensures that command-line specified server options are
> properly passed to each subprocess. Relevant tests have been added.

A more interesting use case, as there is no reason to expect that a
single server-option command line option may apply to all remotes,
would be to configure different server options for different remotes
via the new serverOption configuration, so that different server
options are used for different remotes.

If it happens that the same server option is applicable for all
remotes, it is reasonable to give --server-option from the command
line and expect it to be propagated down to subfetches, so
regardless of the "what happens when different remotes have
different options configured?" above, the change in this step looks
reasonable to me.
diff mbox series

Patch

diff --git a/builtin/fetch.c b/builtin/fetch.c
index c900f577219..54be2e7ca9f 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1980,6 +1980,8 @@  static int fetch_multiple(struct string_list *list, int max_children,
 	strvec_pushl(&argv, "-c", "fetch.bundleURI=",
 		     "fetch", "--append", "--no-auto-gc",
 		     "--no-write-commit-graph", NULL);
+	for (i = 0; i < server_options.nr; i++)
+		strvec_pushf(&argv, "--server-option=%s", server_options.items[i].string);
 	add_options_to_argv(&argv, config);
 
 	if (max_children != 1 && list->nr != 1) {
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index 5cec2061d28..d3df81e7852 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -418,6 +418,16 @@  test_expect_success 'server-options are sent when fetching' '
 	grep "server-option=world" log
 '
 
+test_expect_success 'server-options are sent when fetch multiple remotes' '
+	test_when_finished "rm -f log server_options_sent" &&
+	git clone "file://$(pwd)/file_parent" child_multi_remotes &&
+	git -C child_multi_remotes remote add another "file://$(pwd)/file_parent" &&
+	GIT_TRACE_PACKET="$(pwd)/log" git -C child_multi_remotes -c protocol.version=2 \
+		fetch -o hello --all &&
+	grep "fetch> server-option=hello" log >server_options_sent &&
+	test_line_count = 2 server_options_sent
+'
+
 test_expect_success 'server-options from configuration are used by git-fetch' '
 	test_when_finished "rm -rf log myclone" &&
 	git clone "file://$(pwd)/file_parent" myclone &&