summaryrefslogtreecommitdiff
path: root/ref-filter.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2017-05-19 06:12:12 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-05-20 09:18:45 (GMT)
commit613a0e52ea11c4496e3e154de192486a18eac2e4 (patch)
treeba35570dbd632ef85686276574abf025a0487296 /ref-filter.c
parentac5bbc02b8c3781d517f1414655270b3fa38b028 (diff)
downloadgit-613a0e52ea11c4496e3e154de192486a18eac2e4.zip
git-613a0e52ea11c4496e3e154de192486a18eac2e4.tar.gz
git-613a0e52ea11c4496e3e154de192486a18eac2e4.tar.bz2
ref-filter: resolve HEAD when parsing %(HEAD) atom
If the user asks to display (or sort by) the %(HEAD) atom, ref-filter has to compare each refname to the value of HEAD. We do so by resolving HEAD fresh when calling populate_value() on each ref. If there are a large number of refs, this can have a measurable impact on runtime. Instead, let's resolve HEAD once when we realize we need the %(HEAD) atom, allowing us to do a simple string comparison for each ref. On a repository with 3000 branches (high, but an actual example found in the wild) this drops the best-of-five time to run "git branch >/dev/null" from 59ms to 48ms (~20% savings). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'ref-filter.c')
-rw-r--r--ref-filter.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/ref-filter.c b/ref-filter.c
index 2a94d6d..f4c6823 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -92,6 +92,7 @@ static struct used_atom {
unsigned int length;
} objectname;
struct refname_atom refname;
+ char *head;
} u;
} *used_atom;
static int used_atom_cnt, need_tagged, need_symref;
@@ -286,6 +287,12 @@ static void if_atom_parser(struct used_atom *atom, const char *arg)
}
}
+static void head_atom_parser(struct used_atom *atom, const char *arg)
+{
+ unsigned char unused[GIT_SHA1_RAWSZ];
+
+ atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, unused, NULL);
+}
static struct {
const char *name;
@@ -324,7 +331,7 @@ static struct {
{ "push", FIELD_STR, remote_ref_atom_parser },
{ "symref", FIELD_STR, refname_atom_parser },
{ "flag" },
- { "HEAD" },
+ { "HEAD", FIELD_STR, head_atom_parser },
{ "color", FIELD_STR, color_atom_parser },
{ "align", FIELD_STR, align_atom_parser },
{ "end" },
@@ -1366,12 +1373,7 @@ static void populate_value(struct ref_array_item *ref)
} else if (!deref && grab_objectname(name, ref->objectname, v, atom)) {
continue;
} else if (!strcmp(name, "HEAD")) {
- const char *head;
- unsigned char sha1[20];
-
- head = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
- sha1, NULL);
- if (head && !strcmp(ref->refname, head))
+ if (atom->u.head && !strcmp(ref->refname, atom->u.head))
v->s = "*";
else
v->s = " ";