packfile: disentangle return value of `packed_object_info()`

The `packed_object_info()` function returns the type of the packed object. While we use an `enum object_type` to store the return value, this type is not to be confused with the actual object type. It _may_ contain the object type, but it may just as well encode that the given packed object is stored as a delta. We have removed the only caller that relied on this returned object type in the preceding commit, so let's simplify semantics and return either 0 on success or a negative error code otherwise. This unblocks a small optimization where we can skip reading the object type altogether. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jan 12, 2026 at 10:00 UTC 8908c303da91400e8d9643da6fc697a081ac7374
2 files changed +16 -9
packfile.c
+12 -9
@@ -1587,6 +1587,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,
1587 unsigned long size;
1588 off_t curpos = obj_offset;
1589 enum object_type type;
1590 + int ret;
1591
1592 /*
1593 * We always get the representation type, but only convert it to
@@ -1607,12 +1608,12 @@ int packed_object_info(struct repository *r, struct packed_git *p,
1608 off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
1609 type, obj_offset);
1610 if (!base_offset) {
1610 - type = OBJ_BAD;
1611 + ret = -1;
1612 goto out;
1613 }
1614 *oi->sizep = get_size_from_delta(p, &w_curs, tmp_pos);
1615 if (*oi->sizep == 0) {
1615 - type = OBJ_BAD;
1616 + ret = -1;
1617 goto out;
1618 }
1619 } else {
@@ -1625,7 +1626,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,
1626 if (offset_to_pack_pos(p, obj_offset, &pos) < 0) {
1627 error("could not find object at offset %"PRIuMAX" "
1628 "in pack %s", (uintmax_t)obj_offset, p->pack_name);
1628 - type = OBJ_BAD;
1629 + ret = -1;
1630 goto out;
1631 }
1632
@@ -1639,7 +1640,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,
1640 if (oi->typep)
1641 *oi->typep = ptot;
1642 if (ptot < 0) {
1642 - type = OBJ_BAD;
1643 + ret = -1;
1644 goto out;
1645 }
1646 }
@@ -1649,7 +1650,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,
1650 if (get_delta_base_oid(p, &w_curs, curpos,
1651 oi->delta_base_oid,
1652 type, obj_offset) < 0) {
1652 - type = OBJ_BAD;
1653 + ret = -1;
1654 goto out;
1655 }
1656 } else
@@ -1672,9 +1673,11 @@ int packed_object_info(struct repository *r, struct packed_git *p,
1673 break;
1674 }
1675
1676 + ret = 0;
1677 +
1678 out:
1679 unuse_pack(&w_curs);
1677 - return type;
1680 + return ret;
1681 }
1682
1683 static void *unpack_compressed_entry(struct packed_git *p,
@@ -2152,7 +2155,7 @@ int packfile_store_read_object_info(struct packfile_store *store,
2155 unsigned flags UNUSED)
2156 {
2157 struct pack_entry e;
2155 - int rtype;
2158 + int ret;
2159
2160 if (!find_pack_entry(store->odb->repo, oid, &e))
2161 return 1;
@@ -2164,8 +2167,8 @@ int packfile_store_read_object_info(struct packfile_store *store,
2167 if (!oi)
2168 return 0;
2169
2167 - rtype = packed_object_info(store->odb->repo, e.p, e.offset, oi);
2168 - if (rtype < 0) {
2170 + ret = packed_object_info(store->odb->repo, e.p, e.offset, oi);
2171 + if (ret < 0) {
2172 mark_bad_packed_object(e.p, oid);
2173 return -1;
2174 }
packfile.h
+4
@@ -378,6 +378,10 @@ void release_pack_memory(size_t);
378 /* global flag to enable extra checks when accessing packed objects */
379 extern int do_check_packed_object_crc;
380
381 +/*
382 + * Look up the object info for a specific offset in the packfile.
383 + * Returns zero on success, a negative error code otherwise.
384 + */
385 int packed_object_info(struct repository *r,
386 struct packed_git *pack,
387 off_t offset, struct object_info *);