Skip to content

Commit e70a303

Browse files
jonathantanmygitster
authored andcommitted
fetch: do not list refs if fetching only hashes
If only hash literals are given on a "git fetch" command-line, tag following is not requested, and the fetch is done using protocol v2, a list of refs is not required from the remote. Therefore, optimize by invoking transport_get_remote_refs() only if we need the refs. Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6ab4055 commit e70a303

File tree

3 files changed

+54
-6
lines changed

3 files changed

+54
-6
lines changed

builtin/fetch.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,7 @@ static int do_fetch(struct transport *transport,
11751175
int retcode = 0;
11761176
const struct ref *remote_refs;
11771177
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
1178+
int must_list_refs = 1;
11781179

11791180
if (tags == TAGS_DEFAULT) {
11801181
if (transport->remote->fetch_tags == 2)
@@ -1190,17 +1191,36 @@ static int do_fetch(struct transport *transport,
11901191
goto cleanup;
11911192
}
11921193

1193-
if (rs->nr)
1194+
if (rs->nr) {
1195+
int i;
1196+
11941197
refspec_ref_prefixes(rs, &ref_prefixes);
1195-
else if (transport->remote && transport->remote->fetch.nr)
1198+
1199+
/*
1200+
* We can avoid listing refs if all of them are exact
1201+
* OIDs
1202+
*/
1203+
must_list_refs = 0;
1204+
for (i = 0; i < rs->nr; i++) {
1205+
if (!rs->items[i].exact_sha1) {
1206+
must_list_refs = 1;
1207+
break;
1208+
}
1209+
}
1210+
} else if (transport->remote && transport->remote->fetch.nr)
11961211
refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes);
11971212

1198-
if (ref_prefixes.argc &&
1199-
(tags == TAGS_SET || (tags == TAGS_DEFAULT))) {
1200-
argv_array_push(&ref_prefixes, "refs/tags/");
1213+
if (tags == TAGS_SET || tags == TAGS_DEFAULT) {
1214+
must_list_refs = 1;
1215+
if (ref_prefixes.argc)
1216+
argv_array_push(&ref_prefixes, "refs/tags/");
12011217
}
12021218

1203-
remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
1219+
if (must_list_refs)
1220+
remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
1221+
else
1222+
remote_refs = NULL;
1223+
12041224
argv_array_clear(&ref_prefixes);
12051225

12061226
ref_map = get_ref_map(transport->remote, remote_refs, rs,

t/t5551-http-fetch-smart.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,21 @@ test_expect_success 'using fetch command in remote-curl updates refs' '
381381
test_cmp expect actual
382382
'
383383

384+
test_expect_success 'fetch by SHA-1 without tag following' '
385+
SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" &&
386+
rm -rf "$SERVER" client &&
387+
388+
git init "$SERVER" &&
389+
test_commit -C "$SERVER" foo &&
390+
391+
git clone $HTTPD_URL/smart/server client &&
392+
393+
test_commit -C "$SERVER" bar &&
394+
git -C "$SERVER" rev-parse bar >bar_hash &&
395+
git -C client -c protocol.version=0 fetch \
396+
--no-tags origin $(cat bar_hash)
397+
'
398+
384399
test_expect_success 'GIT_REDACT_COOKIES redacts cookies' '
385400
rm -rf clone &&
386401
echo "Set-Cookie: Foo=1" >cookies &&

t/t5702-protocol-v2.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ test_expect_success 'fetch with git:// using protocol v2' '
7979
grep "fetch< version 2" log
8080
'
8181

82+
test_expect_success 'fetch by hash without tag following with protocol v2 does not list refs' '
83+
test_when_finished "rm -f log" &&
84+
85+
test_commit -C "$daemon_parent" two_a &&
86+
git -C "$daemon_parent" rev-parse two_a >two_a_hash &&
87+
88+
GIT_TRACE_PACKET="$(pwd)/log" git -C daemon_child -c protocol.version=2 \
89+
fetch --no-tags origin $(cat two_a_hash) &&
90+
91+
grep "fetch< version 2" log &&
92+
! grep "fetch> command=ls-refs" log
93+
'
94+
8295
test_expect_success 'pull with git:// using protocol v2' '
8396
test_when_finished "rm -f log" &&
8497

0 commit comments

Comments
 (0)