Skip to content

Commit 84d1783

Browse files
committed
Merge branch 'sg/clone-initial-fetch-configuration'
Refspecs configured with "git -c var=val clone" did not propagate to the resulting repository, which has been corrected. * sg/clone-initial-fetch-configuration: Documentation/clone: document ignored configuration variables clone: respect additional configured fetch refspecs during initial fetch clone: use a more appropriate variable name for the default refspec
2 parents 8d7f9db + 7eae4a3 commit 84d1783

File tree

3 files changed

+72
-14
lines changed

3 files changed

+72
-14
lines changed

Documentation/git-clone.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ objects from the source repository into a pack in the cloned repository.
189189
values are given for the same key, each value will be written to
190190
the config file. This makes it safe, for example, to add
191191
additional fetch refspecs to the origin remote.
192+
+
193+
Due to limitations of the current implementation, some configuration
194+
variables do not take effect until after the initial fetch and checkout.
195+
Configuration variables known to not take effect are:
196+
`remote.<name>.mirror` and `remote.<name>.tagOpt`. Use the
197+
corresponding `--mirror` and `--no-tags` options instead.
192198

193199
--depth <depth>::
194200
Create a 'shallow' clone with a history truncated to the

builtin/clone.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ static struct ref *find_remote_branch(const struct ref *refs, const char *branch
548548
}
549549

550550
static struct ref *wanted_peer_refs(const struct ref *refs,
551-
struct refspec_item *refspec)
551+
struct refspec *refspec)
552552
{
553553
struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));
554554
struct ref *local_refs = head;
@@ -569,13 +569,19 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
569569
warning(_("Could not find remote branch %s to clone."),
570570
option_branch);
571571
else {
572-
get_fetch_map(remote_head, refspec, &tail, 0);
572+
int i;
573+
for (i = 0; i < refspec->nr; i++)
574+
get_fetch_map(remote_head, &refspec->items[i],
575+
&tail, 0);
573576

574577
/* if --branch=tag, pull the requested tag explicitly */
575578
get_fetch_map(remote_head, tag_refspec, &tail, 0);
576579
}
577-
} else
578-
get_fetch_map(refs, refspec, &tail, 0);
580+
} else {
581+
int i;
582+
for (i = 0; i < refspec->nr; i++)
583+
get_fetch_map(refs, &refspec->items[i], &tail, 0);
584+
}
579585

580586
if (!option_mirror && !option_single_branch && !option_no_tags)
581587
get_fetch_map(refs, tag_refspec, &tail, 0);
@@ -890,15 +896,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
890896
const struct ref *our_head_points_at;
891897
struct ref *mapped_refs;
892898
const struct ref *ref;
893-
struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
899+
struct strbuf key = STRBUF_INIT;
900+
struct strbuf default_refspec = STRBUF_INIT;
894901
struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
895902
struct transport *transport = NULL;
896903
const char *src_ref_prefix = "refs/heads/";
897904
struct remote *remote;
898905
int err = 0, complete_refs_before_fetch = 1;
899906
int submodule_progress;
900907

901-
struct refspec rs = REFSPEC_INIT_FETCH;
902908
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
903909

904910
fetch_if_missing = 0;
@@ -1067,7 +1073,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
10671073
strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
10681074
}
10691075

1070-
strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
10711076
strbuf_addf(&key, "remote.%s.url", option_origin);
10721077
git_config_set(key.buf, repo);
10731078
strbuf_reset(&key);
@@ -1081,11 +1086,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
10811086
if (option_required_reference.nr || option_optional_reference.nr)
10821087
setup_reference();
10831088

1084-
refspec_append(&rs, value.buf);
1089+
remote = remote_get(option_origin);
10851090

1086-
strbuf_reset(&value);
1091+
strbuf_addf(&default_refspec, "+%s*:%s*", src_ref_prefix,
1092+
branch_top.buf);
1093+
refspec_append(&remote->fetch, default_refspec.buf);
10871094

1088-
remote = remote_get(option_origin);
10891095
transport = transport_get(remote, remote->url[0]);
10901096
transport_set_verbosity(transport, option_verbosity, option_progress);
10911097
transport->family = family;
@@ -1140,7 +1146,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
11401146

11411147

11421148
argv_array_push(&ref_prefixes, "HEAD");
1143-
refspec_ref_prefixes(&rs, &ref_prefixes);
1149+
refspec_ref_prefixes(&remote->fetch, &ref_prefixes);
11441150
if (option_branch)
11451151
expand_ref_prefix(&ref_prefixes, option_branch);
11461152
if (!option_no_tags)
@@ -1149,7 +1155,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
11491155
refs = transport_get_remote_refs(transport, &ref_prefixes);
11501156

11511157
if (refs) {
1152-
mapped_refs = wanted_peer_refs(refs, &rs.items[0]);
1158+
mapped_refs = wanted_peer_refs(refs, &remote->fetch);
11531159
/*
11541160
* transport_get_remote_refs() may return refs with null sha-1
11551161
* in mapped_refs (see struct transport->get_refs_list
@@ -1240,10 +1246,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
12401246
strbuf_release(&reflog_msg);
12411247
strbuf_release(&branch_top);
12421248
strbuf_release(&key);
1243-
strbuf_release(&value);
1249+
strbuf_release(&default_refspec);
12441250
junk_mode = JUNK_LEAVE_ALL;
12451251

1246-
refspec_clear(&rs);
12471252
argv_array_clear(&ref_prefixes);
12481253
return err;
12491254
}

t/t5611-clone-config.sh

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,53 @@ test_expect_success 'clone -c config is available during clone' '
4545
test_cmp expect child/file
4646
'
4747

48+
test_expect_success 'clone -c remote.origin.fetch=<refspec> works' '
49+
rm -rf child &&
50+
git update-ref refs/grab/it refs/heads/master &&
51+
git update-ref refs/leave/out refs/heads/master &&
52+
git clone -c "remote.origin.fetch=+refs/grab/*:refs/grab/*" . child &&
53+
git -C child for-each-ref --format="%(refname)" >actual &&
54+
55+
cat >expect <<-\EOF &&
56+
refs/grab/it
57+
refs/heads/master
58+
refs/remotes/origin/HEAD
59+
refs/remotes/origin/master
60+
EOF
61+
test_cmp expect actual
62+
'
63+
64+
test_expect_success 'git -c remote.origin.fetch=<refspec> clone works' '
65+
rm -rf child &&
66+
git -c "remote.origin.fetch=+refs/grab/*:refs/grab/*" clone . child &&
67+
git -C child for-each-ref --format="%(refname)" >actual &&
68+
69+
cat >expect <<-\EOF &&
70+
refs/grab/it
71+
refs/heads/master
72+
refs/remotes/origin/HEAD
73+
refs/remotes/origin/master
74+
EOF
75+
test_cmp expect actual
76+
'
77+
78+
test_expect_success 'clone -c remote.<remote>.fetch=<refspec> --origin=<name>' '
79+
rm -rf child &&
80+
git clone --origin=upstream \
81+
-c "remote.upstream.fetch=+refs/grab/*:refs/grab/*" \
82+
-c "remote.origin.fetch=+refs/leave/*:refs/leave/*" \
83+
. child &&
84+
git -C child for-each-ref --format="%(refname)" >actual &&
85+
86+
cat >expect <<-\EOF &&
87+
refs/grab/it
88+
refs/heads/master
89+
refs/remotes/upstream/HEAD
90+
refs/remotes/upstream/master
91+
EOF
92+
test_cmp expect actual
93+
'
94+
4895
# Tests for the hidden file attribute on windows
4996
is_hidden () {
5097
# Use the output of `attrib`, ignore the absolute path

0 commit comments

Comments
 (0)