Configuration variables specified via 'git clone -c <key>=<value>' "take effect immediately after the repository is initialized, but before the remote history is fetched". This implies that any fetch refspecs specified this way should already be taken into account during the initial fetch and remote refs matching these refspecs should be retrieved as well. This never worked, however, not even when the feature was introduced in v1.7.7-rc0~90^2 (clone: accept config options on the command line, 2011-06-09). While the given refspecs are written to the config file alright, no matching refs are fetched, because the initial fetch ignores them and respects only that single default refspec. Check whether there are any relevant configured fetch refspecs and take those into account during the initial fetch, unless running 'git clone --single-branch'. Signed-off-by: SZEDER Gábor <szeder@xxxxxxxxxx> --- I'm unsure what to do with the '-c <fetch-refspec> --single-branch' combination: it doesn't really make sense to me and can't imagaine a use case where it would be useful... but perhaps I just lack imagination on this Sunday night. Hence the RFC. builtin/clone.c | 32 +++++++++++++++++++++++++------- t/t5708-clone-config.sh | 13 +++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 9ac6c0144279..5b96b373675a 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -515,7 +515,7 @@ static struct ref *find_remote_branch(const struct ref *refs, const char *branch } static struct ref *wanted_peer_refs(const struct ref *refs, - struct refspec *refspec) + struct refspec *refspec, unsigned int refspec_count) { struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD")); struct ref *local_refs = head; @@ -541,8 +541,11 @@ static struct ref *wanted_peer_refs(const struct ref *refs, /* if --branch=tag, pull the requested tag explicitly */ get_fetch_map(remote_head, tag_refspec, &tail, 0); } - } else - get_fetch_map(refs, refspec, &tail, 0); + } else { + unsigned int i; + for (i = 0; i < refspec_count; i++) + get_fetch_map(refs, &refspec[i], &tail, 0); + } if (!option_mirror && !option_single_branch) get_fetch_map(refs, tag_refspec, &tail, 0); @@ -840,7 +843,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix) int err = 0, complete_refs_before_fetch = 1; struct refspec *refspec; - const char *fetch_pattern; + unsigned int refspec_count = 1; + const char **fetch_patterns; + const struct string_list *config_fetch_patterns; packet_trace_identity("clone"); argc = parse_options(argc, argv, prefix, builtin_clone_options, @@ -967,9 +972,21 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (option_reference.nr) setup_reference(); - fetch_pattern = value.buf; - refspec = parse_fetch_refspec(1, &fetch_pattern); + strbuf_addf(&key, "remote.%s.fetch", option_origin); + config_fetch_patterns = git_config_get_value_multi(key.buf); + if (config_fetch_patterns) + refspec_count = 1 + config_fetch_patterns->nr; + fetch_patterns = xcalloc(refspec_count, sizeof(*fetch_patterns)); + fetch_patterns[0] = value.buf; + if (config_fetch_patterns) { + struct string_list_item *fp; + unsigned int i = 1; + for_each_string_list_item(fp, config_fetch_patterns) + fetch_patterns[i++] = fp->string; + } + refspec = parse_fetch_refspec(refspec_count, fetch_patterns); + strbuf_reset(&key); strbuf_reset(&value); remote = remote_get(option_origin); @@ -1013,7 +1030,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) refs = transport_get_remote_refs(transport); if (refs) { - mapped_refs = wanted_peer_refs(refs, refspec); + mapped_refs = wanted_peer_refs(refs, refspec, refspec_count); /* * transport_get_remote_refs() may return refs with null sha-1 * in mapped_refs (see struct transport->get_refs_list @@ -1094,6 +1111,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) strbuf_release(&value); junk_mode = JUNK_LEAVE_ALL; + free(fetch_patterns); free(refspec); return err; } diff --git a/t/t5708-clone-config.sh b/t/t5708-clone-config.sh index 27d730c0a720..377837e3539a 100755 --- a/t/t5708-clone-config.sh +++ b/t/t5708-clone-config.sh @@ -37,4 +37,17 @@ test_expect_success 'clone -c config is available during clone' ' test_cmp expect child/file ' +test_expect_success 'clone -c remote.origin.fetch=<refspec> works' ' + rm -rf child && + git update-ref refs/grab/it refs/heads/master && + git update-ref refs/keep/out refs/heads/master && + git clone -c "remote.origin.fetch=+refs/grab/*:refs/grab/*" . child && + ( + cd child && + git for-each-ref --format="%(refname)" refs/grab/ >../actual + ) && + echo refs/grab/it >expect && + test_cmp expect actual +' + test_done -- 2.7.2.410.g92cb358 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html