@matheusbsbs / matheus-bagliano / commits / de9ed3ef37
Fork 0

clone: allow configurable default for `-o`/`--origin`

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. Add support for a new `clone.defaultRemoteName` config, with the newly-created remote name resolved in 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 4. A `clone.defaultRemoteName` value set in a non-template config file 5. The default value of `origin` Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de> Helped-by: Derrick Stolee <stolee@gmail.com> Helped-by: Andrei Rybak <rybak.a.v@gmail.com> Signed-off-by: Sean Barag <sean@barag.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Sean Barag committed Oct 1, 2020 at 03:46 UTC de9ed3ef3740f8227cc924e845032954d1f1b1b7
5 files changed +50 -9
Documentation/config.txt
+2
@@ -334,6 +334,8 @@ include::config/checkout.txt[]
334
335 include::config/clean.txt[]
336
337 +include::config/clone.txt[]
338 +
339 include::config/color.txt[]
340
341 include::config/column.txt[]
Documentation/config/clone.txt new
+4
@@ -0,0 +1,4 @@
1 +clone.defaultRemoteName::
2 + The name of the remote to create when cloning a repository. Defaults to
3 + `origin`, and can be overridden by passing the `--origin` command-line
4 + option to linkgit:git-clone[1].
Documentation/git-clone.txt
+3 -2
@@ -183,8 +183,9 @@ objects from the source repository into a pack in the cloned repository.
183
184 -o <name>::
185 --origin <name>::
186 - Instead of using the remote name `origin` to keep track
187 - of the upstream repository, use `<name>`.
186 + Instead of using the remote name `origin` to keep track of the upstream
187 + repository, use `<name>`. Overrides `clone.defaultRemoteName` from the
188 + config.
189
190 -b <name>::
191 --branch <name>::
builtin/clone.c
+19 -7
@@ -53,7 +53,7 @@ static int option_shallow_submodules;
53 static int deepen;
54 static char *option_template, *option_depth, *option_since;
55 static char *option_origin = NULL;
56 -static char *remote_name = "origin";
56 +static char *remote_name = NULL;
57 static char *option_branch = NULL;
58 static struct string_list option_not = STRING_LIST_INIT_NODUP;
59 static const char *real_git_dir;
@@ -854,6 +854,10 @@ static int checkout(int submodule_progress)
854
855 static int git_clone_config(const char *k, const char *v, void *cb)
856 {
857 + if (!strcmp(k, "clone.defaultremotename")) {
858 + free(remote_name);
859 + remote_name = xstrdup(v);
860 + }
861 return git_default_config(k, v, cb);
862 }
863
@@ -1010,12 +1014,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1014 option_no_checkout = 1;
1015 }
1016
1013 - if (option_origin)
1014 - remote_name = option_origin;
1015 -
1016 - if (!valid_remote_name(remote_name))
1017 - die(_("'%s' is not a valid remote name"), remote_name);
1018 -
1017 repo_name = argv[0];
1018
1019 path = get_repo_path(repo_name, &is_bundle);
@@ -1158,6 +1156,19 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1156 */
1157 git_config(git_clone_config, NULL);
1158
1159 + /*
1160 + * apply the remote name provided by --origin only after this second
1161 + * call to git_config, to ensure it overrides all config-based values.
1162 + */
1163 + if (option_origin != NULL)
1164 + remote_name = xstrdup(option_origin);
1165 +
1166 + if (remote_name == NULL)
1167 + remote_name = xstrdup("origin");
1168 +
1169 + if (!valid_remote_name(remote_name))
1170 + die(_("'%s' is not a valid remote name"), remote_name);
1171 +
1172 if (option_bare) {
1173 if (option_mirror)
1174 src_ref_prefix = "refs/";
@@ -1358,6 +1369,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1369 junk_mode = JUNK_LEAVE_REPO;
1370 err = checkout(submodule_progress);
1371
1372 + free(remote_name);
1373 strbuf_release(&reflog_msg);
1374 strbuf_release(&branch_top);
1375 strbuf_release(&key);
t/t5606-clone-options.sh
+22
@@ -19,6 +19,13 @@ test_expect_success 'clone -o' '
19
20 '
21
22 +test_expect_success 'rejects invalid -o/--origin' '
23 +
24 + test_must_fail git clone -o "bad...name" parent clone-bad-name 2>err &&
25 + test_i18ngrep "'\''bad...name'\'' is not a valid remote name" err
26 +
27 +'
28 +
29 test_expect_success 'disallows --bare with --origin' '
30
31 test_must_fail git clone -o foo --bare parent clone-bare-o 2>err &&
@@ -63,6 +70,21 @@ test_expect_success 'prefers -c config over --template config' '
70
71 '
72
73 +test_expect_success 'prefers config "clone.defaultRemoteName" over default' '
74 +
75 + test_config_global clone.defaultRemoteName from_config &&
76 + git clone parent clone-config-origin &&
77 + git -C clone-config-origin rev-parse --verify refs/remotes/from_config/master
78 +
79 +'
80 +
81 +test_expect_success 'prefers --origin over -c config' '
82 +
83 + git clone -c clone.defaultRemoteName=inline --origin from_option parent clone-o-and-inline-config &&
84 + git -C clone-o-and-inline-config rev-parse --verify refs/remotes/from_option/master
85 +
86 +'
87 +
88 test_expect_success 'redirected clone does not show progress' '
89
90 git clone "file://$(pwd)/parent" clone-redirected >out 2>err &&