diff options
author | Jonathan Tan <jonathantanmy@google.com> | 2018-09-27 12:24:07 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2018-10-07 09:53:21 +0900 |
commit | e70a3030e747312327a4f3619247bf8a986aa577 (patch) | |
tree | 595256e117267f0dd72e9e7c75104efc9fd62dd4 /builtin/fetch.c | |
parent | transport: list refs before fetch if necessary (diff) | |
download | tgif-e70a3030e747312327a4f3619247bf8a986aa577.tar.xz |
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 <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 0696abfc2a..4c4f8fa194 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1175,6 +1175,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) @@ -1190,17 +1191,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, |