Merge branch 'vd/sparse-sparsity-fix-on-read'
Ensure that the sparseness of the in-core index matches the index.sparse configuration specified by the repository immediately after the on-disk index file is read. * vd/sparse-sparsity-fix-on-read: sparse-index: update do_read_index to ensure correct sparsity sparse-index: add ensure_correct_sparsity function sparse-index: avoid unnecessary cache tree clearing test-read-cache.c: prepare_repo_settings after config init
This commit is contained in:
commit
5396d7b298
@ -2352,9 +2352,17 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
|
||||
|
||||
if (!istate->repo)
|
||||
istate->repo = the_repository;
|
||||
|
||||
/*
|
||||
* If the command explicitly requires a full index, force it
|
||||
* to be full. Otherwise, correct the sparsity based on repository
|
||||
* settings and other properties of the index (if necessary).
|
||||
*/
|
||||
prepare_repo_settings(istate->repo);
|
||||
if (istate->repo->settings.command_requires_full_index)
|
||||
ensure_full_index(istate);
|
||||
else
|
||||
ensure_correct_sparsity(istate);
|
||||
|
||||
return istate->cache_nr;
|
||||
|
||||
|
@ -122,17 +122,17 @@ static int index_has_unmerged_entries(struct index_state *istate)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int convert_to_sparse(struct index_state *istate, int flags)
|
||||
static int is_sparse_index_allowed(struct index_state *istate, int flags)
|
||||
{
|
||||
int test_env;
|
||||
if (istate->sparse_index || !istate->cache_nr ||
|
||||
!core_apply_sparse_checkout || !core_sparse_checkout_cone)
|
||||
if (!core_apply_sparse_checkout || !core_sparse_checkout_cone)
|
||||
return 0;
|
||||
|
||||
if (!istate->repo)
|
||||
istate->repo = the_repository;
|
||||
|
||||
if (!(flags & SPARSE_INDEX_MEMORY_ONLY)) {
|
||||
int test_env;
|
||||
|
||||
/*
|
||||
* The sparse index is not (yet) integrated with a split index.
|
||||
*/
|
||||
@ -168,6 +168,19 @@ int convert_to_sparse(struct index_state *istate, int flags)
|
||||
if (!istate->sparse_checkout_patterns->use_cone_patterns)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int convert_to_sparse(struct index_state *istate, int flags)
|
||||
{
|
||||
/*
|
||||
* If the index is already sparse, empty, or otherwise
|
||||
* cannot be converted to sparse, do not convert.
|
||||
*/
|
||||
if (istate->sparse_index || !istate->cache_nr ||
|
||||
!is_sparse_index_allowed(istate, flags))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* NEEDSWORK: If we have unmerged entries, then stay full.
|
||||
* Unmerged entries prevent the cache-tree extension from working.
|
||||
@ -175,17 +188,20 @@ int convert_to_sparse(struct index_state *istate, int flags)
|
||||
if (index_has_unmerged_entries(istate))
|
||||
return 0;
|
||||
|
||||
/* Clear and recompute the cache-tree */
|
||||
cache_tree_free(&istate->cache_tree);
|
||||
/*
|
||||
* Silently return if there is a problem with the cache tree update,
|
||||
* which might just be due to a conflict state in some entry.
|
||||
*
|
||||
* This might create new tree objects, so be sure to use
|
||||
* WRITE_TREE_MISSING_OK.
|
||||
*/
|
||||
if (cache_tree_update(istate, WRITE_TREE_MISSING_OK))
|
||||
return 0;
|
||||
if (!cache_tree_fully_valid(istate->cache_tree)) {
|
||||
/* Clear and recompute the cache-tree */
|
||||
cache_tree_free(&istate->cache_tree);
|
||||
|
||||
/*
|
||||
* Silently return if there is a problem with the cache tree update,
|
||||
* which might just be due to a conflict state in some entry.
|
||||
*
|
||||
* This might create new tree objects, so be sure to use
|
||||
* WRITE_TREE_MISSING_OK.
|
||||
*/
|
||||
if (cache_tree_update(istate, WRITE_TREE_MISSING_OK))
|
||||
return 0;
|
||||
}
|
||||
|
||||
remove_fsmonitor(istate);
|
||||
|
||||
@ -313,6 +329,18 @@ void ensure_full_index(struct index_state *istate)
|
||||
trace2_region_leave("index", "ensure_full_index", istate->repo);
|
||||
}
|
||||
|
||||
void ensure_correct_sparsity(struct index_state *istate)
|
||||
{
|
||||
/*
|
||||
* If the index can be sparse, make it sparse. Otherwise,
|
||||
* ensure the index is full.
|
||||
*/
|
||||
if (is_sparse_index_allowed(istate, 0))
|
||||
convert_to_sparse(istate, 0);
|
||||
else
|
||||
ensure_full_index(istate);
|
||||
}
|
||||
|
||||
/*
|
||||
* This static global helps avoid infinite recursion between
|
||||
* expand_to_path() and index_file_exists().
|
||||
|
@ -4,6 +4,7 @@
|
||||
struct index_state;
|
||||
#define SPARSE_INDEX_MEMORY_ONLY (1 << 0)
|
||||
int convert_to_sparse(struct index_state *istate, int flags);
|
||||
void ensure_correct_sparsity(struct index_state *istate);
|
||||
|
||||
/*
|
||||
* Some places in the codebase expect to search for a specific path.
|
||||
|
@ -39,8 +39,6 @@ int cmd__read_cache(int argc, const char **argv)
|
||||
int table = 0, expand = 0;
|
||||
|
||||
initialize_the_repository();
|
||||
prepare_repo_settings(r);
|
||||
r->settings.command_requires_full_index = 0;
|
||||
|
||||
for (++argv, --argc; *argv && starts_with(*argv, "--"); ++argv, --argc) {
|
||||
if (skip_prefix(*argv, "--print-and-refresh=", &name))
|
||||
@ -56,6 +54,9 @@ int cmd__read_cache(int argc, const char **argv)
|
||||
setup_git_directory();
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
prepare_repo_settings(r);
|
||||
r->settings.command_requires_full_index = 0;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
repo_read_index(r);
|
||||
|
||||
|
@ -694,6 +694,37 @@ test_expect_success 'sparse-index is expanded and converted back' '
|
||||
test_region index ensure_full_index trace2.txt
|
||||
'
|
||||
|
||||
test_expect_success 'index.sparse disabled inline uses full index' '
|
||||
init_repos &&
|
||||
|
||||
# When index.sparse is disabled inline with `git status`, the
|
||||
# index is expanded at the beginning of the execution then never
|
||||
# converted back to sparse. It is then written to disk as a full index.
|
||||
rm -f trace2.txt &&
|
||||
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
|
||||
git -C sparse-index -c index.sparse=false status &&
|
||||
! test_region index convert_to_sparse trace2.txt &&
|
||||
test_region index ensure_full_index trace2.txt &&
|
||||
|
||||
# Since index.sparse is set to true at a repo level, the index
|
||||
# is converted from full to sparse when read, then never expanded
|
||||
# over the course of `git status`. It is written to disk as a sparse
|
||||
# index.
|
||||
rm -f trace2.txt &&
|
||||
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
|
||||
git -C sparse-index status &&
|
||||
test_region index convert_to_sparse trace2.txt &&
|
||||
! test_region index ensure_full_index trace2.txt &&
|
||||
|
||||
# Now that the index has been written to disk as sparse, it is not
|
||||
# converted to sparse (or expanded to full) when read by `git status`.
|
||||
rm -f trace2.txt &&
|
||||
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
|
||||
git -C sparse-index status &&
|
||||
! test_region index convert_to_sparse trace2.txt &&
|
||||
! test_region index ensure_full_index trace2.txt
|
||||
'
|
||||
|
||||
ensure_not_expanded () {
|
||||
rm -f trace2.txt &&
|
||||
echo >>sparse-index/untracked.txt &&
|
||||
|
Loading…
Reference in New Issue
Block a user