]> granicus.if.org Git - git/commitdiff
transport: do not list refs if possible
authorJonathan Tan <jonathantanmy@google.com>
Thu, 27 Sep 2018 19:24:05 +0000 (12:24 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 7 Oct 2018 00:53:15 +0000 (09:53 +0900)
When all refs to be fetched are exact OIDs, it is possible to perform a
fetch without requiring the remote to list refs if protocol v2 is used.
Teach Git to do this.

This currently has an effect only for lazy fetches done from partial
clones. The change necessary to likewise optimize "git fetch <remote>
<sha-1>" will be done in a subsequent patch.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
fetch-pack.c
t/t5702-protocol-v2.sh
transport.c

index 75047a4b2a491e805f7c500dc804e78a8538bfa2..15652b47762d131d22814ac122a7e216eda8164c 100644 (file)
@@ -1598,7 +1598,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
        if (nr_sought)
                nr_sought = remove_duplicates_in_refs(sought, nr_sought);
 
-       if (!ref) {
+       if (version != protocol_v2 && !ref) {
                packet_flush(fd[1]);
                die(_("no matching remote head"));
        }
index 3beeed4546cee6c7793de94ba2735b0e6d63b073..e32b5b4e3e2dadb44553ef4627fee817c56d752b 100755 (executable)
@@ -286,6 +286,10 @@ test_expect_success 'dynamically fetch missing object' '
        grep "version 2" trace
 '
 
+test_expect_success 'when dynamically fetching missing object, do not list refs' '
+       ! grep "git> command=ls-refs" trace
+'
+
 test_expect_success 'partial fetch' '
        rm -rf client "$(pwd)/trace" &&
        git init client &&
index 5fb9ff6b56f4b20705451a4d2a290fe8ad6fb619..4329cca8e5a831db1892d57cd75f3d06bed3e94a 100644 (file)
@@ -341,8 +341,17 @@ static int fetch_refs_via_pack(struct transport *transport,
        args.server_options = transport->server_options;
        args.negotiation_tips = data->options.negotiation_tips;
 
-       if (!data->got_remote_heads)
-               refs_tmp = get_refs_via_connect(transport, 0, NULL);
+       if (!data->got_remote_heads) {
+               int i;
+               int must_list_refs = 0;
+               for (i = 0; i < nr_heads; i++) {
+                       if (!to_fetch[i]->exact_oid) {
+                               must_list_refs = 1;
+                               break;
+                       }
+               }
+               refs_tmp = handshake(transport, 0, NULL, must_list_refs);
+       }
 
        switch (data->version) {
        case protocol_v2: