Skip to content

Commit 402c47d

Browse files
bmwillgitster
authored andcommitted
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>
1 parent 53f9a3e commit 402c47d

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

builtin/clone.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
895895
int err = 0, complete_refs_before_fetch = 1;
896896
int submodule_progress;
897897

898-
struct refspec_item refspec;
898+
struct refspec rs = REFSPEC_INIT_FETCH;
899+
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
899900

900901
fetch_if_missing = 0;
901902

@@ -1077,7 +1078,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
10771078
if (option_required_reference.nr || option_optional_reference.nr)
10781079
setup_reference();
10791080

1080-
refspec_item_init(&refspec, value.buf, REFSPEC_FETCH);
1081+
refspec_append(&rs, value.buf);
10811082

10821083
strbuf_reset(&value);
10831084

@@ -1134,10 +1135,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
11341135
if (transport->smart_options && !deepen && !filter_options.choice)
11351136
transport->smart_options->check_self_contained_and_connected = 1;
11361137

1137-
refs = transport_get_remote_refs(transport, NULL);
1138+
1139+
argv_array_push(&ref_prefixes, "HEAD");
1140+
refspec_ref_prefixes(&rs, &ref_prefixes);
1141+
if (option_branch)
1142+
expand_ref_prefix(&ref_prefixes, option_branch);
1143+
if (!option_no_tags)
1144+
argv_array_push(&ref_prefixes, "refs/tags/");
1145+
1146+
refs = transport_get_remote_refs(transport, &ref_prefixes);
11381147

11391148
if (refs) {
1140-
mapped_refs = wanted_peer_refs(refs, &refspec);
1149+
mapped_refs = wanted_peer_refs(refs, &rs.items[0]);
11411150
/*
11421151
* transport_get_remote_refs() may return refs with null sha-1
11431152
* in mapped_refs (see struct transport->get_refs_list
@@ -1231,6 +1240,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
12311240
strbuf_release(&value);
12321241
junk_mode = JUNK_LEAVE_ALL;
12331242

1234-
refspec_item_clear(&refspec);
1243+
refspec_clear(&rs);
1244+
argv_array_clear(&ref_prefixes);
12351245
return err;
12361246
}

t/t5702-protocol-v2.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,12 @@ test_expect_success 'clone with file:// using protocol v2' '
181181
test_cmp expect actual &&
182182
183183
# Server responded using protocol v2
184-
grep "clone< version 2" log
184+
grep "clone< version 2" log &&
185+
186+
# Client sent ref-prefixes to filter the ref-advertisement
187+
grep "ref-prefix HEAD" log &&
188+
grep "ref-prefix refs/heads/" log &&
189+
grep "ref-prefix refs/tags/" log
185190
'
186191

187192
test_expect_success 'fetch with file:// using protocol v2' '

0 commit comments

Comments
 (0)