[PATCH v2 3/6] odb: add `source` field to struct object_info_source
From: Patrick Steinhardt <hidden>
Date: 2026-07-02 12:02:13
Subsystem:
the rest · Maintainer:
Linus Torvalds
The previous commit introduced `struct object_info_source` as an opt-in container for backend-specific information, but for now we only moved preexisting data into this structure. Most importantly, the caller has no way yet to learn about which source an object was actually looked up from. Instead, callers have to rely on the `whence` enum to distinguish the object type, but cannot use that enum to tell the object source. Add a `struct odb_source *source` field to the structure and populate it from each backend's lookup path. The `whence` enum is still set and used by callers; it will be removed in a subsequent commit now that `sourcep->source` can identify the backend on its own. Signed-off-by: Patrick Steinhardt <redacted> --- builtin/cat-file.c | 8 ++++---- builtin/index-pack.c | 6 +++--- builtin/pack-objects.c | 14 +++++++------- odb.c | 4 ++-- odb.h | 11 +++++++---- odb/source-inmemory.c | 3 +++ odb/source-loose.c | 2 ++ packfile.c | 20 ++++++++++++-------- reachable.c | 8 ++++---- 9 files changed, 44 insertions(+), 32 deletions(-)
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index adc626ce30..0aca6acb75 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c@@ -835,8 +835,8 @@ static int batch_one_object_oi(const struct object_id *oid, { struct for_each_object_payload *payload = _payload; if (oi && oi->whence == OI_PACKED) - return payload->callback(oid, oi->sourcep->u.packed.pack, - oi->sourcep->u.packed.offset, + return payload->callback(oid, oi->source_infop->u.packed.pack, + oi->source_infop->u.packed.offset, payload->payload); return payload->callback(oid, NULL, 0, payload->payload); }
@@ -907,9 +907,9 @@ static void batch_each_object(struct batch_options *opt, &payload, flags); } } else { - struct object_info_source oi_source; + struct odb_source_info source_info; struct object_info oi = { - .sourcep = &oi_source, + .source_infop = &source_info, }; for (source = the_repository->objects->sources; source; source = source->next) {
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 77af26db8f..fe6e70522d 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c@@ -1825,15 +1825,15 @@ static void repack_local_links(void) oidset_iter_init(&outgoing_links, &iter); while ((oid = oidset_iter_next(&iter))) { - struct object_info_source info_source; + struct odb_source_info source_info; struct object_info info = { - .sourcep = &info_source, + .source_infop = &source_info, }; if (odb_read_object_info_extended(the_repository->objects, oid, &info, 0)) /* Missing; assume it is a promisor object */ continue; - if (info.whence == OI_PACKED && info_source.u.packed.pack->pack_promisor) + if (info.whence == OI_PACKED && source_info.u.packed.pack->pack_promisor) continue; if (!cmd.args.nr) {
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 9deb37e9e8..b7ef90f67c 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c@@ -4491,8 +4491,8 @@ static int add_object_in_unpacked_pack(const struct object_id *oid, void *data UNUSED) { if (cruft) { - add_cruft_object_entry(oid, OBJ_NONE, oi->sourcep->u.packed.pack, - oi->sourcep->u.packed.offset, NULL, + add_cruft_object_entry(oid, OBJ_NONE, oi->source_infop->u.packed.pack, + oi->source_infop->u.packed.offset, NULL, *oi->mtimep); } else { add_object_entry(oid, OBJ_NONE, "", 0);
@@ -4510,10 +4510,10 @@ static void add_objects_in_unpacked_packs(void) ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS | ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS, }; - struct object_info_source oi_source; + struct odb_source_info source_info; struct object_info oi = { .mtimep = &mtime, - .sourcep = &oi_source, + .source_infop = &source_info, }; odb_prepare_alternates(to_pack.repo->objects);
@@ -5003,14 +5003,14 @@ static int option_parse_cruft_expiration(const struct option *opt UNUSED, static int is_not_in_promisor_pack_obj(struct object *obj, void *data UNUSED) { - struct object_info_source info_source; + struct odb_source_info source_info; struct object_info info = { - .sourcep = &info_source, + .source_infop = &source_info, }; if (odb_read_object_info_extended(the_repository->objects, &obj->oid, &info, 0)) BUG("should_include_obj should only be called on existing objects"); - return info.whence != OI_PACKED || !info_source.u.packed.pack->pack_promisor; + return info.whence != OI_PACKED || !source_info.u.packed.pack->pack_promisor; } static int is_not_in_promisor_pack(struct commit *commit, void *data) {
diff --git a/odb.c b/odb.c
index 99f4e7551c..34c35c47a5 100644
--- a/odb.c
+++ b/odb.c@@ -692,8 +692,8 @@ static int oid_object_info_convert(struct repository *r, } } input_oi->whence = new_oi.whence; - if (input_oi->sourcep) - *input_oi->sourcep = *new_oi.sourcep; + if (input_oi->source_infop) + *input_oi->source_infop = *new_oi.source_infop; return ret; }
diff --git a/odb.h b/odb.h
index 770900289a..659bf8afe1 100644
--- a/odb.h
+++ b/odb.h@@ -249,10 +249,13 @@ int odb_pretend_object(struct object_database *odb, struct object_id *oid); /* - * Object information that can be used to uniquely identify an object and learn - * more about how exactly it is stored. + * Object database source information that can be used to uniquely identify an + * object and learn more about how exactly it is stored. */ -struct object_info_source { +struct odb_source_info { + /* The source that this object has been looked up from. */ + struct odb_source *source; + /* * Backend-specific information about the specific object. This can be * used for example to uniquely identify a given object in case it
@@ -307,7 +310,7 @@ struct object_info { * object lookups in case the same object exists in multiple sources, * or multiple times in the same source. */ - struct object_info_source *sourcep; + struct odb_source_info *source_infop; /* Response */ enum {
diff --git a/odb/source-inmemory.c b/odb/source-inmemory.c
index e004566d76..1d173bfa46 100644
--- a/odb/source-inmemory.c
+++ b/odb/source-inmemory.c@@ -52,6 +52,9 @@ static void populate_object_info(struct odb_source_inmemory *source, *oi->contentp = xmemdupz(object->buf, object->size); if (oi->mtimep) *oi->mtimep = 0; + if (oi->source_infop) + oi->source_infop->source = &source->base; + oi->whence = OI_CACHED; }
diff --git a/odb/source-loose.c b/odb/source-loose.c
index 66e6bb8d3f..c254957602 100644
--- a/odb/source-loose.c
+++ b/odb/source-loose.c@@ -196,6 +196,8 @@ static int read_object_info_from_path(struct odb_source_loose *loose, oi->typep = NULL; if (oi->delta_base_oid) oidclr(oi->delta_base_oid, loose->base.odb->repo->hash_algo); + if (oi->source_infop && !ret) + oi->source_infop->source = &loose->base; if (!ret) oi->whence = OI_LOOSE; }
diff --git a/packfile.c b/packfile.c
index 688c410b35..ce51d1e5a3 100644
--- a/packfile.c
+++ b/packfile.c@@ -1324,7 +1324,7 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset, hashmap_add(&delta_base_cache, &ent->ent); } -int packed_object_info_with_index_pos(struct odb_source_packed *source UNUSED, +int packed_object_info_with_index_pos(struct odb_source_packed *source, struct packed_git *p, off_t obj_offset, uint32_t *maybe_index_pos, struct object_info *oi) {
@@ -1423,22 +1423,26 @@ int packed_object_info_with_index_pos(struct odb_source_packed *source UNUSED, oi->whence = OI_PACKED; - if (oi->sourcep) { - oi->sourcep->u.packed.offset = obj_offset; - oi->sourcep->u.packed.pack = p; + if (oi->source_infop) { + if (!source) + BUG("cannot request source without an owning source"); + oi->source_infop->source = &source->base; + + oi->source_infop->u.packed.offset = obj_offset; + oi->source_infop->u.packed.pack = p; switch (type) { case OBJ_NONE: - oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN; + oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN; break; case OBJ_REF_DELTA: - oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA; + oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA; break; case OBJ_OFS_DELTA: - oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA; + oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA; break; default: - oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_FULL; + oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_FULL; break; } }
diff --git a/reachable.c b/reachable.c
index 2fc5b82d62..bf76b48fc5 100644
--- a/reachable.c
+++ b/reachable.c@@ -235,8 +235,8 @@ static int add_recent_object(const struct object_id *oid, add_pending_object(data->revs, obj, ""); if (data->cb) { if (oi->whence == OI_PACKED) - data->cb(obj, oi->sourcep->u.packed.pack, - oi->sourcep->u.packed.offset, *oi->mtimep); + data->cb(obj, oi->source_infop->u.packed.pack, + oi->source_infop->u.packed.offset, *oi->mtimep); else data->cb(obj, NULL, 0, *oi->mtimep); }
@@ -253,11 +253,11 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs, unsigned flags; enum object_type type; time_t mtime; - struct object_info_source oi_source; + struct odb_source_info source_info; struct object_info oi = { .mtimep = &mtime, .typep = &type, - .sourcep = &oi_source, + .source_infop = &source_info, }; int r;
--
2.55.0.795.g602f6c329a.dirty