From 87842f68352040858f581b64509932fb91c64f0f Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 5 Mar 2026 15:19:45 +0100 Subject: [PATCH] odb/source: introduce source type for robustness When a caller holds a `struct odb_source`, they have no way of telling what type the source is. This doesn't really cause any problems in the current status quo as we only have a single type anyway, "files". But going forward we expect to add more types, and if so it will become necessary to tell the sources apart. Introduce a new enum to cover this use case and assert that the given source actually matches the target source when performing the downcast. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- odb/source-files.c | 2 +- odb/source-files.h | 5 ++++- odb/source.c | 2 ++ odb/source.h | 15 +++++++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/odb/source-files.c b/odb/source-files.c index df0ea9ee62..7496e1d9f8 100644 --- a/odb/source-files.c +++ b/odb/source-files.c @@ -36,7 +36,7 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb, struct odb_source_files *files; CALLOC_ARRAY(files, 1); - odb_source_init(&files->base, odb, path, local); + odb_source_init(&files->base, odb, ODB_SOURCE_FILES, path, local); files->loose = odb_source_loose_new(&files->base); files->packed = packfile_store_new(&files->base); diff --git a/odb/source-files.h b/odb/source-files.h index 859a8f518a..803fa995fb 100644 --- a/odb/source-files.h +++ b/odb/source-files.h @@ -25,10 +25,13 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb, void odb_source_files_free(struct odb_source_files *files); /* - * Cast the given object database source to the files backend. + * Cast the given object database source to the files backend. This will cause + * a BUG in case the source doesn't use this backend. */ static inline struct odb_source_files *odb_source_files_downcast(struct odb_source *source) { + if (source->type != ODB_SOURCE_FILES) + BUG("trying to downcast source of type '%d' to files", source->type); return container_of(source, struct odb_source_files, base); } diff --git a/odb/source.c b/odb/source.c index d8b2176a94..c7dcc528f6 100644 --- a/odb/source.c +++ b/odb/source.c @@ -13,10 +13,12 @@ struct odb_source *odb_source_new(struct object_database *odb, void odb_source_init(struct odb_source *source, struct object_database *odb, + enum odb_source_type type, const char *path, bool local) { source->odb = odb; + source->type = type; source->local = local; source->path = xstrdup(path); } diff --git a/odb/source.h b/odb/source.h index e6698b73a3..45b72b81a0 100644 --- a/odb/source.h +++ b/odb/source.h @@ -1,6 +1,17 @@ #ifndef ODB_SOURCE_H #define ODB_SOURCE_H +enum odb_source_type { + /* + * The "unknown" type, which should never be in use. This type mostly + * exists to catch cases where the type field remains zeroed out. + */ + ODB_SOURCE_UNKNOWN, + + /* The "files" backend that uses loose objects and packfiles. */ + ODB_SOURCE_FILES, +}; + /* * The source is the part of the object database that stores the actual * objects. It thus encapsulates the logic to read and write the specific @@ -19,6 +30,9 @@ struct odb_source { /* Object database that owns this object source. */ struct object_database *odb; + /* The type used by this source. */ + enum odb_source_type type; + /* * Figure out whether this is the local source of the owning * repository, which would typically be its ".git/objects" directory. @@ -58,6 +72,7 @@ struct odb_source *odb_source_new(struct object_database *odb, */ void odb_source_init(struct odb_source *source, struct object_database *odb, + enum odb_source_type type, const char *path, bool local);