From b3b89b691c57f1bc4c6847c5aba2b21d0da8ad32 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 7 Jan 2026 14:08:00 +0100 Subject: [PATCH 1/7] object-file: always set OI_LOOSE when reading object info There are some early returns in `odb_source_loose_read_object_info()` in cases where we don't have to open the loose object. These return paths do not set `struct object_info::whence` to `OI_LOOSE` though, so it becomes impossible for the caller to tell the format of such an object. The root cause of this really is that we have so many different return paths in the function. As a consequence, it's harder than necessary to make sure that all successful exit paths sot up the `whence` field as expected. Address this by refactoring the function to have a single exit path. Like this, we can trivially set up the `whence` field when we exit successfully from the function. Note that we also: - Rename `status` to `ret` to match our usual coding style, but also to show that the old `status` variable is now always getting the expected value. Furthermore, the value is not initialized anymore, which has the consequence that most compilers will warn for exit paths where we forgot to set it. - Move the setup of scratch pointers closer to `parse_loose_header()` to show where it's needed. - Guard a couple of variables on cleanup so that they only get released in case they have been set up. - Reset `oi->delta_base_oid` towards the end of the function, together with all the other object info pointers. Overall, all these changes result in a diff that is somewhat hard to read. But the end result is significantly easier to read and reason about, so I'd argue this one-time churn is worth it. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- object-file.c | 115 +++++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 44 deletions(-) diff --git a/object-file.c b/object-file.c index 6280e42f34..e7e4c3348f 100644 --- a/object-file.c +++ b/object-file.c @@ -416,19 +416,16 @@ int odb_source_loose_read_object_info(struct odb_source *source, const struct object_id *oid, struct object_info *oi, int flags) { - int status = 0; + int ret; int fd; unsigned long mapsize; const char *path; - void *map; - git_zstream stream; + void *map = NULL; + git_zstream stream, *stream_to_end = NULL; char hdr[MAX_HEADER_LEN]; unsigned long size_scratch; enum object_type type_scratch; - if (oi && oi->delta_base_oid) - oidclr(oi->delta_base_oid, source->odb->repo->hash_algo); - /* * If we don't care about type or size, then we don't * need to look inside the object at all. Note that we @@ -439,71 +436,101 @@ int odb_source_loose_read_object_info(struct odb_source *source, */ if (!oi || (!oi->typep && !oi->sizep && !oi->contentp)) { struct stat st; - if ((!oi || !oi->disk_sizep) && (flags & OBJECT_INFO_QUICK)) - return quick_has_loose(source->loose, oid) ? 0 : -1; - if (stat_loose_object(source->loose, oid, &st, &path) < 0) - return -1; + + if ((!oi || !oi->disk_sizep) && (flags & OBJECT_INFO_QUICK)) { + ret = quick_has_loose(source->loose, oid) ? 0 : -1; + goto out; + } + + if (stat_loose_object(source->loose, oid, &st, &path) < 0) { + ret = -1; + goto out; + } + if (oi && oi->disk_sizep) *oi->disk_sizep = st.st_size; - return 0; + + ret = 0; + goto out; } fd = open_loose_object(source->loose, oid, &path); if (fd < 0) { if (errno != ENOENT) error_errno(_("unable to open loose object %s"), oid_to_hex(oid)); - return -1; + ret = -1; + goto out; } - map = map_fd(fd, path, &mapsize); - if (!map) - return -1; - if (!oi->sizep) - oi->sizep = &size_scratch; - if (!oi->typep) - oi->typep = &type_scratch; + map = map_fd(fd, path, &mapsize); + if (!map) { + ret = -1; + goto out; + } if (oi->disk_sizep) *oi->disk_sizep = mapsize; + stream_to_end = &stream; + switch (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr))) { case ULHR_OK: - if (parse_loose_header(hdr, oi) < 0) - status = error(_("unable to parse %s header"), oid_to_hex(oid)); - else if (*oi->typep < 0) + if (!oi->sizep) + oi->sizep = &size_scratch; + if (!oi->typep) + oi->typep = &type_scratch; + + if (parse_loose_header(hdr, oi) < 0) { + ret = error(_("unable to parse %s header"), oid_to_hex(oid)); + goto corrupt; + } + + if (*oi->typep < 0) die(_("invalid object type")); - if (!oi->contentp) - break; - *oi->contentp = unpack_loose_rest(&stream, hdr, *oi->sizep, oid); - if (*oi->contentp) - goto cleanup; + if (oi->contentp) { + *oi->contentp = unpack_loose_rest(&stream, hdr, *oi->sizep, oid); + if (!*oi->contentp) { + ret = -1; + goto corrupt; + } + } - status = -1; break; case ULHR_BAD: - status = error(_("unable to unpack %s header"), - oid_to_hex(oid)); - break; + ret = error(_("unable to unpack %s header"), + oid_to_hex(oid)); + goto corrupt; case ULHR_TOO_LONG: - status = error(_("header for %s too long, exceeds %d bytes"), - oid_to_hex(oid), MAX_HEADER_LEN); - break; + ret = error(_("header for %s too long, exceeds %d bytes"), + oid_to_hex(oid), MAX_HEADER_LEN); + goto corrupt; } - if (status && (flags & OBJECT_INFO_DIE_IF_CORRUPT)) + ret = 0; + +corrupt: + if (ret && (flags & OBJECT_INFO_DIE_IF_CORRUPT)) die(_("loose object %s (stored in %s) is corrupt"), oid_to_hex(oid), path); -cleanup: - git_inflate_end(&stream); - munmap(map, mapsize); - if (oi->sizep == &size_scratch) - oi->sizep = NULL; - if (oi->typep == &type_scratch) - oi->typep = NULL; - oi->whence = OI_LOOSE; - return status; +out: + if (stream_to_end) + git_inflate_end(stream_to_end); + if (map) + munmap(map, mapsize); + if (oi) { + if (oi->sizep == &size_scratch) + oi->sizep = NULL; + if (oi->typep == &type_scratch) + oi->typep = NULL; + if (oi->delta_base_oid) + oidclr(oi->delta_base_oid, source->odb->repo->hash_algo); + if (!ret) + oi->whence = OI_LOOSE; + } + + return ret; } static void hash_object_body(const struct git_hash_algo *algo, struct git_hash_ctx *c, From 0ff0f991df049b8bb67d8e6ed821a3b2504a653e Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 7 Jan 2026 14:08:01 +0100 Subject: [PATCH 2/7] packfile: always declare object info to be OI_PACKED When reading object info via a packfile we yield one of two types: - The object can either be OI_PACKED, which is what a caller would typically expect. - Or it can be OI_DBCACHED if it is stored in the delta base cache. The latter really is an implementation detail though, and callers typically don't care at all about the difference. Furthermore, the information whether or not it is part of the delta base cache can already be derived via the `is_delta` field, so the fact that we discern between OI_PACKED and OI_DBCACHED only further complicates the interface. There aren't all that many callers that care about the `whence` field in the first place. In fact, there's only three: - `packfile_store_read_object_info()` checks for `whence == OI_PACKED` and then populates the packfile information of the object info structure. We now start to do this also for deltified objects, which gives its callers strictly more information. - `repack_local_links()` wants to determine whether the object is part of a promisor pack and checks for `whence == OI_PACKED`. If so, it verifies that the packfile is a promisor pack. It's arguably wrong to declare that an object is not part of a promisor pack only because it is stored in the delta base cache. - `is_not_in_promisor_pack_obj()` does the same, but checks that a specific object is _not_ part of a promisor pack. The same reasoning as above applies. Drop the OI_DBCACHED enum completely. None of the callers seem to care about the distinction. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- odb.h | 1 - packfile.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/odb.h b/odb.h index 014cd9585a..73b0b87ad5 100644 --- a/odb.h +++ b/odb.h @@ -330,7 +330,6 @@ struct object_info { OI_CACHED, OI_LOOSE, OI_PACKED, - OI_DBCACHED } whence; union { /* diff --git a/packfile.c b/packfile.c index 08a0863fc3..b0c6665c87 100644 --- a/packfile.c +++ b/packfile.c @@ -1656,8 +1656,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, oidclr(oi->delta_base_oid, p->repo->hash_algo); } - oi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED : - OI_PACKED; + oi->whence = OI_PACKED; out: unuse_pack(&w_curs); From 56be11f501151c4955fc4fd09a8c7a06c73b3f46 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 7 Jan 2026 14:08:02 +0100 Subject: [PATCH 3/7] packfile: extend `is_delta` field to allow for "unknown" state The `struct object_info::u::packed::is_delta` field determines whether or not a specific object is stored as a delta. It only stores whether or not the object is stored as delta, so it is treated as a boolean value. This boolean is insufficient though: when reading a packed object via `packfile_store_read_object_info()` we know to skip parsing the actual object when the user didn't request any object-specific data. In that case we won't read the object itself, but will only look up its position in the packfile. Consequently, we do not know whether it is a delta or not. This isn't really an issue right now, as the check for an empty request is broken. But a subsequent commit will fix it, and once we do we will have the need to also represent an "unknown" delta state. Prepare for this change by introducing a new enum that encodes the object type. We don't use the "unknown" state just yet, but will start to do so in a subsequent commit. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- odb.h | 7 ++++++- packfile.c | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/odb.h b/odb.h index 73b0b87ad5..afae5e5c01 100644 --- a/odb.h +++ b/odb.h @@ -343,7 +343,12 @@ struct object_info { struct { struct packed_git *pack; off_t offset; - unsigned int is_delta; + enum packed_object_type { + PACKED_OBJECT_TYPE_UNKNOWN, + PACKED_OBJECT_TYPE_FULL, + PACKED_OBJECT_TYPE_OFS_DELTA, + PACKED_OBJECT_TYPE_REF_DELTA, + } type; } packed; } u; }; diff --git a/packfile.c b/packfile.c index b0c6665c87..cc797b2b6a 100644 --- a/packfile.c +++ b/packfile.c @@ -2159,8 +2159,18 @@ int packfile_store_read_object_info(struct packfile_store *store, if (oi->whence == OI_PACKED) { oi->u.packed.offset = e.offset; oi->u.packed.pack = e.p; - oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA || - rtype == OBJ_OFS_DELTA); + + switch (rtype) { + case OBJ_REF_DELTA: + oi->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA; + break; + case OBJ_OFS_DELTA: + oi->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA; + break; + default: + oi->u.packed.type = PACKED_OBJECT_TYPE_FULL; + break; + } } return 0; @@ -2531,7 +2541,8 @@ int packfile_store_read_object_stream(struct odb_read_stream **out, oi.sizep = &size; if (packfile_store_read_object_info(store, oid, &oi, 0) || - oi.u.packed.is_delta || + oi.u.packed.type == PACKED_OBJECT_TYPE_REF_DELTA || + oi.u.packed.type == PACKED_OBJECT_TYPE_OFS_DELTA || repo_settings_get_big_file_threshold(store->odb->repo) >= size) return -1; From 03d894e23cda0de863c4d277f34c523898c84746 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 7 Jan 2026 14:08:03 +0100 Subject: [PATCH 4/7] packfile: always populate pack-specific info when reading object info When reading object information via `packed_object_info()` we may not populate the object info's packfile-specific fields. This leads to inconsistent object info depending on whether the info was populated via `packfile_store_read_object_info()` or `packed_object_info()`. Fix this inconsistency so that we can always assume the pack info to be populated when reading object info from a pack. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- packfile.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/packfile.c b/packfile.c index cc797b2b6a..f7c33a2f77 100644 --- a/packfile.c +++ b/packfile.c @@ -1657,6 +1657,20 @@ int packed_object_info(struct repository *r, struct packed_git *p, } oi->whence = OI_PACKED; + oi->u.packed.offset = obj_offset; + oi->u.packed.pack = p; + + switch (type) { + case OBJ_REF_DELTA: + oi->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA; + break; + case OBJ_OFS_DELTA: + oi->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA; + break; + default: + oi->u.packed.type = PACKED_OBJECT_TYPE_FULL; + break; + } out: unuse_pack(&w_curs); @@ -2156,23 +2170,6 @@ int packfile_store_read_object_info(struct packfile_store *store, return -1; } - if (oi->whence == OI_PACKED) { - oi->u.packed.offset = e.offset; - oi->u.packed.pack = e.p; - - switch (rtype) { - case OBJ_REF_DELTA: - oi->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA; - break; - case OBJ_OFS_DELTA: - oi->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA; - break; - default: - oi->u.packed.type = PACKED_OBJECT_TYPE_FULL; - break; - } - } - return 0; } From 9c82ba6c3204f20797d429ee5af04e2127504ac0 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 7 Jan 2026 14:08:04 +0100 Subject: [PATCH 5/7] 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 Signed-off-by: Junio C Hamano --- packfile.c | 21 ++++++++++++--------- packfile.h | 4 ++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packfile.c b/packfile.c index f7c33a2f77..8c6ef45a67 100644 --- a/packfile.c +++ b/packfile.c @@ -1587,6 +1587,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, unsigned long size; off_t curpos = obj_offset; enum object_type type; + int ret; /* * 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, off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos, type, obj_offset); if (!base_offset) { - type = OBJ_BAD; + ret = -1; goto out; } *oi->sizep = get_size_from_delta(p, &w_curs, tmp_pos); if (*oi->sizep == 0) { - type = OBJ_BAD; + ret = -1; goto out; } } else { @@ -1625,7 +1626,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, if (offset_to_pack_pos(p, obj_offset, &pos) < 0) { error("could not find object at offset %"PRIuMAX" " "in pack %s", (uintmax_t)obj_offset, p->pack_name); - type = OBJ_BAD; + ret = -1; goto out; } @@ -1639,7 +1640,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, if (oi->typep) *oi->typep = ptot; if (ptot < 0) { - type = OBJ_BAD; + ret = -1; goto out; } } @@ -1649,7 +1650,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, if (get_delta_base_oid(p, &w_curs, curpos, oi->delta_base_oid, type, obj_offset) < 0) { - type = OBJ_BAD; + ret = -1; goto out; } } else @@ -1672,9 +1673,11 @@ int packed_object_info(struct repository *r, struct packed_git *p, break; } + ret = 0; + out: unuse_pack(&w_curs); - return type; + return ret; } static void *unpack_compressed_entry(struct packed_git *p, @@ -2152,7 +2155,7 @@ int packfile_store_read_object_info(struct packfile_store *store, unsigned flags UNUSED) { struct pack_entry e; - int rtype; + int ret; if (!find_pack_entry(store->odb->repo, oid, &e)) return 1; @@ -2164,8 +2167,8 @@ int packfile_store_read_object_info(struct packfile_store *store, if (!oi) return 0; - rtype = packed_object_info(store->odb->repo, e.p, e.offset, oi); - if (rtype < 0) { + ret = packed_object_info(store->odb->repo, e.p, e.offset, oi); + if (ret < 0) { mark_bad_packed_object(e.p, oid); return -1; } diff --git a/packfile.h b/packfile.h index 59d162a3f4..d7cce582af 100644 --- a/packfile.h +++ b/packfile.h @@ -378,6 +378,10 @@ void release_pack_memory(size_t); /* global flag to enable extra checks when accessing packed objects */ extern int do_check_packed_object_crc; +/* + * Look up the object info for a specific offset in the packfile. + * Returns zero on success, a negative error code otherwise. + */ int packed_object_info(struct repository *r, struct packed_git *pack, off_t offset, struct object_info *); From ca3b4933e97be13a006eba8574d608275f2c0694 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 7 Jan 2026 14:08:05 +0100 Subject: [PATCH 6/7] 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; From 57592cba247124be7b8d7649a605f6b4e81476e7 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 7 Jan 2026 14:08:06 +0100 Subject: [PATCH 7/7] packfile: drop repository parameter from `packed_object_info()` The function `packed_object_info()` takes a packfile and offset and returns the object info for the corresponding object. Despite these two parameters though it also takes a repository pointer. This is redundant information though, as `struct packed_git` already has a repository pointer that is always populated. Drop the redundant parameter. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/cat-file.c | 3 +-- builtin/pack-objects.c | 4 ++-- commit-graph.c | 2 +- pack-bitmap.c | 3 +-- packfile.c | 8 ++++---- packfile.h | 3 +-- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 505ddaa12f..2ad712e9f8 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -487,8 +487,7 @@ static void batch_object_write(const char *obj_name, data->info.sizep = &data->size; if (pack) - ret = packed_object_info(the_repository, pack, - offset, &data->info); + ret = packed_object_info(pack, offset, &data->info); else ret = odb_read_object_info_extended(the_repository->objects, &data->oid, &data->info, diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 1ce8d6ee21..85762f8c4f 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -2411,7 +2411,7 @@ static void drop_reused_delta(struct object_entry *entry) oi.sizep = &size; oi.typep = &type; - if (packed_object_info(the_repository, IN_PACK(entry), entry->in_pack_offset, &oi) < 0) { + if (packed_object_info(IN_PACK(entry), entry->in_pack_offset, &oi) < 0) { /* * We failed to get the info from this pack for some reason; * fall back to odb_read_object_info, which may find another copy. @@ -3748,7 +3748,7 @@ static int add_object_entry_from_pack(const struct object_id *oid, struct object_info oi = OBJECT_INFO_INIT; oi.typep = &type; - if (packed_object_info(the_repository, p, ofs, &oi) < 0) { + if (packed_object_info(p, ofs, &oi) < 0) { die(_("could not get type of object %s in pack %s"), oid_to_hex(oid), p->pack_name); } else if (type == OBJ_COMMIT) { diff --git a/commit-graph.c b/commit-graph.c index 80be2ff2c3..f572670bd0 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1499,7 +1499,7 @@ static int add_packed_commits(const struct object_id *oid, display_progress(ctx->progress, ++ctx->progress_done); oi.typep = &type; - if (packed_object_info(ctx->r, pack, offset, &oi) < 0) + if (packed_object_info(pack, offset, &oi) < 0) die(_("unable to get type of object %s"), oid_to_hex(oid)); if (type != OBJ_COMMIT) diff --git a/pack-bitmap.c b/pack-bitmap.c index 8ca79725b1..972203f12b 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -1876,8 +1876,7 @@ static unsigned long get_size_by_pos(struct bitmap_index *bitmap_git, ofs = pack_pos_to_offset(pack, pos); } - if (packed_object_info(bitmap_repo(bitmap_git), pack, ofs, - &oi) < 0) { + if (packed_object_info(pack, ofs, &oi) < 0) { struct object_id oid; nth_bitmap_object_oid(bitmap_git, &oid, pack_pos_to_index(pack, pos)); diff --git a/packfile.c b/packfile.c index a2ba237ce7..39899aec49 100644 --- a/packfile.c +++ b/packfile.c @@ -1580,7 +1580,7 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset, hashmap_add(&delta_base_cache, &ent->ent); } -int packed_object_info(struct repository *r, struct packed_git *p, +int packed_object_info(struct packed_git *p, off_t obj_offset, struct object_info *oi) { struct pack_window *w_curs = NULL; @@ -1594,7 +1594,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, * a "real" type later if the caller is interested. */ if (oi->contentp) { - *oi->contentp = cache_or_unpack_entry(r, p, obj_offset, oi->sizep, + *oi->contentp = cache_or_unpack_entry(p->repo, p, obj_offset, oi->sizep, &type); if (!*oi->contentp) type = OBJ_BAD; @@ -1635,7 +1635,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, if (oi->typep) { enum object_type ptot; - ptot = packed_to_object_type(r, p, obj_offset, + ptot = packed_to_object_type(p->repo, p, obj_offset, type, &w_curs, curpos); if (oi->typep) *oi->typep = ptot; @@ -2170,7 +2170,7 @@ int packfile_store_read_object_info(struct packfile_store *store, if (!oi) return 0; - ret = packed_object_info(store->odb->repo, e.p, e.offset, oi); + ret = packed_object_info(e.p, e.offset, oi); if (ret < 0) { mark_bad_packed_object(e.p, oid); return -1; diff --git a/packfile.h b/packfile.h index d7cce582af..33fed26362 100644 --- a/packfile.h +++ b/packfile.h @@ -382,8 +382,7 @@ extern int do_check_packed_object_crc; * Look up the object info for a specific offset in the packfile. * Returns zero on success, a negative error code otherwise. */ -int packed_object_info(struct repository *r, - struct packed_git *pack, +int packed_object_info(struct packed_git *pack, off_t offset, struct object_info *); void mark_bad_packed_object(struct packed_git *, const struct object_id *);