From ca3b4933e97be13a006eba8574d608275f2c0694 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 7 Jan 2026 14:08:05 +0100 Subject: [PATCH] packfile: skip unpacking object header for disk size requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While most of the object info requests for a packed object require us to unpack its headers, reading its disk size doesn't. We still unpack the object header in that case though, which is unnecessary work. Skip reading the header if only the disk size is requested. This leads to a small speedup when reading disk size, only. The following benchmark was done in the Git repository: Benchmark 1: ./git rev-list --disk-usage HEAD (rev = HEAD~) Time (mean ± σ): 105.2 ms ± 0.6 ms [User: 91.4 ms, System: 13.3 ms] Range (min … max): 103.7 ms … 106.0 ms 27 runs Benchmark 2: ./git rev-list --disk-usage HEAD (rev = HEAD) Time (mean ± σ): 96.7 ms ± 0.4 ms [User: 86.2 ms, System: 10.0 ms] Range (min … max): 96.2 ms … 98.1 ms 30 runs Summary ./git rev-list --disk-usage HEAD (rev = HEAD) ran 1.09 ± 0.01 times faster than ./git rev-list --disk-usage HEAD (rev = HEAD~) Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- packfile.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packfile.c b/packfile.c index 8c6ef45a67..a2ba237ce7 100644 --- a/packfile.c +++ b/packfile.c @@ -1586,7 +1586,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, struct pack_window *w_curs = NULL; unsigned long size; off_t curpos = obj_offset; - enum object_type type; + enum object_type type = OBJ_NONE; int ret; /* @@ -1598,7 +1598,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, &type); if (!*oi->contentp) type = OBJ_BAD; - } else { + } else if (oi->sizep || oi->typep || oi->delta_base_oid) { type = unpack_object_header(p, &w_curs, &curpos, &size); } @@ -1662,6 +1662,9 @@ int packed_object_info(struct repository *r, struct packed_git *p, oi->u.packed.pack = p; switch (type) { + case OBJ_NONE: + oi->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN; + break; case OBJ_REF_DELTA: oi->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA; break;