git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 04/13] odb: refactor `odb_for_each_alternate()` to yield dirs

From
Patrick Steinhardt <ps@pks.im>
Date
Oct 8, 2026, 08:35 UTC
Message-ID
<20261008-pks-odb-move-alternates-v2-4-b47e8189baa5@pks.im>
In-Reply-To
<20261008-pks-odb-move-alternates-v2-0-b47e8189baa5@pks.im>

The function `odb_for_each_alternate()` iterates through all alternates of an object database. This is becoming an implementation detail of the "files" backend though, where each alternate will be represented by one `struct odb_files_dir`.

Adapt `odb_for_each_alternate()` to already iterate through these structs instead of iterating through sources.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 builtin/count-objects.c     |  4 ++--
 builtin/submodule--helper.c |  7 ++++---
 diagnose.c                  |  8 ++++----
 odb.c                       | 18 +++++++++++-------
 odb.h                       |  3 ++-
 5 files changed, 23 insertions(+), 17 deletions(-)
diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index 18f6e33b6f..f2abfaccec 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -81,10 +81,10 @@ static int count_cruft(const char *basename UNUSED, const char *path,
 	return 0;
 }
 
-static int print_alternate(struct odb_source *alternate, void *data UNUSED)
+static int print_alternate(struct odb_files_dir *alternate, void *data UNUSED)
 {
 	printf("alternate: ");
-	quote_c_style(alternate->path, NULL, stdout, 0);
+	quote_c_style(alternate->abspath, NULL, stdout, 0);
 	putchar('\n');
 	return 0;
 }
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 40a052d674..64412adf9f 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -30,6 +30,7 @@
 #include "object-name.h"
 #include "odb.h"
 #include "odb/source.h"
+#include "odb/source-files.h"
 #include "advice.h"
 #include "branch.h"
 #include "list-objects-filter-options.h"
@@ -1770,7 +1771,7 @@ static const char alternate_error_advice[] = N_(
 );
 
 static int add_possible_reference_from_superproject(
-		struct odb_source *alt_odb, void *sas_cb)
+		struct odb_files_dir *alt_odb, void *sas_cb)
 {
 	struct submodule_alternate_setup *sas = sas_cb;
 	size_t len;
@@ -1779,12 +1780,12 @@ static int add_possible_reference_from_superproject(
 	 * If the alternate object store is another repository, try the
 	 * standard layout with .git/(modules/<name>)+/objects
 	 */
-	if (strip_suffix(alt_odb->path, "/objects", &len)) {
+	if (strip_suffix(alt_odb->abspath, "/objects", &len)) {
 		struct repository alternate;
 		char *sm_alternate;
 		struct strbuf sb = STRBUF_INIT;
 		struct strbuf err = STRBUF_INIT;
-		strbuf_add(&sb, alt_odb->path, len);
+		strbuf_add(&sb, alt_odb->abspath, len);
 
 		if (repo_init(&alternate, sb.buf, NULL) < 0)
 			die(_("could not get a repository handle for gitdir '%s'"),
diff --git a/diagnose.c b/diagnose.c
index 5092bf80d3..89240e47d6 100644
--- a/diagnose.c
+++ b/diagnose.c
@@ -59,13 +59,13 @@ static void dir_file_stats_objects(const char *full_path,
 			    (uintmax_t)st.st_size);
 }
 
-static int dir_file_stats(struct odb_source *source, void *data)
+static int dir_file_stats(struct odb_files_dir *source, void *data)
 {
 	struct strbuf *buf = data;
 
-	strbuf_addf(buf, "Contents of %s:\n", source->path);
+	strbuf_addf(buf, "Contents of %s:\n", source->abspath);
 
-	for_each_file_in_pack_dir(source->path, dir_file_stats_objects,
+	for_each_file_in_pack_dir(source->abspath, dir_file_stats_objects,
 				  data);
 
 	return 0;
@@ -228,7 +228,7 @@ int create_diagnostics_archive(struct repository *r,
 
 	strbuf_reset(&buf);
 	strbuf_addstr(&buf, "--add-virtual-file=packs-local.txt:");
-	dir_file_stats(r->objects->sources, &buf);
+	dir_file_stats(odb_source_files_downcast(r->objects->sources)->dirs, &buf);
 	odb_for_each_alternate(r->objects, dir_file_stats, &buf);
 	strvec_push(&archiver_args, buf.buf);
 
diff --git a/odb.c b/odb.c
index 0200e26f21..9b70859c23 100644
--- a/odb.c
+++ b/odb.c
@@ -14,6 +14,7 @@
 #include "object-name.h"
 #include "odb.h"
 #include "odb/source-inmemory.h"
+#include "odb/source-files.h"
 #include "path.h"
 #include "promisor-remote.h"
 #include "quote.h"
@@ -435,18 +436,19 @@ static void read_alternate_refs(struct repository *repo,
 }
 
 struct alternate_refs_data {
+	struct repository *repo;
 	odb_for_each_alternate_ref_fn *fn;
 	void *payload;
 };
 
-static int refs_from_alternate_cb(struct odb_source *alternate,
+static int refs_from_alternate_cb(struct odb_files_dir *alternate,
 				  void *payload)
 {
 	struct strbuf path = STRBUF_INIT;
 	size_t base_len;
 	struct alternate_refs_data *cb = payload;
 
-	if (!strbuf_realpath(&path, alternate->path, 0))
+	if (!strbuf_realpath(&path, alternate->abspath, 0))
 		goto out;
 	if (!strbuf_strip_suffix(&path, "/objects"))
 		goto out;
@@ -458,7 +460,7 @@ static int refs_from_alternate_cb(struct odb_source *alternate,
 		goto out;
 	strbuf_setlen(&path, base_len);
 
-	read_alternate_refs(alternate->odb->repo, path.buf, cb->fn, cb->payload);
+	read_alternate_refs(cb->repo, path.buf, cb->fn, cb->payload);
 
 out:
 	strbuf_release(&path);
@@ -468,9 +470,11 @@ static int refs_from_alternate_cb(struct odb_source *alternate,
 void odb_for_each_alternate_ref(struct object_database *odb,
 				odb_for_each_alternate_ref_fn cb, void *payload)
 {
-	struct alternate_refs_data data;
-	data.fn = cb;
-	data.payload = payload;
+	struct alternate_refs_data data = {
+		.fn = cb,
+		.payload = payload,
+		.repo = odb->repo,
+	};
 	odb_for_each_alternate(odb, refs_from_alternate_cb, &data);
 }
 
@@ -481,7 +485,7 @@ int odb_for_each_alternate(struct object_database *odb,
 	int r = 0;
 
 	for (alternate = odb->sources->next; alternate; alternate = alternate->next) {
-		r = cb(alternate, payload);
+		r = cb(odb_source_files_downcast(alternate)->dirs, payload);
 		if (r)
 			break;
 	}
diff --git a/odb.h b/odb.h
index 797eecbb94..3715351bb3 100644
--- a/odb.h
+++ b/odb.h
@@ -12,6 +12,7 @@
 struct cached_object_entry;
 struct list_objects_filter_options;
 struct odb_source_inmemory;
+struct odb_files_dir;
 struct packed_git;
 struct repository;
 struct strbuf;
@@ -257,7 +258,7 @@ void odb_restore_primary_source(struct object_database *odb,
  * function returns a non-zero value, in which case the value is bubbled up
  * from the callback.
  */
-typedef int odb_for_each_alternate_fn(struct odb_source *, void *);
+typedef int odb_for_each_alternate_fn(struct odb_files_dir *, void *);
 int odb_for_each_alternate(struct object_database *odb,
 			   odb_for_each_alternate_fn cb, void *payload);
 
-- 
2.56.0.406.ga2d225a756.dirty
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 31 of 41 in “odb/source-files: move alternates into the backend”
  1. 00/13 odb/source-files: move alternates into the backendPatrick Steinhardt, Oct 2, 2026
  2. 01/13 commit-graph: require resolved packfile paths for `stdin_packs`Patrick Steinhardt, Oct 2, 2026
  3. Karthik NayakOct 5, 2026
  4. Patrick SteinhardtOct 6, 2026
  5. 02/13 commit-graph: stop depending on `struct odb_source`Patrick Steinhardt, Oct 2, 2026
  6. Karthik NayakOct 5, 2026
  7. Patrick SteinhardtOct 6, 2026
  8. Karthik NayakOct 6, 2026
  9. 03/13 odb/source-files: introduce `struct odb_files_dir`Patrick Steinhardt, Oct 2, 2026
  10. 04/13 odb: refactor `odb_for_each_alternate()` to yield dirsPatrick Steinhardt, Oct 2, 2026
  11. Karthik NayakOct 6, 2026
  12. 05/13 odb: refactor `odb_find_source()` to yield dirsPatrick Steinhardt, Oct 2, 2026
  13. 06/13 odb/source-files: add the ability to have multiple object dirsPatrick Steinhardt, Oct 2, 2026
  14. 07/13 tmp-objdir: absorb logic to set and restore primary sourcesPatrick Steinhardt, Oct 2, 2026
  15. 08/13 tmp-objdir: manage quarantine as an object directoryPatrick Steinhardt, Oct 2, 2026
  16. Karthik NayakOct 6, 2026
  17. Karthik NayakOct 6, 2026
  18. 09/13 tmp-objdir: replace primary source at creation timePatrick Steinhardt, Oct 2, 2026
  19. 10/13 odb/source: make `will_destroy` an implementation detailPatrick Steinhardt, Oct 2, 2026
  20. 11/13 odb/source-files: extract reading alternatesPatrick Steinhardt, Oct 2, 2026
  21. 12/13 odb/source-files: move alternates into the backendPatrick Steinhardt, Oct 2, 2026
  22. Karthik NayakOct 6, 2026
  23. Patrick SteinhardtOct 7, 2026
  24. 13/13 odb/source: drop `read_alternates` callbackPatrick Steinhardt, Oct 2, 2026
  25. Karthik NayakOct 6, 2026
  26. Patrick SteinhardtOct 7, 2026
  27. 00/13 odb/source-files: move alternates into the backendPatrick Steinhardt, Oct 8, 2026
  28. 01/13 commit-graph: require resolved packfile paths for `stdin_packs`Patrick Steinhardt, Oct 8, 2026
  29. 02/13 commit-graph: stop depending on `struct odb_source`Patrick Steinhardt, Oct 8, 2026
  30. 03/13 odb/source-files: introduce `struct odb_files_dir`Patrick Steinhardt, Oct 8, 2026
  31. 04/13 odb: refactor `odb_for_each_alternate()` to yield dirsPatrick Steinhardt, Oct 8, 2026
  32. 05/13 odb: refactor `odb_find_source()` to yield dirsPatrick Steinhardt, Oct 8, 2026
  33. 06/13 odb/source-files: add the ability to have multiple object dirsPatrick Steinhardt, Oct 8, 2026
  34. 07/13 tmp-objdir: absorb logic to set and restore primary sourcesPatrick Steinhardt, Oct 8, 2026
  35. 08/13 tmp-objdir: manage quarantine as an object directoryPatrick Steinhardt, Oct 8, 2026
  36. 09/13 tmp-objdir: replace primary source at creation timePatrick Steinhardt, Oct 8, 2026
  37. 10/13 odb/source: make `will_destroy` an implementation detailPatrick Steinhardt, Oct 8, 2026
  38. 11/13 odb/source-files: extract reading alternatesPatrick Steinhardt, Oct 8, 2026
  39. 12/13 odb/source-files: move alternates into the backendPatrick Steinhardt, Oct 8, 2026
  40. 13/13 odb/source: drop `read_alternates` callbackPatrick Steinhardt, Oct 8, 2026
  41. Karthik NayakOct 8, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.