]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'sg/clone-initial-fetch-configuration'
authorJunio C Hamano <gitster@pobox.com>
Fri, 4 Jan 2019 21:33:34 +0000 (13:33 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 4 Jan 2019 21:33:34 +0000 (13:33 -0800)
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

Documentation/git-clone.txt
builtin/clone.c
t/t5611-clone-config.sh

index a55536f0bfb2dfa3774e1b952ac4dee1eea6e505..2fd12524f95afef9c688d3402cd2a8b6d2d98c2e 100644 (file)
@@ -189,6 +189,12 @@ objects from the source repository into a pack in the cloned repository.
        values are given for the same key, each value will be written to
        the config file. This makes it safe, for example, to add
        additional fetch refspecs to the origin remote.
++
+Due to limitations of the current implementation, some configuration
+variables do not take effect until after the initial fetch and checkout.
+Configuration variables known to not take effect are:
+`remote.<name>.mirror` and `remote.<name>.tagOpt`.  Use the
+corresponding `--mirror` and `--no-tags` options instead.
 
 --depth <depth>::
        Create a 'shallow' clone with a history truncated to the
index 15b142d64640e29c10e62d565ac21adbaaeebca4..7c7f98c72c80cfcb12f3d3f61a13f46b19967a8f 100644 (file)
@@ -548,7 +548,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_item *refspec)
+               struct refspec *refspec)
 {
        struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));
        struct ref *local_refs = head;
@@ -569,13 +569,19 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
                        warning(_("Could not find remote branch %s to clone."),
                                option_branch);
                else {
-                       get_fetch_map(remote_head, refspec, &tail, 0);
+                       int i;
+                       for (i = 0; i < refspec->nr; i++)
+                               get_fetch_map(remote_head, &refspec->items[i],
+                                             &tail, 0);
 
                        /* 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 {
+               int i;
+               for (i = 0; i < refspec->nr; i++)
+                       get_fetch_map(refs, &refspec->items[i], &tail, 0);
+       }
 
        if (!option_mirror && !option_single_branch && !option_no_tags)
                get_fetch_map(refs, tag_refspec, &tail, 0);
@@ -890,7 +896,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        const struct ref *our_head_points_at;
        struct ref *mapped_refs;
        const struct ref *ref;
-       struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
+       struct strbuf key = STRBUF_INIT;
+       struct strbuf default_refspec = STRBUF_INIT;
        struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
        struct transport *transport = NULL;
        const char *src_ref_prefix = "refs/heads/";
@@ -898,7 +905,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        int err = 0, complete_refs_before_fetch = 1;
        int submodule_progress;
 
-       struct refspec rs = REFSPEC_INIT_FETCH;
        struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
 
        fetch_if_missing = 0;
@@ -1067,7 +1073,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
        }
 
-       strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
        strbuf_addf(&key, "remote.%s.url", option_origin);
        git_config_set(key.buf, repo);
        strbuf_reset(&key);
@@ -1081,11 +1086,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        if (option_required_reference.nr || option_optional_reference.nr)
                setup_reference();
 
-       refspec_append(&rs, value.buf);
+       remote = remote_get(option_origin);
 
-       strbuf_reset(&value);
+       strbuf_addf(&default_refspec, "+%s*:%s*", src_ref_prefix,
+                   branch_top.buf);
+       refspec_append(&remote->fetch, default_refspec.buf);
 
-       remote = remote_get(option_origin);
        transport = transport_get(remote, remote->url[0]);
        transport_set_verbosity(transport, option_verbosity, option_progress);
        transport->family = family;
@@ -1140,7 +1146,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 
        argv_array_push(&ref_prefixes, "HEAD");
-       refspec_ref_prefixes(&rs, &ref_prefixes);
+       refspec_ref_prefixes(&remote->fetch, &ref_prefixes);
        if (option_branch)
                expand_ref_prefix(&ref_prefixes, option_branch);
        if (!option_no_tags)
@@ -1149,7 +1155,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        refs = transport_get_remote_refs(transport, &ref_prefixes);
 
        if (refs) {
-               mapped_refs = wanted_peer_refs(refs, &rs.items[0]);
+               mapped_refs = wanted_peer_refs(refs, &remote->fetch);
                /*
                 * transport_get_remote_refs() may return refs with null sha-1
                 * in mapped_refs (see struct transport->get_refs_list
@@ -1240,10 +1246,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        strbuf_release(&reflog_msg);
        strbuf_release(&branch_top);
        strbuf_release(&key);
-       strbuf_release(&value);
+       strbuf_release(&default_refspec);
        junk_mode = JUNK_LEAVE_ALL;
 
-       refspec_clear(&rs);
        argv_array_clear(&ref_prefixes);
        return err;
 }
index 39329eb7a8a64b177794b83ef8828b866fead547..60c1ba951b7d4178708574d10986659749925059 100755 (executable)
@@ -45,6 +45,53 @@ 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/leave/out refs/heads/master &&
+       git clone -c "remote.origin.fetch=+refs/grab/*:refs/grab/*" . child &&
+       git -C child for-each-ref --format="%(refname)" >actual &&
+
+       cat >expect <<-\EOF &&
+       refs/grab/it
+       refs/heads/master
+       refs/remotes/origin/HEAD
+       refs/remotes/origin/master
+       EOF
+       test_cmp expect actual
+'
+
+test_expect_success 'git -c remote.origin.fetch=<refspec> clone works' '
+       rm -rf child &&
+       git -c "remote.origin.fetch=+refs/grab/*:refs/grab/*" clone . child &&
+       git -C child for-each-ref --format="%(refname)" >actual &&
+
+       cat >expect <<-\EOF &&
+       refs/grab/it
+       refs/heads/master
+       refs/remotes/origin/HEAD
+       refs/remotes/origin/master
+       EOF
+       test_cmp expect actual
+'
+
+test_expect_success 'clone -c remote.<remote>.fetch=<refspec> --origin=<name>' '
+       rm -rf child &&
+       git clone --origin=upstream \
+                 -c "remote.upstream.fetch=+refs/grab/*:refs/grab/*" \
+                 -c "remote.origin.fetch=+refs/leave/*:refs/leave/*" \
+                 . child &&
+       git -C child for-each-ref --format="%(refname)" >actual &&
+
+       cat >expect <<-\EOF &&
+       refs/grab/it
+       refs/heads/master
+       refs/remotes/upstream/HEAD
+       refs/remotes/upstream/master
+       EOF
+       test_cmp expect actual
+'
+
 # Tests for the hidden file attribute on windows
 is_hidden () {
        # Use the output of `attrib`, ignore the absolute path