Skip to content

Commit 613a0e5

Browse files
peffgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ac5bbc0 commit 613a0e5

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

ref-filter.c

+9-7
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ static struct used_atom {
9292
unsigned int length;
9393
} objectname;
9494
struct refname_atom refname;
95+
char *head;
9596
} u;
9697
} *used_atom;
9798
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)
286287
}
287288
}
288289

290+
static void head_atom_parser(struct used_atom *atom, const char *arg)
291+
{
292+
unsigned char unused[GIT_SHA1_RAWSZ];
293+
294+
atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, unused, NULL);
295+
}
289296

290297
static struct {
291298
const char *name;
@@ -324,7 +331,7 @@ static struct {
324331
{ "push", FIELD_STR, remote_ref_atom_parser },
325332
{ "symref", FIELD_STR, refname_atom_parser },
326333
{ "flag" },
327-
{ "HEAD" },
334+
{ "HEAD", FIELD_STR, head_atom_parser },
328335
{ "color", FIELD_STR, color_atom_parser },
329336
{ "align", FIELD_STR, align_atom_parser },
330337
{ "end" },
@@ -1366,12 +1373,7 @@ static void populate_value(struct ref_array_item *ref)
13661373
} else if (!deref && grab_objectname(name, ref->objectname, v, atom)) {
13671374
continue;
13681375
} else if (!strcmp(name, "HEAD")) {
1369-
const char *head;
1370-
unsigned char sha1[20];
1371-
1372-
head = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
1373-
sha1, NULL);
1374-
if (head && !strcmp(ref->refname, head))
1376+
if (atom->u.head && !strcmp(ref->refname, atom->u.head))
13751377
v->s = "*";
13761378
else
13771379
v->s = " ";

0 commit comments

Comments
 (0)