diff options
| author | Junio C Hamano <gitster@pobox.com> | 2018-10-19 13:34:07 +0900 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2018-10-19 13:34:07 +0900 |
| commit | 0527fbab689929de47ab3fa7baf1e7618ffa704f (patch) | |
| tree | 225a1b7916ff4b81f30d661f0014f973eea38642 /builtin/fetch.c | |
| parent | d4cd2dd214c9800c8ccf45cf413acc727f4abcc2 (diff) | |
| parent | e70a3030e747312327a4f3619247bf8a986aa577 (diff) | |
| download | git-0527fbab689929de47ab3fa7baf1e7618ffa704f.tar.gz | |
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.c | 32 |
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, |
