Merge branch 'bw/clone-ref-prefixes'
authorJunio C Hamano <gitster@pobox.com>
Wed, 15 Aug 2018 22:08:23 +0000 (15:08 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 15 Aug 2018 22:08:23 +0000 (15:08 -0700)
The wire-protocol v2 relies on the client to send "ref prefixes" to
limit the bandwidth spent on the initial ref advertisement. "git
clone" when learned to speak v2 forgot to do so, which has been
corrected.

* bw/clone-ref-prefixes:
clone: send ref-prefixes when using protocol v2

builtin/clone.c
t/t5702-protocol-v2.sh
index 9ebb5acf56c5e03f8acafda4d806d6e3a41ee91f..26fb0da42dff2124e90999a352c9dc9cdf94d6ac 100644 (file)
@@ -897,7 +897,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        int err = 0, complete_refs_before_fetch = 1;
        int submodule_progress;
 
-       struct refspec_item refspec;
+       struct refspec rs = REFSPEC_INIT_FETCH;
+       struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
 
        fetch_if_missing = 0;
 
@@ -1079,7 +1080,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        if (option_required_reference.nr || option_optional_reference.nr)
                setup_reference();
 
-       refspec_item_init_or_die(&refspec, value.buf, REFSPEC_FETCH);
+       refspec_append(&rs, value.buf);
 
        strbuf_reset(&value);
 
@@ -1136,10 +1137,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        if (transport->smart_options && !deepen && !filter_options.choice)
                transport->smart_options->check_self_contained_and_connected = 1;
 
-       refs = transport_get_remote_refs(transport, NULL);
+
+       argv_array_push(&ref_prefixes, "HEAD");
+       refspec_ref_prefixes(&rs, &ref_prefixes);
+       if (option_branch)
+               expand_ref_prefix(&ref_prefixes, option_branch);
+       if (!option_no_tags)
+               argv_array_push(&ref_prefixes, "refs/tags/");
+
+       refs = transport_get_remote_refs(transport, &ref_prefixes);
 
        if (refs) {
-               mapped_refs = wanted_peer_refs(refs, &refspec);
+               mapped_refs = wanted_peer_refs(refs, &rs.items[0]);
                /*
                 * transport_get_remote_refs() may return refs with null sha-1
                 * in mapped_refs (see struct transport->get_refs_list
@@ -1233,6 +1242,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        strbuf_release(&value);
        junk_mode = JUNK_LEAVE_ALL;
 
-       refspec_item_clear(&refspec);
+       refspec_clear(&rs);
+       argv_array_clear(&ref_prefixes);
        return err;
 }
index a4fe6508bdd73784758b2ea80ab81752e15c01b3..9ae560eb2a7238b9ec7d7fca27e10715956b6a00 100755 (executable)
@@ -181,7 +181,12 @@ test_expect_success 'clone with file:// using protocol v2' '
        test_cmp expect actual &&
 
        # Server responded using protocol v2
-       grep "clone< version 2" log
+       grep "clone< version 2" log &&
+
+       # Client sent ref-prefixes to filter the ref-advertisement
+       grep "ref-prefix HEAD" log &&
+       grep "ref-prefix refs/heads/" log &&
+       grep "ref-prefix refs/tags/" log
 '
 
 test_expect_success 'fetch with file:// using protocol v2' '