Browse Source

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>
maint
Jeff King 8 years ago committed by Junio C Hamano
parent
commit
613a0e52ea
  1. 16
      ref-filter.c

16
ref-filter.c

@ -92,6 +92,7 @@ static struct used_atom {
unsigned int length; unsigned int length;
} objectname; } objectname;
struct refname_atom refname; struct refname_atom refname;
char *head;
} u; } u;
} *used_atom; } *used_atom;
static int used_atom_cnt, need_tagged, need_symref; 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 { static struct {
const char *name; const char *name;
@ -324,7 +331,7 @@ static struct {
{ "push", FIELD_STR, remote_ref_atom_parser }, { "push", FIELD_STR, remote_ref_atom_parser },
{ "symref", FIELD_STR, refname_atom_parser }, { "symref", FIELD_STR, refname_atom_parser },
{ "flag" }, { "flag" },
{ "HEAD" }, { "HEAD", FIELD_STR, head_atom_parser },
{ "color", FIELD_STR, color_atom_parser }, { "color", FIELD_STR, color_atom_parser },
{ "align", FIELD_STR, align_atom_parser }, { "align", FIELD_STR, align_atom_parser },
{ "end" }, { "end" },
@ -1366,12 +1373,7 @@ static void populate_value(struct ref_array_item *ref)
} else if (!deref && grab_objectname(name, ref->objectname, v, atom)) { } else if (!deref && grab_objectname(name, ref->objectname, v, atom)) {
continue; continue;
} else if (!strcmp(name, "HEAD")) { } else if (!strcmp(name, "HEAD")) {
const char *head; if (atom->u.head && !strcmp(ref->refname, atom->u.head))
unsigned char sha1[20];

head = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
sha1, NULL);
if (head && !strcmp(ref->refname, head))
v->s = "*"; v->s = "*";
else else
v->s = " "; v->s = " ";

Loading…
Cancel
Save