packfile: extract function to iterate through objects of a store

In the next commit we're about to introduce a new function that knows to iterate through objects of a given packfile store. Same as with the equivalent function for loose objects, this new function will also be agnostic of backends by using a `struct object_info`. Prepare for this by extracting a new shared function to iterate through a single packfile store. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jan 26, 2026 at 10:51 UTC 37353119046414b2dccb26b32cb5224e0c9258e1
1 file changed +45 -33
packfile.c
+45 -33
@@ -2301,51 +2301,63 @@ int for_each_object_in_pack(struct packed_git *p,
2301 return r;
2302 }
2303
2304 -int for_each_packed_object(struct repository *repo, each_packed_object_fn cb,
2305 - void *data, unsigned flags)
2304 +static int packfile_store_for_each_object_internal(struct packfile_store *store,
2305 + each_packed_object_fn cb,
2306 + void *data,
2307 + unsigned flags,
2308 + int *pack_errors)
2309 {
2307 - struct odb_source *source;
2308 - int r = 0;
2309 - int pack_errors = 0;
2310 + struct packfile_list_entry *e;
2311 + int ret = 0;
2312
2311 - odb_prepare_alternates(repo->objects);
2313 + store->skip_mru_updates = true;
2314
2313 - for (source = repo->objects->sources; source; source = source->next) {
2314 - struct packfile_list_entry *e;
2315 + for (e = packfile_store_get_packs(store); e; e = e->next) {
2316 + struct packed_git *p = e->pack;
2317
2316 - source->packfiles->skip_mru_updates = true;
2318 + if ((flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
2319 + continue;
2320 + if ((flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY) &&
2321 + !p->pack_promisor)
2322 + continue;
2323 + if ((flags & ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS) &&
2324 + p->pack_keep_in_core)
2325 + continue;
2326 + if ((flags & ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS) &&
2327 + p->pack_keep)
2328 + continue;
2329 + if (open_pack_index(p)) {
2330 + *pack_errors = 1;
2331 + continue;
2332 + }
2333
2318 - for (e = packfile_store_get_packs(source->packfiles); e; e = e->next) {
2319 - struct packed_git *p = e->pack;
2334 + ret = for_each_object_in_pack(p, cb, data, flags);
2335 + if (ret)
2336 + break;
2337 + }
2338
2321 - if ((flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
2322 - continue;
2323 - if ((flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY) &&
2324 - !p->pack_promisor)
2325 - continue;
2326 - if ((flags & ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS) &&
2327 - p->pack_keep_in_core)
2328 - continue;
2329 - if ((flags & ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS) &&
2330 - p->pack_keep)
2331 - continue;
2332 - if (open_pack_index(p)) {
2333 - pack_errors = 1;
2334 - continue;
2335 - }
2339 + store->skip_mru_updates = false;
2340
2337 - r = for_each_object_in_pack(p, cb, data, flags);
2338 - if (r)
2339 - break;
2340 - }
2341 + return ret;
2342 +}
2343
2342 - source->packfiles->skip_mru_updates = false;
2344 +int for_each_packed_object(struct repository *repo, each_packed_object_fn cb,
2345 + void *data, unsigned flags)
2346 +{
2347 + struct odb_source *source;
2348 + int pack_errors = 0;
2349 + int ret = 0;
2350
2344 - if (r)
2351 + odb_prepare_alternates(repo->objects);
2352 +
2353 + for (source = repo->objects->sources; source; source = source->next) {
2354 + ret = packfile_store_for_each_object_internal(source->packfiles, cb, data,
2355 + flags, &pack_errors);
2356 + if (ret)
2357 break;
2358 }
2359
2348 - return r ? r : pack_errors;
2360 + return ret ? ret : pack_errors;
2361 }
2362
2363 static int add_promisor_object(const struct object_id *oid,