summaryrefslogtreecommitdiff
path: root/builtin/fetch.c
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2018-10-19 13:34:07 +0900
committerLibravatar Junio C Hamano <gitster@pobox.com>2018-10-19 13:34:07 +0900
commit0527fbab689929de47ab3fa7baf1e7618ffa704f (patch)
tree225a1b7916ff4b81f30d661f0014f973eea38642 /builtin/fetch.c
parentMerge branch 'ds/commit-graph-leakfix' (diff)
parentfetch: do not list refs if fetching only hashes (diff)
downloadtgif-0527fbab689929de47ab3fa7baf1e7618ffa704f.tar.xz
Merge branch 'jt/avoid-ls-refs'
Over some transports, fetching objects with an exact commit object name can be done without first seeing the ref advertisements. The code has been optimized to exploit this. * jt/avoid-ls-refs: fetch: do not list refs if fetching only hashes transport: list refs before fetch if necessary transport: do not list refs if possible transport: allow skipping of ref listing
Diffstat (limited to 'builtin/fetch.c')
-rw-r--r--builtin/fetch.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 6ce882ce82..8f7249f2b1 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1186,6 +1186,7 @@ static int do_fetch(struct transport *transport,
int retcode = 0;
const struct ref *remote_refs;
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
+ int must_list_refs = 1;
if (tags == TAGS_DEFAULT) {
if (transport->remote->fetch_tags == 2)
@@ -1201,17 +1202,36 @@ static int do_fetch(struct transport *transport,
goto cleanup;
}
- if (rs->nr)
+ if (rs->nr) {
+ int i;
+
refspec_ref_prefixes(rs, &ref_prefixes);
- else if (transport->remote && transport->remote->fetch.nr)
+
+ /*
+ * We can avoid listing refs if all of them are exact
+ * OIDs
+ */
+ must_list_refs = 0;
+ for (i = 0; i < rs->nr; i++) {
+ if (!rs->items[i].exact_sha1) {
+ must_list_refs = 1;
+ break;
+ }
+ }
+ } else if (transport->remote && transport->remote->fetch.nr)
refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes);
- if (ref_prefixes.argc &&
- (tags == TAGS_SET || (tags == TAGS_DEFAULT))) {
- argv_array_push(&ref_prefixes, "refs/tags/");
+ if (tags == TAGS_SET || tags == TAGS_DEFAULT) {
+ must_list_refs = 1;
+ if (ref_prefixes.argc)
+ argv_array_push(&ref_prefixes, "refs/tags/");
}
- remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
+ if (must_list_refs)
+ remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
+ else
+ remote_refs = NULL;
+
argv_array_clear(&ref_prefixes);
ref_map = get_ref_map(transport->remote, remote_refs, rs,