diff --git a/log-tree.c b/log-tree.c --- a/log-tree.c +++ b/log-tree.c @@ -174,9 +174,20 @@ return 0; } - objtype = odb_read_object_info(the_repository->objects, ref->oid, NULL); - if (objtype < 0) - return 0; + if (ref->peeled_oid) { + /* + * packed-refs only records a peeled line for refs that point + * at a tag object, so the ref backend has already told us the + * type. Asking the object store again costs a binary search + * through the pack index, per ref, per process. + */ + objtype = OBJ_TAG; + } else { + objtype = odb_read_object_info(the_repository->objects, + ref->oid, NULL); + if (objtype < 0) + return 0; + } obj = lookup_object_by_type(the_repository, ref->oid, objtype); for (i = 0; i < ARRAY_SIZE(ref_namespace); i++) { @@ -206,12 +217,14 @@ */ if (ref->peeled_oid && !reference_get_peeled_oid(the_repository, ref, &peeled)) { - enum object_type ptype; - ptype = odb_read_object_info(the_repository->objects, - &peeled, NULL); - if (ptype < 0) - return 0; - obj = lookup_object_by_type(the_repository, &peeled, ptype); + /* + * The decoration only ever uses this object as a key; + * nothing reads its type. lookup_unknown_object() + * hands back the same struct that a later + * lookup_commit() will fill in, and skips a second + * pack index search. + */ + obj = lookup_unknown_object(the_repository, &peeled); if (obj) add_name_decoration(DECORATION_REF_TAG, ref->name, obj); return 0;