]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'ps/odb-for-each-object' into seen
authorJunio C Hamano <gitster@pobox.com>
Sat, 17 Jan 2026 18:37:35 +0000 (10:37 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sat, 17 Jan 2026 18:37:35 +0000 (10:37 -0800)
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

1  2 
builtin/cat-file.c
builtin/fsck.c
builtin/pack-objects.c
commit-graph.c
repack-promisor.c
revision.c

index df8e87a81f5eee47fa94f4211cc3ad1eee40c5e4,7d16fbc1b865565686a4104509f734c1e305b469..fbed136fbfd7c3782f0c4ce695b75b4448ff94a2
@@@ -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 0512f78a87fe1da9ceb8786da89d94a3e17df72e,96107695ae1ed111dcdb39abce7b8c52ed650ed1..5fc305727fd56c30845b705efeafd76937bb0730
@@@ -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)
Simple merge
diff --cc commit-graph.c
Simple merge
index 73af57bce313768c57461ec35cf1829adafc518d,35c4073632b1b49cec04f1a71ff77ca7605fcd0a..90318ce15093f55a80c1eda1f0698bb15a413baf
@@@ -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);
  }
-       for_each_packed_object(repo, write_oid, &ctx,
-                              FOR_EACH_OBJECT_PROMISOR_ONLY);
 +
 +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;
++      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);
 +}
diff --cc revision.c
Simple merge