cache-tree: remove dependency on `the_repository`
The "cache-tree" subsystem still depends on `the_repository`. Adapt it to instead use repositories provided via the context, either as a new parameter or the one passed in via `struct index_state`. Besides getting rid of `the_repository`, this also removes the last dependency on registering submodule sources with the main object database. When reading gitmodules from a submodule's index we implicitly read that object via `the_repository`'s object database, which is of course wrong. This works though because we would then register the submodule's object database with the main object database, but a later patch is going to get rid of that mechanism. You can verify that we indeed no longer depend on this mechanism by running tests with `GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=true`. Without this patch we fail in t1092, with this patch we never register submodule object databases anymore. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>jch^2
parent
004f98f28f
commit
895156bb99
|
|
@ -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, the_repository->index->cache_tree))
|
||||
cache_tree_update(the_repository->index, WRITE_TREE_SILENT | WRITE_TREE_REPAIR);
|
||||
|
||||
if (write_locked_index(the_repository->index, &lock_file, COMMIT_LOCK))
|
||||
|
|
|
|||
|
|
@ -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, the_repository->index->cache_tree))
|
||||
cache_tree_update(the_repository->index, WRITE_TREE_SILENT);
|
||||
if (write_locked_index(the_repository->index, &index_lock,
|
||||
COMMIT_LOCK | SKIP_IF_UNCHANGED))
|
||||
|
|
|
|||
88
cache-tree.c
88
cache-tree.c
|
|
@ -1,4 +1,3 @@
|
|||
#define USE_THE_REPOSITORY_VARIABLE
|
||||
#define DISABLE_SIGN_COMPARE_WARNINGS
|
||||
|
||||
#include "git-compat-util.h"
|
||||
|
|
@ -275,28 +274,30 @@ static void discard_unused_subtrees(struct cache_tree *it)
|
|||
}
|
||||
}
|
||||
|
||||
int cache_tree_fully_valid(struct cache_tree *it)
|
||||
int cache_tree_fully_valid(struct repository *repo, 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(repo->objects, &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(repo, it->down[i]->cache_tree))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int must_check_existence(const struct cache_entry *ce)
|
||||
static int must_check_existence(const struct cache_entry *ce, void *cb_data)
|
||||
{
|
||||
return !(repo_has_promisor_remote(the_repository) && ce_skip_worktree(ce));
|
||||
struct repository *repo = cb_data;
|
||||
return !(repo_has_promisor_remote(repo) && ce_skip_worktree(ce));
|
||||
}
|
||||
|
||||
static int update_one(struct cache_tree *it,
|
||||
static int update_one(struct repository *repo,
|
||||
struct cache_tree *it,
|
||||
struct cache_entry **cache,
|
||||
int entries,
|
||||
const char *base,
|
||||
|
|
@ -334,7 +335,7 @@ static int update_one(struct cache_tree *it,
|
|||
}
|
||||
|
||||
if (0 <= it->entry_count &&
|
||||
odb_has_object(the_repository->objects, &it->oid,
|
||||
odb_has_object(repo->objects, &it->oid,
|
||||
ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR))
|
||||
return it->entry_count;
|
||||
|
||||
|
|
@ -375,7 +376,8 @@ static int update_one(struct cache_tree *it,
|
|||
sub = find_subtree(it, path + baselen, sublen, 1);
|
||||
if (!sub->cache_tree)
|
||||
sub->cache_tree = cache_tree();
|
||||
subcnt = update_one(sub->cache_tree,
|
||||
subcnt = update_one(repo,
|
||||
sub->cache_tree,
|
||||
cache + i, entries - i,
|
||||
path,
|
||||
baselen + sublen + 1,
|
||||
|
|
@ -439,10 +441,10 @@ static int update_one(struct cache_tree *it,
|
|||
}
|
||||
|
||||
ce_missing_ok = mode == S_IFGITLINK || missing_ok ||
|
||||
!must_check_existence(ce);
|
||||
!must_check_existence(ce, repo);
|
||||
if (is_null_oid(oid) ||
|
||||
(!ce_missing_ok &&
|
||||
!odb_has_object(the_repository->objects, oid,
|
||||
!odb_has_object(repo->objects, oid,
|
||||
ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR))) {
|
||||
strbuf_release(&buffer);
|
||||
if (expected_missing)
|
||||
|
|
@ -474,12 +476,12 @@ static int update_one(struct cache_tree *it,
|
|||
/*
|
||||
* "sub" can be an empty tree if all subentries are i-t-a.
|
||||
*/
|
||||
if (contains_ita && is_empty_tree_oid(oid, the_repository->hash_algo))
|
||||
if (contains_ita && is_empty_tree_oid(oid, repo->hash_algo))
|
||||
continue;
|
||||
|
||||
strbuf_grow(&buffer, entlen + 100);
|
||||
strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0');
|
||||
strbuf_add(&buffer, oid->hash, the_hash_algo->rawsz);
|
||||
strbuf_add(&buffer, oid->hash, repo->hash_algo->rawsz);
|
||||
|
||||
#if DEBUG_CACHE_TREE
|
||||
fprintf(stderr, "cache-tree update-one %o %.*s\n",
|
||||
|
|
@ -489,16 +491,16 @@ static int update_one(struct cache_tree *it,
|
|||
|
||||
if (repair) {
|
||||
struct object_id oid;
|
||||
hash_object_file(the_hash_algo, buffer.buf, buffer.len,
|
||||
hash_object_file(repo->hash_algo, buffer.buf, buffer.len,
|
||||
OBJ_TREE, &oid);
|
||||
if (odb_has_object(the_repository->objects, &oid, ODB_HAS_OBJECT_RECHECK_PACKED))
|
||||
if (odb_has_object(repo->objects, &oid, ODB_HAS_OBJECT_RECHECK_PACKED))
|
||||
oidcpy(&it->oid, &oid);
|
||||
else
|
||||
to_invalidate = 1;
|
||||
} else if (dryrun) {
|
||||
hash_object_file(the_hash_algo, buffer.buf, buffer.len,
|
||||
hash_object_file(repo->hash_algo, buffer.buf, buffer.len,
|
||||
OBJ_TREE, &it->oid);
|
||||
} else if (odb_write_object_ext(the_repository->objects, buffer.buf, buffer.len, OBJ_TREE,
|
||||
} else if (odb_write_object_ext(repo->objects, buffer.buf, buffer.len, OBJ_TREE,
|
||||
&it->oid, NULL, flags & WRITE_TREE_SILENT ? ODB_WRITE_OBJECT_SILENT : 0)) {
|
||||
strbuf_release(&buffer);
|
||||
return -1;
|
||||
|
|
@ -516,7 +518,7 @@ static int update_one(struct cache_tree *it,
|
|||
|
||||
int cache_tree_update(struct index_state *istate, int flags)
|
||||
{
|
||||
int inflight = !!the_repository->objects->transaction;
|
||||
int inflight = !!istate->repo->objects->transaction;
|
||||
struct odb_transaction *transaction;
|
||||
int skip, i;
|
||||
|
||||
|
|
@ -528,14 +530,14 @@ int cache_tree_update(struct index_state *istate, int flags)
|
|||
if (!istate->cache_tree)
|
||||
istate->cache_tree = cache_tree();
|
||||
|
||||
if (!(flags & WRITE_TREE_MISSING_OK) && repo_has_promisor_remote(the_repository))
|
||||
prefetch_cache_entries(istate, must_check_existence);
|
||||
if (!(flags & WRITE_TREE_MISSING_OK) && repo_has_promisor_remote(istate->repo))
|
||||
prefetch_cache_entries(istate, must_check_existence, istate->repo);
|
||||
|
||||
trace_performance_enter();
|
||||
trace2_region_enter("cache_tree", "update", istate->repo);
|
||||
if (!inflight)
|
||||
odb_transaction_begin_or_die(the_repository->objects, &transaction, 0);
|
||||
i = update_one(istate->cache_tree, istate->cache, istate->cache_nr,
|
||||
odb_transaction_begin_or_die(istate->repo->objects, &transaction, 0);
|
||||
i = update_one(istate->repo, istate->cache_tree, istate->cache, istate->cache_nr,
|
||||
"", 0, &skip, flags);
|
||||
if (!inflight)
|
||||
odb_transaction_commit_and_finalize_or_die(transaction);
|
||||
|
|
@ -547,7 +549,8 @@ int cache_tree_update(struct index_state *istate, int flags)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void write_one(struct strbuf *buffer, struct cache_tree *it,
|
||||
static void write_one(struct repository *repo,
|
||||
struct strbuf *buffer, struct cache_tree *it,
|
||||
const char *path, int pathlen)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -573,7 +576,7 @@ static void write_one(struct strbuf *buffer, struct cache_tree *it,
|
|||
#endif
|
||||
|
||||
if (0 <= it->entry_count) {
|
||||
strbuf_add(buffer, it->oid.hash, the_hash_algo->rawsz);
|
||||
strbuf_add(buffer, it->oid.hash, repo->hash_algo->rawsz);
|
||||
}
|
||||
for (i = 0; i < it->subtree_nr; i++) {
|
||||
struct cache_tree_sub *down = it->down[i];
|
||||
|
|
@ -583,15 +586,16 @@ static void write_one(struct strbuf *buffer, struct cache_tree *it,
|
|||
prev->name, prev->namelen) <= 0)
|
||||
die("fatal - unsorted cache subtree");
|
||||
}
|
||||
write_one(buffer, down->cache_tree, down->name, down->namelen);
|
||||
write_one(repo, buffer, down->cache_tree, down->name, down->namelen);
|
||||
}
|
||||
}
|
||||
|
||||
void cache_tree_write(struct strbuf *sb, struct cache_tree *root)
|
||||
void cache_tree_write(struct repository *repo,
|
||||
struct strbuf *sb, struct cache_tree *root)
|
||||
{
|
||||
trace2_region_enter("cache_tree", "write", the_repository);
|
||||
write_one(sb, root, "", 0);
|
||||
trace2_region_leave("cache_tree", "write", the_repository);
|
||||
trace2_region_enter("cache_tree", "write", repo);
|
||||
write_one(repo, sb, root, "", 0);
|
||||
trace2_region_leave("cache_tree", "write", repo);
|
||||
}
|
||||
|
||||
static int parse_int(const char **ptr, unsigned long *len_p, int *out)
|
||||
|
|
@ -625,13 +629,14 @@ static int parse_int(const char **ptr, unsigned long *len_p, int *out)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
|
||||
static struct cache_tree *read_one(struct repository *repo,
|
||||
const char **buffer, unsigned long *size_p)
|
||||
{
|
||||
const char *buf = *buffer;
|
||||
unsigned long size = *size_p;
|
||||
struct cache_tree *it;
|
||||
int i, subtree_nr;
|
||||
const unsigned rawsz = the_hash_algo->rawsz;
|
||||
const unsigned rawsz = repo->hash_algo->rawsz;
|
||||
|
||||
it = NULL;
|
||||
/* skip name, but make sure name exists */
|
||||
|
|
@ -658,7 +663,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
|
|||
if (size < rawsz)
|
||||
goto free_return;
|
||||
oidread(&it->oid, (const unsigned char *)buf,
|
||||
the_repository->hash_algo);
|
||||
repo->hash_algo);
|
||||
buf += rawsz;
|
||||
size -= rawsz;
|
||||
}
|
||||
|
|
@ -686,7 +691,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
|
|||
struct cache_tree_sub *subtree;
|
||||
const char *name = buf;
|
||||
|
||||
sub = read_one(&buf, &size);
|
||||
sub = read_one(repo, &buf, &size);
|
||||
if (!sub)
|
||||
goto free_return;
|
||||
subtree = cache_tree_sub(it, name);
|
||||
|
|
@ -703,16 +708,17 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct cache_tree *cache_tree_read(const char *buffer, unsigned long size)
|
||||
struct cache_tree *cache_tree_read(struct repository *repo,
|
||||
const char *buffer, unsigned long size)
|
||||
{
|
||||
struct cache_tree *result;
|
||||
|
||||
if (buffer[0])
|
||||
return NULL; /* not the whole tree */
|
||||
|
||||
trace2_region_enter("cache_tree", "read", the_repository);
|
||||
result = read_one(&buffer, &size);
|
||||
trace2_region_leave("cache_tree", "read", the_repository);
|
||||
trace2_region_enter("cache_tree", "read", repo);
|
||||
result = read_one(repo, &buffer, &size);
|
||||
trace2_region_leave("cache_tree", "read", repo);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -775,7 +781,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(repo, index_state->cache_tree);
|
||||
|
||||
ret = write_index_as_tree_internal(&o, index_state, was_valid, 0, NULL);
|
||||
if (ret == WRITE_TREE_UNMERGED_INDEX) {
|
||||
|
|
@ -803,7 +809,7 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state,
|
|||
hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR);
|
||||
|
||||
entries = read_index_from(index_state, index_path,
|
||||
repo_get_git_dir(the_repository));
|
||||
repo_get_git_dir(index_state->repo));
|
||||
if (entries < 0) {
|
||||
ret = WRITE_TREE_UNREADABLE_INDEX;
|
||||
goto out;
|
||||
|
|
@ -811,7 +817,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->repo, index_state->cache_tree);
|
||||
|
||||
ret = write_index_as_tree_internal(oid, index_state, was_valid, flags,
|
||||
prefix);
|
||||
|
|
@ -859,7 +865,7 @@ static void prime_cache_tree_rec(struct repository *r,
|
|||
struct cache_tree_sub *sub;
|
||||
struct tree *subtree = lookup_tree(r, &entry.oid);
|
||||
|
||||
if (repo_parse_tree(the_repository, subtree) < 0)
|
||||
if (repo_parse_tree(r, subtree) < 0)
|
||||
exit(128);
|
||||
sub = cache_tree_sub(it, entry.path);
|
||||
sub->cache_tree = cache_tree();
|
||||
|
|
|
|||
|
|
@ -28,10 +28,11 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *);
|
|||
|
||||
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);
|
||||
void cache_tree_write(struct repository *repo, struct strbuf *, struct cache_tree *root);
|
||||
struct cache_tree *cache_tree_read(struct repository *repo,
|
||||
const char *buffer, unsigned long size);
|
||||
|
||||
int cache_tree_fully_valid(struct cache_tree *);
|
||||
int cache_tree_fully_valid(struct repository *, struct cache_tree *);
|
||||
int cache_tree_update(struct index_state *, int);
|
||||
int cache_tree_verify(struct repository *, struct index_state *);
|
||||
|
||||
|
|
|
|||
|
|
@ -269,9 +269,10 @@ void validate_cache_entries(const struct index_state *istate);
|
|||
* the given predicate. This function should only be called if
|
||||
* repo_has_promisor_remote() returns true.
|
||||
*/
|
||||
typedef int (*must_prefetch_predicate)(const struct cache_entry *);
|
||||
typedef int (*must_prefetch_predicate)(const struct cache_entry *, void *cb_data);
|
||||
void prefetch_cache_entries(const struct index_state *istate,
|
||||
must_prefetch_predicate must_prefetch);
|
||||
must_prefetch_predicate must_prefetch,
|
||||
void *cb_data);
|
||||
|
||||
/* Initialize and use the cache information */
|
||||
struct lock_file;
|
||||
|
|
|
|||
|
|
@ -1748,7 +1748,7 @@ static int read_index_extension(struct index_state *istate,
|
|||
{
|
||||
switch (CACHE_EXT(ext)) {
|
||||
case CACHE_EXT_TREE:
|
||||
istate->cache_tree = cache_tree_read(data, sz);
|
||||
istate->cache_tree = cache_tree_read(istate->repo, data, sz);
|
||||
break;
|
||||
case CACHE_EXT_RESOLVE_UNDO:
|
||||
istate->resolve_undo = resolve_undo_read(data, sz, the_hash_algo);
|
||||
|
|
@ -3012,7 +3012,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
|
|||
!drop_cache_tree && istate->cache_tree) {
|
||||
strbuf_reset(&sb);
|
||||
|
||||
cache_tree_write(&sb, istate->cache_tree);
|
||||
cache_tree_write(istate->repo, &sb, istate->cache_tree);
|
||||
err = write_index_ext_header(f, eoie_c, CACHE_EXT_TREE, sb.len) < 0;
|
||||
hashwrite(f, sb.buf, sb.len);
|
||||
if (err) {
|
||||
|
|
@ -3733,7 +3733,8 @@ static void write_ieot_extension(struct strbuf *sb, struct index_entry_offset_ta
|
|||
}
|
||||
|
||||
void prefetch_cache_entries(const struct index_state *istate,
|
||||
must_prefetch_predicate must_prefetch)
|
||||
must_prefetch_predicate must_prefetch,
|
||||
void *cb_data)
|
||||
{
|
||||
int i;
|
||||
struct oid_array to_fetch = OID_ARRAY_INIT;
|
||||
|
|
@ -3741,7 +3742,7 @@ void prefetch_cache_entries(const struct index_state *istate,
|
|||
for (i = 0; i < istate->cache_nr; i++) {
|
||||
struct cache_entry *ce = istate->cache[i];
|
||||
|
||||
if (S_ISGITLINK(ce->ce_mode) || !must_prefetch(ce))
|
||||
if (S_ISGITLINK(ce->ce_mode) || !must_prefetch(ce, cb_data))
|
||||
continue;
|
||||
if (!odb_read_object_info_extended(the_repository->objects,
|
||||
&ce->oid, NULL,
|
||||
|
|
|
|||
|
|
@ -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->repo, istate->cache_tree))
|
||||
if (cache_tree_update(istate, 0)) {
|
||||
error(_("unable to update cache tree"));
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -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->repo, istate->cache_tree)) {
|
||||
/* Clear and recompute the cache-tree */
|
||||
cache_tree_free(&istate->cache_tree);
|
||||
|
||||
|
|
|
|||
|
|
@ -416,7 +416,8 @@ static void report_collided_checkout(struct index_state *index)
|
|||
string_list_clear(&list, 0);
|
||||
}
|
||||
|
||||
static int must_checkout(const struct cache_entry *ce)
|
||||
static int must_checkout(const struct cache_entry *ce,
|
||||
void *cb_data UNUSED)
|
||||
{
|
||||
return ce->ce_flags & CE_UPDATE;
|
||||
}
|
||||
|
|
@ -477,7 +478,7 @@ static int check_updates(struct unpack_trees_options *o,
|
|||
* Prefetch the objects that are to be checked out in the loop
|
||||
* below.
|
||||
*/
|
||||
prefetch_cache_entries(index, must_checkout);
|
||||
prefetch_cache_entries(index, must_checkout, NULL);
|
||||
|
||||
get_parallel_checkout_configs(&pc_workers, &pc_threshold);
|
||||
|
||||
|
|
@ -487,7 +488,7 @@ static int check_updates(struct unpack_trees_options *o,
|
|||
for (i = 0; i < index->cache_nr; i++) {
|
||||
struct cache_entry *ce = index->cache[i];
|
||||
|
||||
if (must_checkout(ce)) {
|
||||
if (must_checkout(ce, NULL)) {
|
||||
size_t last_pc_queue_size = pc_queue_size();
|
||||
|
||||
if (ce->ce_flags & CE_WT_REMOVE)
|
||||
|
|
@ -2086,7 +2087,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(the_repository, o->internal.result.cache_tree))
|
||||
cache_tree_update(&o->internal.result,
|
||||
WRITE_TREE_SILENT |
|
||||
WRITE_TREE_REPAIR);
|
||||
|
|
|
|||
Loading…
Reference in New Issue