[PATCH 06/14] packfile: introduce function to iterate through objects
- From
Patrick Steinhardt <ps@pks.im>
- Date
- Jan 15, 2026, 11:04 UTC
- Message-ID
- <20260115-pks-odb-for-each-object-v1-6-5418a91d5d99@pks.im>
- In-Reply-To
- <20260115-pks-odb-for-each-object-v1-0-5418a91d5d99@pks.im>
Introduce a new function `packfile_store_for_each_object()`. This function is the equivalent to `odb_source_loose_for_each_object()` in that it:
- Works on a single packfile store and thus per object source.
- Passes a `struct object_info` to the callback function.
As such, it provides the same callback interface as we already provide for loose objects now. These functions will be used in a subsequent step to implement `odb_for_each_object()`.
The `for_each_packed_object()` function continues to exist for now, but it will be removed at the end of this patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> --- packfile.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ packfile.h | 14 ++++++++++++++ 2 files changed, 62 insertions(+)
diff --git a/packfile.c b/packfile.c index d15a2ce12b..cd45c6f21c 100644 --- a/packfile.c +++ b/packfile.c @@ -2360,6 +2360,54 @@ int for_each_packed_object(struct repository *repo, each_packed_object_fn cb, return ret ? ret : pack_errors; } +struct packfile_store_for_each_object_wrapper_data { + struct packfile_store *store; + struct object_info *oi; + odb_for_each_object_cb cb; + void *cb_data; +}; + +static int packfile_store_for_each_object_wrapper(const struct object_id *oid, + struct packed_git *pack, + uint32_t index_pos, + void *cb_data) +{ + struct packfile_store_for_each_object_wrapper_data *data = cb_data; + + if (data->oi) { + off_t offset = nth_packed_object_offset(pack, index_pos); + + if (packed_object_info(pack, offset, data->oi) < 0) { + mark_bad_packed_object(pack, oid); + return -1; + } + } + + return data->cb(oid, data->oi, data->cb_data); +} + +int packfile_store_for_each_object(struct packfile_store *store, + struct object_info *oi, + odb_for_each_object_cb cb, + void *cb_data, + unsigned flags) +{ + struct packfile_store_for_each_object_wrapper_data data = { + .store = store, + .oi = oi, + .cb = cb, + .cb_data = cb_data, + }; + int pack_errors = 0, ret; + + ret = packfile_store_for_each_object_internal(store, packfile_store_for_each_object_wrapper, + &data, flags, &pack_errors); + if (ret) + return ret; + + return pack_errors ? -1 : 0; +} + static int add_promisor_object(const struct object_id *oid, struct packed_git *pack, uint32_t pos UNUSED, diff --git a/packfile.h b/packfile.h index 447c44c4a7..ab0637fbe9 100644 --- a/packfile.h +++ b/packfile.h @@ -343,6 +343,20 @@ int for_each_object_in_pack(struct packed_git *p, int for_each_packed_object(struct repository *repo, each_packed_object_fn cb, void *data, unsigned flags); +/* + * Iterate through all packed objects in the given packfile store and invoke + * the callback function for each of them. If given, the object info will be + * populated with the object's data as if you had called + * `packfile_store_read_object_info()` on the object. + * + * The flags parameter is a combination of `odb_for_each_object_flags`. + */ +int packfile_store_for_each_object(struct packfile_store *store, + struct object_info *oi, + odb_for_each_object_cb cb, + void *cb_data, + unsigned flags); + /* A hook to report invalid files in pack directory */ #define PACKDIR_FILE_PACK 1 #define PACKDIR_FILE_IDX 2
-- 2.52.0.660.gd05f3a8ea5.dirty