From: Patrick Steinhardt Date: Thu, 15 Jan 2026 11:04:35 +0000 (+0100) Subject: packfile: introduce function to iterate through objects X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2aa629132b9dea035b1636557096611369bde5d;p=thirdparty%2Fgit.git packfile: introduce function to iterate through objects 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 Signed-off-by: Junio C Hamano --- 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