Skip to content

Commit b74cf64

Browse files
peffgitster
authored andcommitted
for-each-ref: avoid loading objects to print %(objectname)
If you ask for-each-ref to print each ref and its object, like: git for-each-ref --format='%(objectname) %(refname)' this should involve little more work than looking at the ref files (and packed-refs) themselves. However, for-each-ref will actually load each object from disk just to print its sha1. For most repositories, this isn't a big deal, but it can be noticeable if you have a large number of refs to print. Here are best-of-five timings for the command above on a repo with ~10K refs: [before] real 0m0.112s user 0m0.092s sys 0m0.016s [after] real 0m0.014s user 0m0.012s sys 0m0.000s This patch checks for %(objectname) and %(objectname:short) before we actually parse the object (and the rest of the code is smart enough to avoid parsing if we have filled all of our placeholders). Note that we can't simply move the objectname parsing code into the early loop. If the "deref" form %(*objectname) is used, then we do need to parse the object in order to peel the tag. So instead of moving the code, we factor it out into a separate function that can be called for both cases. While we're at it, we add some basic tests for the dereferenced placeholders, which were not tested at all before. This helps ensure we didn't regress that case. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e230c56 commit b74cf64

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

builtin/for-each-ref.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,22 @@ static void *get_obj(const unsigned char *sha1, struct object **obj, unsigned lo
205205
return buf;
206206
}
207207

208+
static int grab_objectname(const char *name, const unsigned char *sha1,
209+
struct atom_value *v)
210+
{
211+
if (!strcmp(name, "objectname")) {
212+
char *s = xmalloc(41);
213+
strcpy(s, sha1_to_hex(sha1));
214+
v->s = s;
215+
return 1;
216+
}
217+
if (!strcmp(name, "objectname:short")) {
218+
v->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
219+
return 1;
220+
}
221+
return 0;
222+
}
223+
208224
/* See grab_values */
209225
static void grab_common_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
210226
{
@@ -225,15 +241,8 @@ static void grab_common_values(struct atom_value *val, int deref, struct object
225241
v->ul = sz;
226242
v->s = s;
227243
}
228-
else if (!strcmp(name, "objectname")) {
229-
char *s = xmalloc(41);
230-
strcpy(s, sha1_to_hex(obj->sha1));
231-
v->s = s;
232-
}
233-
else if (!strcmp(name, "objectname:short")) {
234-
v->s = xstrdup(find_unique_abbrev(obj->sha1,
235-
DEFAULT_ABBREV));
236-
}
244+
else if (deref)
245+
grab_objectname(name, obj->sha1, v);
237246
}
238247
}
239248

@@ -676,6 +685,8 @@ static void populate_value(struct refinfo *ref)
676685
}
677686
continue;
678687
}
688+
else if (!deref && grab_objectname(name, ref->objectname, v))
689+
continue;
679690
else
680691
continue;
681692

t/t6300-for-each-ref.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ test_atom head parent ''
5858
test_atom head numparent 0
5959
test_atom head object ''
6060
test_atom head type ''
61+
test_atom head '*objectname' ''
62+
test_atom head '*objecttype' ''
6163
test_atom head author 'A U Thor <[email protected]> 1151939924 +0200'
6264
test_atom head authorname 'A U Thor'
6365
test_atom head authoremail '<[email protected]>'
@@ -91,6 +93,8 @@ test_atom tag parent ''
9193
test_atom tag numparent ''
9294
test_atom tag object '67a36f10722846e891fbada1ba48ed035de75581'
9395
test_atom tag type 'commit'
96+
test_atom tag '*objectname' '67a36f10722846e891fbada1ba48ed035de75581'
97+
test_atom tag '*objecttype' 'commit'
9498
test_atom tag author ''
9599
test_atom tag authorname ''
96100
test_atom tag authoremail ''

0 commit comments

Comments
 (0)