Subject: [PATCH 1/2] odb: add odb_source_files_try() for heterogeneous source iteration

From: "Aaron Paterson via GitGitGadget" <[email-masked]>
Date: Mon, 16 Mar 2026 15:29:42 +0000

From: Aaron Paterson <[email-masked]>

The odb_source vtable introduced in this release allows multiple
backend implementations via the odb_source_type enum. However,
source-chain iteration sites that need files-specific internals
(pack store, loose cache, MIDX) currently use
odb_source_files_downcast(), which calls BUG() for non-files
source types. This makes it impossible to add a non-files source
to the chain without crashing.

Add odb_source_files_try() as a companion to the existing
downcast function. It returns NULL for non-files sources instead
of aborting. This follows the pattern used elsewhere in git where
a "try" or "maybe" variant provides a fallback path while the
strict version retains its safety guarantee.

The existing odb_source_files_downcast() is unchanged and
continues to BUG() on type mismatch, protecting call sites that
should only ever receive a files source.

A subsequent commit will convert the source-chain iteration sites
to use this new helper.

Signed-off-by: Aaron Paterson <[email-masked]>
---
 odb/source-files.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/odb/source-files.h b/odb/source-files.h
index 23a3b4e04b..abd093b23f 100644
--- a/odb/source-files.h
+++ b/odb/source-files.h
@@ -32,4 +32,18 @@ static inline struct odb_source_files *odb_source_files_downcast(struct odb_sour
 	return container_of(source, struct odb_source_files, base);
 }
 
+/*
+ * Try to cast the given source to the files backend. Returns NULL if
+ * the source uses a different backend. Use this in loops that iterate
+ * over heterogeneous source chains (e.g. when alternates may include
+ * non-files backends). Use odb_source_files_downcast() when the source
+ * is known to be a files backend.
+ */
+static inline struct odb_source_files *odb_source_files_try(struct odb_source *source)
+{
+	if (source->type != ODB_SOURCE_FILES)
+		return NULL;
+	return container_of(source, struct odb_source_files, base);
+}
+
 #endif
-- 
gitgitgadget