]> git.ipfire.org Git - thirdparty/git.git/commitdiff
packfile: introduce function to iterate through objects
authorPatrick Steinhardt <ps@pks.im>
Mon, 26 Jan 2026 09:51:22 +0000 (10:51 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 26 Jan 2026 16:26:07 +0000 (08:26 -0800)
Introduce a new function `packfile_store_for_each_object()`. This
function is equivalent to `odb_source_loose_for_each_object()`, except
that it:

  - Works on a single packfile store instead of working on the object
    database level. Consequently, it will only yield packed objects of a
    single object database 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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
packfile.c
packfile.h

index d15a2ce12b1ce510fad1125c7a2495eb54b86b45..c35d5ea6552ec348bbb2fd51432c7adc754d0dd7 100644 (file)
@@ -2360,6 +2360,57 @@ 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;
+       const struct object_info *request;
+       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->request) {
+               off_t offset = nth_packed_object_offset(pack, index_pos);
+               struct object_info oi = *data->request;
+
+               if (packed_object_info(pack, offset, &oi) < 0) {
+                       mark_bad_packed_object(pack, oid);
+                       return -1;
+               }
+
+               return data->cb(oid, &oi, data->cb_data);
+       } else {
+               return data->cb(oid, NULL, data->cb_data);
+       }
+}
+
+int packfile_store_for_each_object(struct packfile_store *store,
+                                  const struct object_info *request,
+                                  odb_for_each_object_cb cb,
+                                  void *cb_data,
+                                  unsigned flags)
+{
+       struct packfile_store_for_each_object_wrapper_data data = {
+               .store = store,
+               .request = request,
+               .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,
index 447c44c4a7517dd03c64c3a1b4e547cd617eb010..b7964f0289705cbf7c1837355a3d59c6cc379555 100644 (file)
@@ -343,6 +343,21 @@ 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 an object info request is given,
+ * then the object info will be read for every individual object and passed to
+ * the callback as if `packfile_store_read_object_info()` was called for the
+ * object.
+ *
+ * The flags parameter is a combination of `odb_for_each_object_flags`.
+ */
+int packfile_store_for_each_object(struct packfile_store *store,
+                                  const struct object_info *request,
+                                  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