odb: refactor `odb_for_each_alternate()` to yield dirs

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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
next
Patrick Steinhardt 2026-10-08 10:35:54 +02:00 committed by Junio C Hamano
parent 45b1324139
commit 8db128e611
5 changed files with 23 additions and 17 deletions

View File

@ -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;
}

View File

@ -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'"),

View File

@ -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);


18
odb.c
View File

@ -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 @@ out:
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;
}

3
odb.h
View File

@ -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);