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

[PATCH 4/4] clone: allow configurable default for `-o`/`--origin`

From
Sean Barag via GitGitGadget <gitgitgadget@gmail.com>
Date
Sep 11, 2020, 18:25 UTC
Message-ID
<5c519376c29a28bd89a712cf0b8125fc1c2c81be.1599848727.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.727.git.1599848727.gitgitgadget@gmail.com>
From: Sean Barag <sean@barag.org>

While the default remote name of "origin" can be changed at clone-time with `git clone`'s `--origin` option, it was previously not possible to specify a default value for the name of that remote. This commit adds support for a new `clone.defaultRemoteName` config.

It's resolved in the expected priority order:
1. (Highest priority) A remote name passed directly to `git clone -o`
2. A `clone.defaultRemoteName=new_name` in config `git clone -c`
3. A `clone.defaultRemoteName` value set in `/path/to/template/config`,
   where `--template=/path/to/template` is provided
3. A `clone.defaultRemoteName` value set in a non-template config file
4. The default value of `origin`
Signed-off-by: Sean Barag <sean@barag.org>
Thanks-to: Junio C Hamano <gitster@pobox.com>
Thanks-to: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/config.txt       |  2 ++
 Documentation/config/clone.txt |  5 ++++
 Documentation/git-clone.txt    |  5 ++--
 builtin/clone.c                | 42 +++++++++++++++++++---------------
 t/t5606-clone-options.sh       | 29 +++++++++++++++++------
 5 files changed, 56 insertions(+), 27 deletions(-)
 create mode 100644 Documentation/config/clone.txt
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 3042d80978..354874facf 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -334,6 +334,8 @@ include::config/checkout.txt[]
 
 include::config/clean.txt[]
 
+include::config/clone.txt[]
+
 include::config/color.txt[]
 
 include::config/column.txt[]
diff --git a/Documentation/config/clone.txt b/Documentation/config/clone.txt
new file mode 100644
index 0000000000..20755d413a
--- /dev/null
+++ b/Documentation/config/clone.txt
@@ -0,0 +1,5 @@
+clone.defaultRemoteName::
+	The name of the remote to create when cloning a repository.  Defaults to
+	`origin`, and can be overridden by passing the `--origin` command-line
+	option to linkgit:git-clone[1].
+
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index c898310099..f04bf6e6ba 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -183,8 +183,9 @@ objects from the source repository into a pack in the cloned repository.
 
 -o <name>::
 --origin <name>::
-	Instead of using the remote name `origin` to keep track
-	of the upstream repository, use `<name>`.
+	Instead of using the remote name `origin` to keep track of the upstream
+	repository, use `<name>`.  Overrides `clone.defaultRemoteName` from the
+	config.
 
 -b <name>::
 --branch <name>::
diff --git a/builtin/clone.c b/builtin/clone.c
index 1cd62d0001..aeb41f15f3 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -53,6 +53,7 @@ static int option_shallow_submodules;
 static int deepen;
 static char *option_template, *option_depth, *option_since;
 static char *option_origin = NULL;
+static char *remote_name = "origin";
 static char *option_branch = NULL;
 static struct string_list option_not = STRING_LIST_INIT_NODUP;
 static const char *real_git_dir;
@@ -721,7 +722,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
 		if (!option_bare) {
 			update_ref(msg, "HEAD", &our->old_oid, NULL, 0,
 				   UPDATE_REFS_DIE_ON_ERR);
-			install_branch_config(0, head, option_origin, our->name);
+			install_branch_config(0, head, remote_name, our->name);
 		}
 	} else if (our) {
 		struct commit *c = lookup_commit_reference(the_repository,
@@ -853,16 +854,18 @@ static int checkout(int submodule_progress)
 
 static int git_clone_config(const char *k, const char *v, void *cb)
 {
+	if (!strcmp(k, "clone.defaultremotename") && !option_origin)
+		remote_name = xstrdup(v);
 	return git_default_config(k, v, cb);
 }
 
 static int write_one_config(const char *key, const char *value, void *data)
 {
 	/*
-	 * give git_config_default a chance to write config values back to the environment, since
+	 * give git_clone_config a chance to write config values back to the environment, since
 	 * git_config_set_multivar_gently only deals with config-file writes
 	 */
-	int apply_failed = git_default_config(key, value, data);
+	int apply_failed = git_clone_config(key, value, data);
 	if (apply_failed)
 		return apply_failed;
 
@@ -918,12 +921,12 @@ static void write_refspec_config(const char *src_ref_prefix,
 		}
 		/* Configure the remote */
 		if (value.len) {
-			strbuf_addf(&key, "remote.%s.fetch", option_origin);
+			strbuf_addf(&key, "remote.%s.fetch", remote_name);
 			git_config_set_multivar(key.buf, value.buf, "^$", 0);
 			strbuf_reset(&key);
 
 			if (option_mirror) {
-				strbuf_addf(&key, "remote.%s.mirror", option_origin);
+				strbuf_addf(&key, "remote.%s.mirror", remote_name);
 				git_config_set(key.buf, "true");
 				strbuf_reset(&key);
 			}
@@ -1009,13 +1012,16 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		option_no_checkout = 1;
 	}
 
-	if (!option_origin)
-		option_origin = "origin";
+	if (option_origin)
+		remote_name = option_origin;
 
-	strbuf_addf(&resolved_refspec, "refs/heads/test:refs/remotes/%s/test", option_origin);
+	strbuf_addf(&resolved_refspec, "refs/heads/test:refs/remotes/%s/test", remote_name);
 	if (!valid_fetch_refspec(resolved_refspec.buf))
-		/* TRANSLATORS: %s will be the user-provided --origin / -o option */
-		die(_("'%s' is not a valid origin name"), option_origin);
+		/*
+		 * TRANSLATORS: %s will be the user-provided --origin / -o option, or the value
+		 * of clone.defaultremotename from the config.
+		 */
+		die(_("'%s' is not a valid origin name"), remote_name);
 	strbuf_release(&resolved_refspec);
 
 	repo_name = argv[0];
@@ -1167,15 +1173,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 		git_config_set("core.bare", "true");
 	} else {
-		strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
+		strbuf_addf(&branch_top, "refs/remotes/%s/", remote_name);
 	}
 
-	strbuf_addf(&key, "remote.%s.url", option_origin);
+	strbuf_addf(&key, "remote.%s.url", remote_name);
 	git_config_set(key.buf, repo);
 	strbuf_reset(&key);
 
 	if (option_no_tags) {
-		strbuf_addf(&key, "remote.%s.tagOpt", option_origin);
+		strbuf_addf(&key, "remote.%s.tagOpt", remote_name);
 		git_config_set(key.buf, "--no-tags");
 		strbuf_reset(&key);
 	}
@@ -1186,7 +1192,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	if (option_sparse_checkout && git_sparse_checkout_init(dir))
 		return 1;
 
-	remote = remote_get(option_origin);
+	remote = remote_get(remote_name);
 
 	strbuf_addf(&default_refspec, "+%s*:%s*", src_ref_prefix,
 		    branch_top.buf);
@@ -1299,7 +1305,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 			if (!our_head_points_at)
 				die(_("Remote branch %s not found in upstream %s"),
-				    option_branch, option_origin);
+				    option_branch, remote_name);
 		}
 		else
 			our_head_points_at = remote_head_points_at;
@@ -1307,7 +1313,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	else {
 		if (option_branch)
 			die(_("Remote branch %s not found in upstream %s"),
-					option_branch, option_origin);
+					option_branch, remote_name);
 
 		warning(_("You appear to have cloned an empty repository."));
 		mapped_refs = NULL;
@@ -1319,7 +1325,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 			const char *branch = git_default_branch_name();
 			char *ref = xstrfmt("refs/heads/%s", branch);
 
-			install_branch_config(0, branch, option_origin, ref);
+			install_branch_config(0, branch, remote_name, ref);
 			free(ref);
 		}
 	}
@@ -1328,7 +1334,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 			remote_head_points_at, &branch_top);
 
 	if (filter_options.choice)
-		partial_clone_register(option_origin, &filter_options);
+		partial_clone_register(remote_name, &filter_options);
 
 	if (is_local)
 		clone_local(path, git_dir);
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index c865f96def..017c24a454 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -43,13 +43,6 @@ test_expect_success 'disallows --bare with --separate-git-dir' '
 
 '
 
-test_expect_success 'uses "origin" for default remote name' '
-
-	git clone parent clone-default-origin &&
-	(cd clone-default-origin && git rev-parse --verify refs/remotes/origin/master)
-
-'
-
 test_expect_success 'prefers --template config over normal config' '
 
 	template="$TRASH_DIRECTORY/template-with-config" &&
@@ -71,6 +64,28 @@ test_expect_success 'prefers -c config over --template config' '
 
 '
 
+test_expect_success 'uses "origin" for default remote name' '
+
+	git clone parent clone-default-origin &&
+	(cd clone-default-origin && git rev-parse --verify refs/remotes/origin/master)
+
+'
+
+test_expect_success 'prefers config "clone.defaultRemoteName" over default' '
+
+	test_config_global clone.defaultRemoteName from_config &&
+	git clone parent clone-config-origin &&
+	(cd clone-config-origin && git rev-parse --verify refs/remotes/from_config/master)
+
+'
+
+test_expect_success 'prefers --origin over -c config' '
+
+	git clone -c clone.defaultRemoteName=inline --origin from_option parent clone-o-and-inline-config &&
+	(cd clone-o-and-inline-config && git rev-parse --verify refs/remotes/from_option/master)
+
+'
+
 test_expect_success 'redirected clone does not show progress' '
 
 	git clone "file://$(pwd)/parent" clone-redirected >out 2>err &&
-- 
gitgitgadget
Previous: Sean BaragNext: Derrick Stolee
Message 22 of 49 in “clone: allow configurable default for -o/--origin”
  1. 0/4 clone: allow configurable default for -o/--originSean Barag via GitGitGadget, Sep 11, 2020
  2. 2/4 clone: call git_config before parse_optionsSean Barag via GitGitGadget, Sep 11, 2020
  3. Derrick StoleeSep 11, 2020
  4. Junio C HamanoSep 11, 2020
  5. Sean BaragSep 16, 2020
  6. 1/4 clone: add tests for --template and some disallowed option pairsSean Barag via GitGitGadget, Sep 11, 2020
  7. Derrick StoleeSep 11, 2020
  8. Jeff KingSep 11, 2020
  9. Eric SunshineSep 11, 2020
  10. Sean BaragSep 16, 2020
  11. Taylor BlauSep 12, 2020
  12. Sean BaragSep 15, 2020
  13. Jeff KingSep 16, 2020
  14. Junio C HamanoSep 11, 2020
  15. Derrick StoleeSep 12, 2020
  16. 3/4 clone: validate --origin option before useSean Barag via GitGitGadget, Sep 11, 2020
  17. Derrick StoleeSep 11, 2020
  18. Sean BaragSep 16, 2020
  19. Junio C HamanoSep 11, 2020
  20. Sean BaragSep 16, 2020
  21. Sean BaragSep 21, 2020
  22. 4/4 clone: allow configurable default for `-o`/`--origin`Sean Barag via GitGitGadget, Sep 11, 2020
  23. Derrick StoleeSep 11, 2020
  24. Sean BaragSep 28, 2020
  25. Junio C HamanoSep 11, 2020
  26. Sean BaragSep 28, 2020
  27. Andrei RybakSep 17, 2020
  28. Derrick StoleeSep 11, 2020
  29. Junio C HamanoSep 11, 2020
  30. 0/7 clone: allow configurable default for -o/--originSean Barag via GitGitGadget, Sep 29, 2020
  31. 1/7 clone: add tests for --template and some disallowed option pairsSean Barag via GitGitGadget, Sep 29, 2020
  32. 2/7 clone: use more conventional config/option layeringSean Barag via GitGitGadget, Sep 29, 2020
  33. 3/7 remote: add tests for add and rename with invalid namesSean Barag via GitGitGadget, Sep 29, 2020
  34. 6/7 clone: read new remote name from remote_name instead of option_originSean Barag via GitGitGadget, Sep 29, 2020
  35. 5/7 clone: validate --origin option before useSean Barag via GitGitGadget, Sep 29, 2020
  36. 4/7 refs: consolidate remote name validationSean Barag via GitGitGadget, Sep 29, 2020
  37. 7/7 clone: allow configurable default for `-o`/`--origin`Sean Barag via GitGitGadget, Sep 29, 2020
  38. Junio C HamanoSep 29, 2020
  39. Sean BaragSep 29, 2020
  40. 0/7 clone: allow configurable default for -o/--originSean Barag, Sep 29, 2020
  41. 0/7 clone: allow configurable default for -o/--originSean Barag via GitGitGadget, Oct 1, 2020
  42. 1/7 clone: add tests for --template and some disallowed option pairsSean Barag via GitGitGadget, Oct 1, 2020
  43. 5/7 clone: validate --origin option before useSean Barag via GitGitGadget, Oct 1, 2020
  44. 7/7 clone: allow configurable default for `-o`/`--origin`Sean Barag via GitGitGadget, Oct 1, 2020
  45. 2/7 clone: use more conventional config/option layeringSean Barag via GitGitGadget, Oct 1, 2020
  46. 3/7 remote: add tests for add and rename with invalid namesSean Barag via GitGitGadget, Oct 1, 2020
  47. 6/7 clone: read new remote name from remote_name instead of option_originSean Barag via GitGitGadget, Oct 1, 2020
  48. 4/7 refs: consolidate remote name validationSean Barag via GitGitGadget, Oct 1, 2020
  49. Derrick StoleeOct 2, 2020

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.