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 <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Mar 5, 2026 at 15:19 UTC 87842f68352040858f581b64509932fb91c64f0f
4 files changed +22 -2
odb/source-files.c
+1 -1
@@ -36,7 +36,7 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb,
36 struct odb_source_files *files;
37
38 CALLOC_ARRAY(files, 1);
39 - odb_source_init(&files->base, odb, path, local);
39 + odb_source_init(&files->base, odb, ODB_SOURCE_FILES, path, local);
40 files->loose = odb_source_loose_new(&files->base);
41 files->packed = packfile_store_new(&files->base);
42
odb/source-files.h
+4 -1
@@ -25,10 +25,13 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb,
25 void odb_source_files_free(struct odb_source_files *files);
26
27 /*
28 - * Cast the given object database source to the files backend.
28 + * Cast the given object database source to the files backend. This will cause
29 + * a BUG in case the source doesn't use this backend.
30 */
31 static inline struct odb_source_files *odb_source_files_downcast(struct odb_source *source)
32 {
33 + if (source->type != ODB_SOURCE_FILES)
34 + BUG("trying to downcast source of type '%d' to files", source->type);
35 return container_of(source, struct odb_source_files, base);
36 }
37
odb/source.c
+2
@@ -13,10 +13,12 @@ struct odb_source *odb_source_new(struct object_database *odb,
13
14 void odb_source_init(struct odb_source *source,
15 struct object_database *odb,
16 + enum odb_source_type type,
17 const char *path,
18 bool local)
19 {
20 source->odb = odb;
21 + source->type = type;
22 source->local = local;
23 source->path = xstrdup(path);
24 }
odb/source.h
+15
@@ -1,6 +1,17 @@
1 #ifndef ODB_SOURCE_H
2 #define ODB_SOURCE_H
3
4 +enum odb_source_type {
5 + /*
6 + * The "unknown" type, which should never be in use. This type mostly
7 + * exists to catch cases where the type field remains zeroed out.
8 + */
9 + ODB_SOURCE_UNKNOWN,
10 +
11 + /* The "files" backend that uses loose objects and packfiles. */
12 + ODB_SOURCE_FILES,
13 +};
14 +
15 /*
16 * The source is the part of the object database that stores the actual
17 * objects. It thus encapsulates the logic to read and write the specific
@@ -19,6 +30,9 @@ struct odb_source {
30 /* Object database that owns this object source. */
31 struct object_database *odb;
32
33 + /* The type used by this source. */
34 + enum odb_source_type type;
35 +
36 /*
37 * Figure out whether this is the local source of the owning
38 * repository, which would typically be its ".git/objects" directory.
@@ -58,6 +72,7 @@ struct odb_source *odb_source_new(struct object_database *odb,
72 */
73 void odb_source_init(struct odb_source *source,
74 struct object_database *odb,
75 + enum odb_source_type type,
76 const char *path,
77 bool local);
78