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>
Brandon Williams committed
Jul 20, 2018 at 15:07 UTC
402c47d939160acc389bbff083fbce9f5482a275
2 files changed
+21
-6
builtin/clone.c
+15
-5
@@ -895,7 +895,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
895
int err = 0, complete_refs_before_fetch = 1;
896
int submodule_progress;
897
898
- struct refspec_item refspec;
898
+ struct refspec rs = REFSPEC_INIT_FETCH;
899
+ struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
900
901
fetch_if_missing = 0;
902
@@ -1077,7 +1078,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1078
if (option_required_reference.nr || option_optional_reference.nr)
1079
setup_reference();
1080
1080
- refspec_item_init(&refspec, value.buf, REFSPEC_FETCH);
1081
+ refspec_append(&rs, value.buf);
1082
1083
strbuf_reset(&value);
1084
@@ -1134,10 +1135,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1135
if (transport->smart_options && !deepen && !filter_options.choice)
1136
transport->smart_options->check_self_contained_and_connected = 1;
1137
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);
1147
1148
if (refs) {
1140
- mapped_refs = wanted_peer_refs(refs, &refspec);
1149
+ mapped_refs = wanted_peer_refs(refs, &rs.items[0]);
1150
/*
1151
* transport_get_remote_refs() may return refs with null sha-1
1152
* in mapped_refs (see struct transport->get_refs_list
@@ -1231,6 +1240,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1240
strbuf_release(&value);
1241
junk_mode = JUNK_LEAVE_ALL;
1242
1234
- refspec_item_clear(&refspec);
1243
+ refspec_clear(&rs);
1244
+ argv_array_clear(&ref_prefixes);
1245
return err;
1246
}
t/t5702-protocol-v2.sh
+6
-1
@@ -181,7 +181,12 @@ test_expect_success 'clone with file:// using protocol v2' '
181
test_cmp expect actual &&
182
183
# 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
190
'
191
192
test_expect_success 'fetch with file:// using protocol v2' '