tmp-objdir: absorb logic to set and restore primary sources

The functions `odb_set_temporary_primary_source()` and
`odb_restore_primary_source()` can be used to adapt the primary object
database source. Nowadays though we only have a single user of this
subsystem left, which is the "tmp-objdir" subsystem.

Despite that, this functionality is also becoming less useful overall as
alternates are becoming an implementation detail of the "files" backend.
And with that change, there will only ever be a single source attached
to the object database anyway.

Move the logic into the "tmp-objdir" subsystem accordingly.

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:57 +02:00 committed by Junio C Hamano
parent 5c869c96a4
commit f80a79e233
3 changed files with 34 additions and 66 deletions

45
odb.c
View File

@ -239,51 +239,6 @@ static struct odb_source *odb_add_alternate_recursively(struct object_database *
return alternate;
}

struct odb_source *odb_set_temporary_primary_source(struct object_database *odb,
const char *dir, int will_destroy,
struct odb_source **prev_source)
{
struct odb_source *source;

/*
* Make a new primary odb and link the old primary ODB in as an
* alternate
*/
source = odb_source_new(odb, dir, false);

/*
* Disable ref updates while a temporary odb is active, since
* the objects in the database may roll back.
*/
odb->repo->disable_ref_updates = true;
source->will_destroy = will_destroy;
source->next = odb->sources;
odb->sources = source;

if (prev_source)
*prev_source = source->next;

return source;
}

void odb_restore_primary_source(struct object_database *odb,
struct odb_source *restore_source,
const char *old_path)
{
struct odb_source *cur_source = odb->sources;

if (strcmp(old_path, cur_source->path))
BUG("expected %s as primary object store; found %s",
old_path, cur_source->path);

if (cur_source->next != restore_source)
BUG("we expect the old primary object store to be the first alternate");

odb->repo->disable_ref_updates = false;
odb->sources = restore_source;
odb_source_free(cur_source);
}

char *compute_alternate_path(const char *path, struct strbuf *err)
{
char *ref_git = NULL;

17
odb.h
View File

@ -226,23 +226,6 @@ struct odb_fsck_options {
*/
int odb_fsck(struct object_database *odb, struct odb_fsck_options *opts);

/*
* Replace the current writable object directory with the specified temporary
* object directory and return the newly installed primary source. The former
* primary source is reported via `prev_source` when non-NULL.
*/
struct odb_source *odb_set_temporary_primary_source(struct object_database *odb,
const char *dir, int will_destroy,
struct odb_source **prev_source);

/*
* Restore the primary source that was previously replaced by
* `odb_set_temporary_primary_source()`.
*/
void odb_restore_primary_source(struct object_database *odb,
struct odb_source *restore_source,
const char *old_path);

/*
* Iterate through all alternates of the database and execute the provided
* callback function for each of them. Stop iterating once the callback

View File

@ -51,6 +51,26 @@ static void tmp_objdir_reparent(const char *old_cwd,
free(path);
}

/*
* Restore the primary source that was previously replaced by
* `tmp_objdir_replace_primary_odb()`.
*/
static void tmp_objdir_restore_source(struct tmp_objdir *t)
{
struct odb_source *cur_source = t->repo->objects->sources;

if (strcmp(t->path.buf, cur_source->path))
BUG("expected %s as primary object store; found %s",
t->path.buf, cur_source->path);

if (cur_source->next != t->prev_source)
BUG("we expect the old primary object store to be the first alternate");

t->repo->disable_ref_updates = false;
t->repo->objects->sources = t->prev_source;
odb_source_free(cur_source);
}

int tmp_objdir_destroy(struct tmp_objdir *t)
{
int err;
@ -62,7 +82,7 @@ int tmp_objdir_destroy(struct tmp_objdir *t)
the_tmp_objdir = NULL;

if (t->prev_source)
odb_restore_primary_source(t->repo->objects, t->prev_source, t->path.buf);
tmp_objdir_restore_source(t);

err = remove_dir_recursively(&t->path, 0);

@ -298,7 +318,7 @@ int tmp_objdir_migrate(struct tmp_objdir *t)
if (t->prev_source) {
if (t->repo->objects->sources->will_destroy)
BUG("migrating an ODB that was marked for destruction");
odb_restore_primary_source(t->repo->objects, t->prev_source, t->path.buf);
tmp_objdir_restore_source(t);
t->prev_source = NULL;
}

@ -328,6 +348,16 @@ struct odb_source *tmp_objdir_replace_primary_odb(struct tmp_objdir *t,
BUG("the primary object database is already replaced");
t->will_destroy = will_destroy;

return odb_set_temporary_primary_source(t->repo->objects, t->path.buf,
will_destroy, &t->prev_source);
/*
* Make a new primary source and link the old primary source in as an
* alternate. Disable ref updates while a temporary source is active,
* since the objects in the database may roll back.
*/
t->prev_source = t->repo->objects->sources;
t->repo->objects->sources = odb_source_new(t->repo->objects, t->path.buf, false);
t->repo->objects->sources->next = t->prev_source;
t->repo->objects->sources->will_destroy = will_destroy;
t->repo->disable_ref_updates = true;

return t->repo->objects->sources;
}