From: Junio C Hamano Date: Sat, 17 Jan 2026 18:37:35 +0000 (-0800) Subject: Merge branch 'ps/odb-for-each-object' into seen X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6dee117b495ba1ba118182c833cf6de65639fde2;p=thirdparty%2Fgit.git Merge branch 'ps/odb-for-each-object' into seen Revamp object enumeration API around odb. Comments? * ps/odb-for-each-object: odb: drop unused `for_each_{loose,packed}_object()` functions reachable: convert to use `odb_for_each_object()` builtin/pack-objects: use `packfile_store_for_each_object()` odb: introduce mtime fields for object info requests treewide: drop uses of `for_each_{loose,packed}_object()` treewide: enumerate promisor objects via `odb_for_each_object()` builtin/fsck: refactor to use `odb_for_each_object()` odb: introduce `odb_for_each_object()` packfile: introduce function to iterate through objects packfile: extract function to iterate through objects of a store object-file: introduce function to iterate through objects object-file: extract function to read object info from path odb: fix flags parameter to be unsigned odb: rename `FOR_EACH_OBJECT_*` flags --- 6dee117b495ba1ba118182c833cf6de65639fde2 diff --cc builtin/cat-file.c index df8e87a81f,7d16fbc1b8..fbed136fbf --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@@ -845,14 -848,19 +848,21 @@@ static void batch_each_object(struct ba .callback = callback, .payload = _payload, }; - struct bitmap_index *bitmap = prepare_bitmap_git(the_repository); + struct bitmap_index *bitmap = NULL; + struct odb_source *source; - for_each_loose_object(the_repository->objects, batch_one_object_loose, &payload, 0); + odb_prepare_alternates(the_repository->objects); + for (source = the_repository->objects->sources; source; source = source->next) { + int ret = odb_source_loose_for_each_object(source, NULL, batch_one_object_oi, + &payload, flags); + if (ret) + break; + } - if (bitmap && !for_each_bitmapped_object(bitmap, &opt->objects_filter, - batch_one_object_bitmapped, &payload)) { + if (opt->objects_filter.choice != LOFC_DISABLED && + (bitmap = prepare_bitmap_git(the_repository)) && + !for_each_bitmapped_object(bitmap, &opt->objects_filter, + batch_one_object_bitmapped, &payload)) { struct packed_git *pack; repo_for_each_pack(the_repository, pack) { diff --cc builtin/fsck.c index 0512f78a87,96107695ae..5fc305727f --- a/builtin/fsck.c +++ b/builtin/fsck.c @@@ -1056,22 -969,9 +1025,20 @@@ int cmd_fsck(int argc if (check_references) fsck_refs(the_repository); + /* + * Take a snapshot of the refs before walking objects to avoid looking + * at a set of refs that may be changed by the user while we are walking + * objects. We can still walk over new objects that are added during the + * execution of fsck but won't miss any objects that were reachable. + */ + snapshot_refs(&snap, argc, argv); + + /* Ensure we get a "fresh" view of the odb */ + odb_reprepare(the_repository->objects); + if (connectivity_only) { - for_each_loose_object(the_repository->objects, - mark_loose_for_connectivity, NULL, 0); - for_each_packed_object(the_repository, - mark_packed_for_connectivity, NULL, 0); + odb_for_each_object(the_repository->objects, NULL, + mark_object_for_connectivity, NULL, 0); } else { odb_prepare_alternates(the_repository->objects); for (source = the_repository->objects->sources; source; source = source->next) diff --cc repack-promisor.c index 73af57bce3,35c4073632..90318ce150 --- a/repack-promisor.c +++ b/repack-promisor.c @@@ -78,62 -100,3 +78,62 @@@ static void finish_repacking_promisor_o die(_("could not finish pack-objects to repack promisor objects")); strbuf_release(&line); } + +void repack_promisor_objects(struct repository *repo, + const struct pack_objects_args *args, + struct string_list *names, const char *packtmp) +{ + struct write_oid_context ctx; + struct child_process cmd = CHILD_PROCESS_INIT; + + prepare_pack_objects(&cmd, args, packtmp); + cmd.in = -1; + + /* + * NEEDSWORK: Giving pack-objects only the OIDs without any ordering + * hints may result in suboptimal deltas in the resulting pack. See if + * the OIDs can be sent with fake paths such that pack-objects can use a + * {type -> existing pack order} ordering when computing deltas instead + * of a {type -> size} ordering, which may produce better deltas. + */ + ctx.cmd = &cmd; + ctx.algop = repo->hash_algo; - for_each_packed_object(repo, write_oid, &ctx, - FOR_EACH_OBJECT_PROMISOR_ONLY); ++ odb_for_each_object(repo->objects, NULL, write_oid, &ctx, ++ ODB_FOR_EACH_OBJECT_PROMISOR_ONLY); + + if (cmd.in == -1) { + /* No packed objects; cmd was never started */ + child_process_clear(&cmd); + return; + } + + finish_repacking_promisor_objects(repo, &cmd, names, packtmp); +} + +void pack_geometry_repack_promisors(struct repository *repo, + const struct pack_objects_args *args, + const struct pack_geometry *geometry, + struct string_list *names, + const char *packtmp) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + FILE *in; + + if (!geometry->promisor_split) + return; + + prepare_pack_objects(&cmd, args, packtmp); + strvec_push(&cmd.args, "--stdin-packs"); + cmd.in = -1; + if (start_command(&cmd)) + die(_("could not start pack-objects to repack promisor packs")); + + in = xfdopen(cmd.in, "w"); + for (size_t i = 0; i < geometry->promisor_split; i++) + fprintf(in, "%s\n", pack_basename(geometry->promisor_pack[i])); + for (size_t i = geometry->promisor_split; i < geometry->promisor_pack_nr; i++) + fprintf(in, "^%s\n", pack_basename(geometry->promisor_pack[i])); + fclose(in); + + finish_repacking_promisor_objects(repo, &cmd, names, packtmp); +}