From: Patrick Steinhardt Date: Thu, 08 Oct 2026 08:35:54 GMT Subject: [PATCH v2 04/13] odb: refactor `odb_for_each_alternate()` to yield dirs 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 --- 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/)+/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