aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2026-03-20 08:07:29 +0100
committerJunio C Hamano <gitster@pobox.com>2026-03-20 13:16:41 -0700
commitcfd575f0a9730712107e4ee6799a37665bcd8204 (patch)
treef52a43e428ac45cb952a3965f8855eb997a2d3df
parentfe446b01aeaab307adcbfb39d4aaa72c37afbcda (diff)
downloadgit-cfd575f0a9730712107e4ee6799a37665bcd8204.tar.xz
odb: introduce `struct odb_for_each_object_options`
The `odb_for_each_object()` function only accepts a bitset of flags. In a subsequent commit we'll want to change object iteration to also support iterating over only those objects that have a specific prefix. While we could of course add the prefix to the function signature, or alternatively introduce a new function, both of these options don't really seem to be that sensible. Instead, introduce a new `struct odb_for_each_object_options` that can be passed to a new `odb_for_each_object_ext()` function. Splice through the options structure into the respective object database sources. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/cat-file.c7
-rw-r--r--builtin/pack-objects.c12
-rw-r--r--commit-graph.c5
-rw-r--r--object-file.c9
-rw-r--r--object-file.h2
-rw-r--r--odb.c26
-rw-r--r--odb.h16
-rw-r--r--odb/source-files.c8
-rw-r--r--odb/source.h6
-rw-r--r--packfile.c12
-rw-r--r--packfile.h2
11 files changed, 71 insertions, 34 deletions
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index b6f12f41d6..cd13a3a89f 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -848,6 +848,9 @@ static void batch_each_object(struct batch_options *opt,
.callback = callback,
.payload = _payload,
};
+ struct odb_for_each_object_options opts = {
+ .flags = flags,
+ };
struct bitmap_index *bitmap = NULL;
struct odb_source *source;
@@ -860,7 +863,7 @@ static void batch_each_object(struct batch_options *opt,
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);
+ &payload, &opts);
if (ret)
break;
}
@@ -884,7 +887,7 @@ static void batch_each_object(struct batch_options *opt,
for (source = the_repository->objects->sources; source; source = source->next) {
struct odb_source_files *files = odb_source_files_downcast(source);
int ret = packfile_store_for_each_object(files->packed, &oi,
- batch_one_object_oi, &payload, flags);
+ batch_one_object_oi, &payload, &opts);
if (ret)
break;
}
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index cd013c0b68..3bb57ff183 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -4344,6 +4344,12 @@ static void add_objects_in_unpacked_packs(void)
{
struct odb_source *source;
time_t mtime;
+ struct odb_for_each_object_options opts = {
+ .flags = ODB_FOR_EACH_OBJECT_PACK_ORDER |
+ ODB_FOR_EACH_OBJECT_LOCAL_ONLY |
+ ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS |
+ ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS,
+ };
struct object_info oi = {
.mtimep = &mtime,
};
@@ -4356,11 +4362,7 @@ static void add_objects_in_unpacked_packs(void)
continue;
if (packfile_store_for_each_object(files->packed, &oi,
- add_object_in_unpacked_pack, NULL,
- ODB_FOR_EACH_OBJECT_PACK_ORDER |
- ODB_FOR_EACH_OBJECT_LOCAL_ONLY |
- ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS |
- ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS))
+ add_object_in_unpacked_pack, NULL, &opts))
die(_("cannot open pack index"));
}
}
diff --git a/commit-graph.c b/commit-graph.c
index c030003330..df4b4a125e 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -1969,6 +1969,9 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx)
{
struct odb_source *source;
enum object_type type;
+ struct odb_for_each_object_options opts = {
+ .flags = ODB_FOR_EACH_OBJECT_PACK_ORDER,
+ };
struct object_info oi = {
.typep = &type,
};
@@ -1983,7 +1986,7 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx)
for (source = ctx->r->objects->sources; source; source = source->next) {
struct odb_source_files *files = odb_source_files_downcast(source);
packfile_store_for_each_object(files->packed, &oi, add_packed_commits_oi,
- ctx, ODB_FOR_EACH_OBJECT_PACK_ORDER);
+ ctx, &opts);
}
if (ctx->progress_done < ctx->approx_nr_objects)
diff --git a/object-file.c b/object-file.c
index 9764c8dd06..56cbb27ab9 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1849,7 +1849,7 @@ int odb_source_loose_for_each_object(struct odb_source *source,
const struct object_info *request,
odb_for_each_object_cb cb,
void *cb_data,
- unsigned flags)
+ const struct odb_for_each_object_options *opts)
{
struct for_each_object_wrapper_data data = {
.source = source,
@@ -1859,9 +1859,9 @@ int odb_source_loose_for_each_object(struct odb_source *source,
};
/* There are no loose promisor objects, so we can return immediately. */
- if ((flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY))
+ if ((opts->flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY))
return 0;
- if ((flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !source->local)
+ if ((opts->flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !source->local)
return 0;
return for_each_loose_file_in_source(source, for_each_object_wrapper_cb,
@@ -1914,9 +1914,10 @@ int odb_source_loose_count_objects(struct odb_source *source,
*out = count * 256;
ret = 0;
} else {
+ struct odb_for_each_object_options opts = { 0 };
*out = 0;
ret = odb_source_loose_for_each_object(source, NULL, count_loose_object,
- out, NULL);
+ out, &opts);
}
out:
diff --git a/object-file.h b/object-file.h
index f8d8805a18..46dfa7b632 100644
--- a/object-file.h
+++ b/object-file.h
@@ -137,7 +137,7 @@ int odb_source_loose_for_each_object(struct odb_source *source,
const struct object_info *request,
odb_for_each_object_cb cb,
void *cb_data,
- unsigned flags);
+ const struct odb_for_each_object_options *opts);
/*
* Count the number of loose objects in this source.
diff --git a/odb.c b/odb.c
index 350e23f3c0..3019957b87 100644
--- a/odb.c
+++ b/odb.c
@@ -896,20 +896,20 @@ int odb_freshen_object(struct object_database *odb,
return 0;
}
-int odb_for_each_object(struct object_database *odb,
- const struct object_info *request,
- odb_for_each_object_cb cb,
- void *cb_data,
- unsigned flags)
+int odb_for_each_object_ext(struct object_database *odb,
+ const struct object_info *request,
+ odb_for_each_object_cb cb,
+ void *cb_data,
+ const struct odb_for_each_object_options *opts)
{
int ret;
odb_prepare_alternates(odb);
for (struct odb_source *source = odb->sources; source; source = source->next) {
- if (flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY && !source->local)
+ if (opts->flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY && !source->local)
continue;
- ret = odb_source_for_each_object(source, request, cb, cb_data, flags);
+ ret = odb_source_for_each_object(source, request, cb, cb_data, opts);
if (ret)
return ret;
}
@@ -917,6 +917,18 @@ int odb_for_each_object(struct object_database *odb,
return 0;
}
+int odb_for_each_object(struct object_database *odb,
+ const struct object_info *request,
+ odb_for_each_object_cb cb,
+ void *cb_data,
+ unsigned flags)
+{
+ struct odb_for_each_object_options opts = {
+ .flags = flags,
+ };
+ return odb_for_each_object_ext(odb, request, cb, cb_data, &opts);
+}
+
int odb_count_objects(struct object_database *odb,
enum odb_count_objects_flags flags,
unsigned long *out)
diff --git a/odb.h b/odb.h
index 9aee260105..a19a8bb50d 100644
--- a/odb.h
+++ b/odb.h
@@ -482,6 +482,15 @@ typedef int (*odb_for_each_object_cb)(const struct object_id *oid,
void *cb_data);
/*
+ * Options that can be passed to `odb_for_each_object()` and its
+ * backend-specific implementations.
+ */
+struct odb_for_each_object_options {
+ /* A bitfield of `odb_for_each_object_flags`. */
+ enum odb_for_each_object_flags flags;
+};
+
+/*
* Iterate through all objects contained in the object database. Note that
* objects may be iterated over multiple times in case they are either stored
* in different backends or in case they are stored in multiple sources.
@@ -495,6 +504,13 @@ typedef int (*odb_for_each_object_cb)(const struct object_id *oid,
* Returns 0 on success, a negative error code in case a failure occurred, or
* an arbitrary non-zero error code returned by the callback itself.
*/
+int odb_for_each_object_ext(struct object_database *odb,
+ const struct object_info *request,
+ odb_for_each_object_cb cb,
+ void *cb_data,
+ const struct odb_for_each_object_options *opts);
+
+/* Same as `odb_for_each_object_ext()` with `opts.flags` set to the given flags. */
int odb_for_each_object(struct object_database *odb,
const struct object_info *request,
odb_for_each_object_cb cb,
diff --git a/odb/source-files.c b/odb/source-files.c
index c08d8993e3..e90bb689bb 100644
--- a/odb/source-files.c
+++ b/odb/source-files.c
@@ -75,18 +75,18 @@ static int odb_source_files_for_each_object(struct odb_source *source,
const struct object_info *request,
odb_for_each_object_cb cb,
void *cb_data,
- unsigned flags)
+ const struct odb_for_each_object_options *opts)
{
struct odb_source_files *files = odb_source_files_downcast(source);
int ret;
- if (!(flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY)) {
- ret = odb_source_loose_for_each_object(source, request, cb, cb_data, flags);
+ if (!(opts->flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY)) {
+ ret = odb_source_loose_for_each_object(source, request, cb, cb_data, opts);
if (ret)
return ret;
}
- ret = packfile_store_for_each_object(files->packed, request, cb, cb_data, flags);
+ ret = packfile_store_for_each_object(files->packed, request, cb, cb_data, opts);
if (ret)
return ret;
diff --git a/odb/source.h b/odb/source.h
index 96c906e7a1..ee5d6ed530 100644
--- a/odb/source.h
+++ b/odb/source.h
@@ -140,7 +140,7 @@ struct odb_source {
const struct object_info *request,
odb_for_each_object_cb cb,
void *cb_data,
- unsigned flags);
+ const struct odb_for_each_object_options *opts);
/*
* This callback is expected to count objects in the given object
@@ -343,9 +343,9 @@ static inline int odb_source_for_each_object(struct odb_source *source,
const struct object_info *request,
odb_for_each_object_cb cb,
void *cb_data,
- unsigned flags)
+ const struct odb_for_each_object_options *opts)
{
- return source->for_each_object(source, request, cb, cb_data, flags);
+ return source->for_each_object(source, request, cb, cb_data, opts);
}
/*
diff --git a/packfile.c b/packfile.c
index d4de9f3ffe..a6f3d2035d 100644
--- a/packfile.c
+++ b/packfile.c
@@ -2375,7 +2375,7 @@ 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)
+ const struct odb_for_each_object_options *opts)
{
struct packfile_store_for_each_object_wrapper_data data = {
.store = store,
@@ -2391,15 +2391,15 @@ int packfile_store_for_each_object(struct packfile_store *store,
for (e = packfile_store_get_packs(store); e; e = e->next) {
struct packed_git *p = e->pack;
- if ((flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
+ if ((opts->flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
continue;
- if ((flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY) &&
+ if ((opts->flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY) &&
!p->pack_promisor)
continue;
- if ((flags & ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS) &&
+ if ((opts->flags & ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS) &&
p->pack_keep_in_core)
continue;
- if ((flags & ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS) &&
+ if ((opts->flags & ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS) &&
p->pack_keep)
continue;
if (open_pack_index(p)) {
@@ -2408,7 +2408,7 @@ int packfile_store_for_each_object(struct packfile_store *store,
}
ret = for_each_object_in_pack(p, packfile_store_for_each_object_wrapper,
- &data, flags);
+ &data, opts->flags);
if (ret)
goto out;
}
diff --git a/packfile.h b/packfile.h
index a16ec3950d..fa41dfda38 100644
--- a/packfile.h
+++ b/packfile.h
@@ -367,7 +367,7 @@ 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);
+ const struct odb_for_each_object_options *opts);
/* A hook to report invalid files in pack directory */
#define PACKDIR_FILE_PACK 1