diff options
author | Brandon Williams <bmwill@google.com> | 2018-07-20 15:07:54 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2018-07-20 15:25:19 -0700 |
commit | 402c47d939160acc389bbff083fbce9f5482a275 (patch) | |
tree | c782b9a46c21ab20d975deac0b3e780246870748 | |
parent | Git 2.18 (diff) | |
download | tgif-402c47d939160acc389bbff083fbce9f5482a275.tar.xz |
clone: send ref-prefixes when using protocol v2
Teach clone to send a list of ref-prefixes, when using protocol v2, to
allow the server to filter out irrelevant references from the
ref-advertisement. This reduces wasted time and bandwidth when cloning
repositories with a larger number of references.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | builtin/clone.c | 20 | ||||
-rwxr-xr-x | t/t5702-protocol-v2.sh | 7 |
2 files changed, 21 insertions, 6 deletions
diff --git a/builtin/clone.c b/builtin/clone.c index 99e73dae85..5c0adbd6d0 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -895,7 +895,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; @@ -1077,7 +1078,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(&refspec, value.buf, REFSPEC_FETCH); + refspec_append(&rs, value.buf); strbuf_reset(&value); @@ -1134,10 +1135,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 @@ -1231,6 +1240,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; } diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index a4fe6508bd..9ae560eb2a 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -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' ' |