summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2018-10-19 04:34:07 (GMT)
committerJunio C Hamano <gitster@pobox.com>2018-10-19 04:34:07 (GMT)
commit0527fbab689929de47ab3fa7baf1e7618ffa704f (patch)
tree225a1b7916ff4b81f30d661f0014f973eea38642 /builtin
parentd4cd2dd214c9800c8ccf45cf413acc727f4abcc2 (diff)
parente70a3030e747312327a4f3619247bf8a986aa577 (diff)
downloadgit-0527fbab689929de47ab3fa7baf1e7618ffa704f.zip
git-0527fbab689929de47ab3fa7baf1e7618ffa704f.tar.gz
git-0527fbab689929de47ab3fa7baf1e7618ffa704f.tar.bz2
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')
-rw-r--r--builtin/fetch.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 6ce882c..8f7249f 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,