From 643681cf89aa5fb2e6a6f6078bb143a07ad7a129 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 15 Dec 2025 08:39:48 +0100 Subject: [PATCH 1/9] Improvements for reading object info Hi, this patch series contains various small improvements for reading object info for either loose or packed objects. These improvements were split out of a larger patch series where I'm about to introduce a new generic `odb_for_each_object()` function. This series has a conflict with ps/packfile-store-in-odb-source. I decided to not make this a dependency though because those two topics are independent from one another, and I expect that this series here will be merged down faster than the conflicting one. Furthermore, the conflict itself is quite minor: diff --cc packfile.c index 8daa5a5ee7,ce6716fbea..0000000000 --- a/packfile.c +++ b/packfile.c @@@ -2157,10 -2132,11 +2151,10 @@@ int packfile_store_read_object_info(str struct object_info *oi, unsigned flags UNUSED) { - static struct object_info blank_oi = OBJECT_INFO_INIT; struct pack_entry e; - int rtype; + int ret; - if (!find_pack_entry(store->odb->repo, oid, &e)) + if (!find_pack_entry(store, oid, &e)) return 1; /* @@@ -2549,9 -2555,8 +2571,9 @@@ int packfile_store_read_object_stream(s 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) + repo_settings_get_big_file_threshold(store->source->odb->repo) >= size) return -1; in_pack_type = unpack_object_header(oi.u.packed.pack, I'd thus propose to merge this series via an evil merge, but if this proves to be burdensome I'm happy to defer it to a later point. Just let me know and I'll adapt accordingly, thanks! Patrick To: git@vger.kernel.org --- b4-submit-tracking --- # This section is used internally by b4 prep for tracking purposes. { "series": { "revision": 1, "change-id": "20251215-b4-pks-odb-read-object-info-improvements-0e031ef827d2", "prefixes": [] } } -- GitLab From bb025556bad63a788d88d9dbe688b032d19edea8 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 10 Dec 2025 15:51:15 +0100 Subject: [PATCH 2/9] 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. Nobody seems to care about this right now, but it's a bug waiting to happen. Fix this by always setting `whence` on success. Signed-off-by: Patrick Steinhardt --- object-file.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/object-file.c b/object-file.c index af1c3f972d..716b325669 100644 --- a/object-file.c +++ b/object-file.c @@ -439,12 +439,21 @@ int odb_source_loose_read_object_info(struct odb_source *source, */ if (!oi->typep && !oi->sizep && !oi->contentp) { struct stat st; - if (!oi->disk_sizep && (flags & OBJECT_INFO_QUICK)) - return quick_has_loose(source->loose, oid) ? 0 : -1; + + if (!oi->disk_sizep && (flags & OBJECT_INFO_QUICK)) { + status = quick_has_loose(source->loose, oid) ? 0 : -1; + if (!status) + oi->whence = OI_LOOSE; + return status; + } + if (stat_loose_object(source->loose, oid, &st, &path) < 0) return -1; + if (oi->disk_sizep) *oi->disk_sizep = st.st_size; + + oi->whence = OI_LOOSE; return 0; } -- GitLab From 0aaab4d3c229aea6cddbbb20ec441465c91b1946 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 15 Dec 2025 08:04:51 +0100 Subject: [PATCH 3/9] 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. Drop the OI_DBCACHED enum completely. There don't seem to be any callers that care about the distinction. Signed-off-by: Patrick Steinhardt --- 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 c88bd92619..79ad9d7179 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); -- GitLab From 70db36e38f38677c7aa28aea6ff589977eeb6d86 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 11 Dec 2025 08:08:03 +0100 Subject: [PATCH 4/9] 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 the next commit. Signed-off-by: Patrick Steinhardt --- 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 79ad9d7179..9bce52f912 100644 --- a/packfile.c +++ b/packfile.c @@ -2160,8 +2160,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; @@ -2532,7 +2542,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; -- GitLab From bde9dc9e5e0d01c4d34123b781ea494ca52c8fb1 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 15 Dec 2025 08:11:13 +0100 Subject: [PATCH 5/9] packfile: always populate pack-specific info when reading object info When reading object information from a packfile we are not always populating the pack-specific information. This happens in two cases: - When calling `packed_object_info()` directly instead of `packfile_store_read_object_info()`. - When we've got the empty request. Fix both of these issues so that we can always assume the pack info to be populated when reading object info from a pack. Note that we don't really care about the second case right now, as the condition will always evaluate to false anyway. This will be fixed in the next commit. Signed-off-by: Patrick Steinhardt --- packfile.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/packfile.c b/packfile.c index 9bce52f912..6e66c90c46 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); @@ -2148,8 +2162,13 @@ int packfile_store_read_object_info(struct packfile_store *store, * We know that the caller doesn't actually need the * information below, so return early. */ - if (oi == &blank_oi) + if (oi == &blank_oi) { + oi->whence = OI_PACKED; + oi->u.packed.offset = e.offset; + oi->u.packed.pack = e.p; + oi->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN; return 0; + } rtype = packed_object_info(store->odb->repo, e.p, e.offset, oi); if (rtype < 0) { @@ -2157,23 +2176,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; } -- GitLab From b2f57b45f00ae952657e53364a4bee892733ca4b Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 15 Dec 2025 08:14:48 +0100 Subject: [PATCH 6/9] 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 --- packfile.c | 21 ++++++++++++--------- packfile.h | 4 ++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packfile.c b/packfile.c index 6e66c90c46..c141b8a7b1 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, @@ -2153,7 +2156,7 @@ int packfile_store_read_object_info(struct packfile_store *store, { static struct object_info blank_oi = OBJECT_INFO_INIT; struct pack_entry e; - int rtype; + int ret; if (!find_pack_entry(store->odb->repo, oid, &e)) return 1; @@ -2170,8 +2173,8 @@ int packfile_store_read_object_info(struct packfile_store *store, 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..07f5bfbc4f 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. + * success, a negative error code otherwise. + */ int packed_object_info(struct repository *r, struct packed_git *pack, off_t offset, struct object_info *); -- GitLab From 6dc2b4e783e0658e259cc86ef32806aa77f2ea6b Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 15 Dec 2025 07:41:06 +0100 Subject: [PATCH 7/9] 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 --- packfile.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packfile.c b/packfile.c index c141b8a7b1..d2ae2432eb 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; -- GitLab From db7cec38715d62c53f2714c401a4d851a93dac03 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 11 Dec 2025 08:17:45 +0100 Subject: [PATCH 8/9] packfile: fix short-circuiting of empty requests When reading object information from the packfile store we have logic that tries to bail out early on empty requests. This is supposed to be a performance optimization so that we don't even have to unpack the object header stored in the packfile. This optimization doesn't work though: we compare the passed-in object info pointer with the pointer of an on-stack variable, which of course cannot ever become true. This issue was introduced via d9f517d051 (object-file: split out functions relating to object store subsystem, 2025-04-15): before this commit, we checked whether the passed-in object info was a `NULL` pointer, and if so, we set it to point to `blank_oi` instead. The commit then split up these the logic so that we continue to set up `blank_oi` in `do_oid_object_info_extended()`, but then do the check in `packfile_store_read_object_info()`. But even before that commit the logic was only partially working, as it could very well be that callers pass a blank object info themselves. Fix this bug by introducing a new `object_info_is_blank_request()` helper, which simply verifies that none of the contained request pointers are populated. Signed-off-by: Patrick Steinhardt --- odb.h | 10 ++++++++++ packfile.c | 3 +-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/odb.h b/odb.h index afae5e5c01..b869c054c1 100644 --- a/odb.h +++ b/odb.h @@ -353,6 +353,16 @@ struct object_info { } u; }; +/* + * Given an object info structure, figure out whether any of its request + * pointers are populated. + */ +static inline bool object_info_is_blank_request(struct object_info *oi) +{ + return !oi->typep && !oi->sizep && !oi->disk_sizep && + !oi->delta_base_oid && !oi->contentp; +} + /* * Initializer for a "struct object_info" that wants no items. You may * also memset() the memory to all-zeroes. diff --git a/packfile.c b/packfile.c index d2ae2432eb..ce83e77899 100644 --- a/packfile.c +++ b/packfile.c @@ -2157,7 +2157,6 @@ int packfile_store_read_object_info(struct packfile_store *store, struct object_info *oi, unsigned flags UNUSED) { - static struct object_info blank_oi = OBJECT_INFO_INIT; struct pack_entry e; int ret; @@ -2168,7 +2167,7 @@ int packfile_store_read_object_info(struct packfile_store *store, * We know that the caller doesn't actually need the * information below, so return early. */ - if (oi == &blank_oi) { + if (object_info_is_blank_request(oi)) { oi->whence = OI_PACKED; oi->u.packed.offset = e.offset; oi->u.packed.pack = e.p; -- GitLab From 6990bdb3d49fb9a93b5a0a63293a50cdbeef753b Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 15 Dec 2025 08:16:54 +0100 Subject: [PATCH 9/9] 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 --- 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 ce83e77899..8daa5a5ee7 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; @@ -2175,7 +2175,7 @@ int packfile_store_read_object_info(struct packfile_store *store, 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 07f5bfbc4f..573d06f6ba 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. * 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 *); -- GitLab