cache-tree: drop `the_repository` in `cache_tree_fully_valid()`

The function `cache_tree_fully_valid()` verifies whether the cache tree
owned by the index is valid or not. As part of that, the function checks
whether the objects referenced by the cache all exist. But because the
function has no repository available, it is using the object database of
`the_repository` instead.

We could of course adapt callers to pass in a repository as parameter
explicitly to get rid of this implicit dependency on global state. But
all of them pass the cache tree owned by a `struct index_state`, and
that structure already has a reference to its owning repository.

So instead, adapt the function to accept a `struct index_state`, which
ensures that callers will implicitly always pass the correct repository.
Adapt callers accordingly.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
jch^2
Patrick Steinhardt 2026-09-02 15:34:49 +02:00 committed by Junio C Hamano
parent 004f98f28f
commit f5e831f38f
7 changed files with 18 additions and 11 deletions

View File

@ -921,7 +921,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
}
}

if (!cache_tree_fully_valid(the_repository->index->cache_tree))
if (!cache_tree_fully_valid(the_repository->index))
cache_tree_update(the_repository->index, WRITE_TREE_SILENT | WRITE_TREE_REPAIR);

if (write_locked_index(the_repository->index, &lock_file, COMMIT_LOCK))

View File

@ -484,7 +484,7 @@ static const char *prepare_index(const char **argv, const char *prefix,
LOCK_DIE_ON_ERROR);
refresh_cache_or_die(refresh_flags);
if (the_repository->index->cache_changed
|| !cache_tree_fully_valid(the_repository->index->cache_tree))
|| !cache_tree_fully_valid(the_repository->index))
cache_tree_update(the_repository->index, WRITE_TREE_SILENT);
if (write_locked_index(the_repository->index, &index_lock,
COMMIT_LOCK | SKIP_IF_UNCHANGED))

View File

@ -275,22 +275,29 @@ static void discard_unused_subtrees(struct cache_tree *it)
}
}

int cache_tree_fully_valid(struct cache_tree *it)
static int cache_tree_fully_valid_recursive(struct object_database *odb,
struct cache_tree *it)
{
int i;
if (!it)
return 0;
if (it->entry_count < 0 ||
!odb_has_object(the_repository->objects, &it->oid,
!odb_has_object(odb, &it->oid,
ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR))
return 0;
for (i = 0; i < it->subtree_nr; i++) {
if (!cache_tree_fully_valid(it->down[i]->cache_tree))
if (!cache_tree_fully_valid_recursive(odb, it->down[i]->cache_tree))
return 0;
}
return 1;
}

int cache_tree_fully_valid(struct index_state *istate)
{
return cache_tree_fully_valid_recursive(istate->repo->objects,
istate->cache_tree);
}

static int must_check_existence(const struct cache_entry *ce)
{
return !(repo_has_promisor_remote(the_repository) && ce_skip_worktree(ce));
@ -775,7 +782,7 @@ struct tree *write_in_core_index_as_tree(struct repository *repo,
int was_valid, ret;

was_valid = index_state->cache_tree &&
cache_tree_fully_valid(index_state->cache_tree);
cache_tree_fully_valid(index_state);

ret = write_index_as_tree_internal(&o, index_state, was_valid, 0, NULL);
if (ret == WRITE_TREE_UNMERGED_INDEX) {
@ -811,7 +818,7 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state,

was_valid = !(flags & WRITE_TREE_IGNORE_CACHE_TREE) &&
index_state->cache_tree &&
cache_tree_fully_valid(index_state->cache_tree);
cache_tree_fully_valid(index_state);

ret = write_index_as_tree_internal(oid, index_state, was_valid, flags,
prefix);

View File

@ -31,7 +31,7 @@ int cache_tree_subtree_pos(struct cache_tree *it, const char *path, int pathlen)
void cache_tree_write(struct strbuf *, struct cache_tree *root);
struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);

int cache_tree_fully_valid(struct cache_tree *);
int cache_tree_fully_valid(struct index_state *);
int cache_tree_update(struct index_state *, int);
int cache_tree_verify(struct repository *, struct index_state *);


View File

@ -814,7 +814,7 @@ static int do_recursive_merge(struct repository *r,

static struct object_id *get_cache_tree_oid(struct index_state *istate)
{
if (!cache_tree_fully_valid(istate->cache_tree))
if (!cache_tree_fully_valid(istate))
if (cache_tree_update(istate, 0)) {
error(_("unable to update cache tree"));
return NULL;

View File

@ -228,7 +228,7 @@ int convert_to_sparse(struct index_state *istate, int flags)
if (index_has_unmerged_entries(istate))
return 0;

if (!cache_tree_fully_valid(istate->cache_tree)) {
if (!cache_tree_fully_valid(istate)) {
/* Clear and recompute the cache-tree */
cache_tree_free(&istate->cache_tree);


View File

@ -2086,7 +2086,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
}

if (!o->skip_cache_tree_update &&
!cache_tree_fully_valid(o->internal.result.cache_tree))
!cache_tree_fully_valid(&o->internal.result))
cache_tree_update(&o->internal.result,
WRITE_TREE_SILENT |
WRITE_TREE_REPAIR);