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

[PATCH 3/4] builtin/clone.c: recognize fetch.serverOption configuration

From
XGXing Xin via GitGitGadget <gitgitgadget@gmail.com>
Date
Sep 2, 2024, 12:13 UTC
Message-ID
<7c3ebda513d872a2ab2aa0cff5887757de4cde0a.1725279236.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1776.git.git.1725279236.gitgitgadget@gmail.com>
From: Xing Xin <xingxin.xx@bytedance.com>

Teach git-clone to recognize the `fetch.serverOption` configuration as a default list of server options to send for Git protocol v2, if server options are not explicitly set via the command line.

Note that `builtin/clone.c:cmd_clone` originally read the git config twice via `builtin/clone.c:git_clone_config`, which would duplicate server options if parsing logic were added there. Upon investigation, it was found that the first config read is unnecessary since all the global variables it sets are actually used after the second config read. Therefore, the first config read is replaced with a simple `config.c:git_default_config`.

Tests and documentation have been updated accordingly.
Signed-off-by: Xing Xin <xingxin.xx@bytedance.com>
---
 Documentation/git-clone.txt |  3 +++
 builtin/clone.c             | 22 ++++++++++++++++------
 t/t5702-protocol-v2.sh      | 22 ++++++++++++++++++++--
 3 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 8e925db7e9c..105645ed685 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -149,6 +149,9 @@ objects from the source repository into a pack in the cloned repository.
 	unknown ones, is server-specific.
 	When multiple ++--server-option=++__<option>__ are given, they are all
 	sent to the other side in the order listed on the command line.
+	When no ++--server-option=++__<option>__ is given from the command
+	line, the values of configuration variable `fetch.serverOption`
+	are used instead.
 
 `-n`::
 `--no-checkout`::
diff --git a/builtin/clone.c b/builtin/clone.c
index 269b6e18a4e..5a1e2e769af 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -85,7 +85,8 @@ static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP;
 static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
 static int option_filter_submodules = -1;    /* unspecified */
 static int config_filter_submodules = -1;    /* unspecified */
-static struct string_list server_options = STRING_LIST_INIT_NODUP;
+static struct string_list config_server_options = STRING_LIST_INIT_DUP;
+static struct string_list option_server_options = STRING_LIST_INIT_DUP;
 static int option_remote_submodules;
 static const char *bundle_uri;
 
@@ -160,7 +161,7 @@ static struct option builtin_clone_options[] = {
 		   N_("specify the reference format to use")),
 	OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
 			N_("set config inside the new repository")),
-	OPT_STRING_LIST(0, "server-option", &server_options,
+	OPT_STRING_LIST(0, "server-option", &option_server_options,
 			N_("server-specific"), N_("option to transmit")),
 	OPT_IPVERSION(&family),
 	OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
@@ -847,6 +848,12 @@ static int git_clone_config(const char *k, const char *v,
 		config_reject_shallow = git_config_bool(k, v);
 	if (!strcmp(k, "clone.filtersubmodules"))
 		config_filter_submodules = git_config_bool(k, v);
+	if (!strcmp(k, "fetch.serveroption")) {
+		if (!v)
+			return config_error_nonbool(k);
+		parse_transport_option(v, &config_server_options);
+		return 0;
+	}
 
 	return git_default_config(k, v, ctx, cb);
 }
@@ -982,17 +989,20 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	int hash_algo;
 	enum ref_storage_format ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
 	const int do_not_override_repo_unix_permissions = -1;
-
+	struct string_list *server_options = NULL;
 	struct transport_ls_refs_options transport_ls_refs_options =
 		TRANSPORT_LS_REFS_OPTIONS_INIT;
 
 	packet_trace_identity("clone");
 
-	git_config(git_clone_config, NULL);
+	git_config(git_default_config, NULL);
 
 	argc = parse_options(argc, argv, prefix, builtin_clone_options,
 			     builtin_clone_usage, 0);
 
+	server_options = option_server_options.nr ?
+			 &option_server_options : &config_server_options;
+
 	if (argc > 2)
 		usage_msg_opt(_("Too many arguments."),
 			builtin_clone_usage, builtin_clone_options);
@@ -1359,8 +1369,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		transport_set_option(transport, TRANS_OPT_UPLOADPACK,
 				     option_upload_pack);
 
-	if (server_options.nr)
-		transport->server_options = &server_options;
+	if (server_options && server_options->nr)
+		transport->server_options = server_options;
 
 	if (filter_options.choice) {
 		const char *spec =
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index ae25400010e..3bf31fb570d 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -424,12 +424,30 @@ test_expect_success 'warn if using server-option with fetch with legacy protocol
 test_expect_success 'server-options are sent when cloning' '
 	test_when_finished "rm -rf log myclone" &&
 
+	# Specify server options from command line
 	GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
 		clone --server-option=hello --server-option=world \
 		"file://$(pwd)/file_parent" myclone &&
+	test_grep "server-option=hello" log &&
+	test_grep "server-option=world" log &&
+	rm -rf log myclone &&
 
-	grep "server-option=hello" log &&
-	grep "server-option=world" log
+	# Specify server options from fetch.serverOption config
+	GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+		-c fetch.serverOption=hello -c fetch.serverOption=world \
+		clone "file://$(pwd)/file_parent" myclone &&
+	test_grep "server-option=hello" log &&
+	test_grep "server-option=world" log &&
+	rm -rf log myclone &&
+
+	# Cmdline server options take a higher priority
+	GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+		-c fetch.serverOption=hello -c fetch.serverOption=world \
+		clone --server-option=foo=bar \
+		"file://$(pwd)/file_parent" myclone &&
+	test_grep ! "server-option=hello" log &&
+	test_grep ! "server-option=world" log &&
+	test_grep "server-option=foo=bar" log
 '
 
 test_expect_success 'warn if using server-option with clone with legacy protocol' '
-- 
gitgitgadget
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 5 of 39 in “Support server option from configuration”
  1. 0/4 Support server option from configurationblanet via GitGitGadget, Sep 2, 2024
  2. 1/4 transport: add parse_transport_option() methodXing Xin via GitGitGadget, Sep 2, 2024
  3. 2/4 builtin/fetch.c: add fetch.serverOption configurationXing Xin via GitGitGadget, Sep 2, 2024
  4. Patrick SteinhardtSep 3, 2024
  5. 3/4 builtin/clone.c: recognize fetch.serverOption configurationXing Xin via GitGitGadget, Sep 2, 2024
  6. Patrick SteinhardtSep 3, 2024
  7. Xing XinSep 4, 2024
  8. Patrick SteinhardtSep 5, 2024
  9. Xing XinSep 5, 2024
  10. Patrick SteinhardtSep 5, 2024
  11. Junio C HamanoSep 5, 2024
  12. Xing XinSep 9, 2024
  13. Patrick SteinhardtSep 9, 2024
  14. Xing XinSep 23, 2024
  15. Junio C HamanoSep 9, 2024
  16. 4/4 builtin/ls-remote.c: recognize fetch.serverOption configurationXing Xin via GitGitGadget, Sep 2, 2024
  17. Patrick SteinhardtSep 3, 2024
  18. Patrick SteinhardtSep 3, 2024
  19. 0/5 Support server option from configurationblanet via GitGitGadget, Sep 23, 2024
  20. 1/5 transport: introduce parse_transport_option() methodXing Xin via GitGitGadget, Sep 23, 2024
  21. 2/5 remote: introduce remote.<name>.serverOption configurationXing Xin via GitGitGadget, Sep 23, 2024
  22. Patrick SteinhardtOct 7, 2024
  23. Xing XinOct 8, 2024
  24. 3/5 transport.c::handshake: make use of server options from remoteXing Xin via GitGitGadget, Sep 23, 2024
  25. 4/5 fetch: respect --server-option when fetching multiple remotesXing Xin via GitGitGadget, Sep 23, 2024
  26. Patrick SteinhardtOct 7, 2024
  27. 5/5 ls-remote: leakfix for not clearing server_optionsXing Xin via GitGitGadget, Sep 23, 2024
  28. Patrick SteinhardtOct 7, 2024
  29. Patrick SteinhardtOct 7, 2024
  30. Xing XinOct 8, 2024
  31. 0/5 Support server option from configurationblanet via GitGitGadget, Oct 8, 2024
  32. 1/5 transport: introduce parse_transport_option() methodXing Xin via GitGitGadget, Oct 8, 2024
  33. 2/5 remote: introduce remote.<name>.serverOption configurationXing Xin via GitGitGadget, Oct 8, 2024
  34. 3/5 transport.c::handshake: make use of server options from remoteXing Xin via GitGitGadget, Oct 8, 2024
  35. 4/5 fetch: respect --server-option when fetching multiple remotesXing Xin via GitGitGadget, Oct 8, 2024
  36. Junio C HamanoOct 8, 2024
  37. 5/5 ls-remote: leakfix for not clearing server_optionsXing Xin via GitGitGadget, Oct 8, 2024
  38. Patrick SteinhardtOct 8, 2024
  39. Junio C HamanoOct 8, 2024

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.