sparse-checkout: toggle sparse index from builtin
The sparse index extension is used to signal that index writes should be in sparse mode. This was only updated using GIT_TEST_SPARSE_INDEX=1. Add a '--[no-]sparse-index' option to 'git sparse-checkout init' that specifies if the sparse index should be used. It also updates the index to use the correct format, either way. Add a warning in the documentation that the use of a repository extension might reduce compatibility with third-party tools. 'git sparse-checkout init' already sets extension.worktreeConfig, which places most sparse-checkout users outside of the scope of most third-party tools. Update t1092-sparse-checkout-compatibility.sh to use this CLI instead of GIT_TEST_SPARSE_INDEX=1. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
58300f4743
commit
122ba1f7b5
@ -45,6 +45,20 @@ To avoid interfering with other worktrees, it first enables the
|
||||
When `--cone` is provided, the `core.sparseCheckoutCone` setting is
|
||||
also set, allowing for better performance with a limited set of
|
||||
patterns (see 'CONE PATTERN SET' below).
|
||||
+
|
||||
Use the `--[no-]sparse-index` option to toggle the use of the sparse
|
||||
index format. This reduces the size of the index to be more closely
|
||||
aligned with your sparse-checkout definition. This can have significant
|
||||
performance advantages for commands such as `git status` or `git add`.
|
||||
This feature is still experimental. Some commands might be slower with
|
||||
a sparse index until they are properly integrated with the feature.
|
||||
+
|
||||
**WARNING:** Using a sparse index requires modifying the index in a way
|
||||
that is not completely understood by external tools. If you have trouble
|
||||
with this compatibility, then run `git sparse-checkout init --no-sparse-index`
|
||||
to rewrite your index to not be sparse. Older versions of Git will not
|
||||
understand the sparse directory entries index extension and may fail to
|
||||
interact with your repository until it is disabled.
|
||||
|
||||
'set'::
|
||||
Write a set of patterns to the sparse-checkout file, as given as
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "unpack-trees.h"
|
||||
#include "wt-status.h"
|
||||
#include "quote.h"
|
||||
#include "sparse-index.h"
|
||||
|
||||
static const char *empty_base = "";
|
||||
|
||||
@ -283,12 +284,13 @@ static int set_config(enum sparse_checkout_mode mode)
|
||||
}
|
||||
|
||||
static char const * const builtin_sparse_checkout_init_usage[] = {
|
||||
N_("git sparse-checkout init [--cone]"),
|
||||
N_("git sparse-checkout init [--cone] [--[no-]sparse-index]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct sparse_checkout_init_opts {
|
||||
int cone_mode;
|
||||
int sparse_index;
|
||||
} init_opts;
|
||||
|
||||
static int sparse_checkout_init(int argc, const char **argv)
|
||||
@ -303,11 +305,15 @@ static int sparse_checkout_init(int argc, const char **argv)
|
||||
static struct option builtin_sparse_checkout_init_options[] = {
|
||||
OPT_BOOL(0, "cone", &init_opts.cone_mode,
|
||||
N_("initialize the sparse-checkout in cone mode")),
|
||||
OPT_BOOL(0, "sparse-index", &init_opts.sparse_index,
|
||||
N_("toggle the use of a sparse index")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
repo_read_index(the_repository);
|
||||
|
||||
init_opts.sparse_index = -1;
|
||||
|
||||
argc = parse_options(argc, argv, NULL,
|
||||
builtin_sparse_checkout_init_options,
|
||||
builtin_sparse_checkout_init_usage, 0);
|
||||
@ -326,6 +332,15 @@ static int sparse_checkout_init(int argc, const char **argv)
|
||||
sparse_filename = get_sparse_checkout_filename();
|
||||
res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL);
|
||||
|
||||
if (init_opts.sparse_index >= 0) {
|
||||
if (set_sparse_index_config(the_repository, init_opts.sparse_index) < 0)
|
||||
die(_("failed to modify sparse-index config"));
|
||||
|
||||
/* force an index rewrite */
|
||||
repo_read_index(the_repository);
|
||||
the_repository->index->updated_workdir = 1;
|
||||
}
|
||||
|
||||
/* If we already have a sparse-checkout file, use it. */
|
||||
if (res >= 0) {
|
||||
free(sparse_filename);
|
||||
|
@ -102,21 +102,32 @@ static int convert_to_sparse_rec(struct index_state *istate,
|
||||
return num_converted - start_converted;
|
||||
}
|
||||
|
||||
static int enable_sparse_index(struct repository *repo)
|
||||
static int set_index_sparse_config(struct repository *repo, int enable)
|
||||
{
|
||||
const char *config_path = repo_git_path(repo, "config.worktree");
|
||||
|
||||
git_config_set_in_file_gently(config_path,
|
||||
"index.sparse",
|
||||
"true");
|
||||
int res;
|
||||
char *config_path = repo_git_path(repo, "config.worktree");
|
||||
res = git_config_set_in_file_gently(config_path,
|
||||
"index.sparse",
|
||||
enable ? "true" : NULL);
|
||||
free(config_path);
|
||||
|
||||
prepare_repo_settings(repo);
|
||||
repo->settings.sparse_index = 1;
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
int set_sparse_index_config(struct repository *repo, int enable)
|
||||
{
|
||||
int res = set_index_sparse_config(repo, enable);
|
||||
|
||||
prepare_repo_settings(repo);
|
||||
repo->settings.sparse_index = enable;
|
||||
return res;
|
||||
}
|
||||
|
||||
int convert_to_sparse(struct index_state *istate)
|
||||
{
|
||||
int test_env;
|
||||
if (istate->split_index || istate->sparse_index ||
|
||||
!core_apply_sparse_checkout || !core_sparse_checkout_cone)
|
||||
return 0;
|
||||
@ -128,11 +139,9 @@ int convert_to_sparse(struct index_state *istate)
|
||||
* The GIT_TEST_SPARSE_INDEX environment variable triggers the
|
||||
* index.sparse config variable to be on.
|
||||
*/
|
||||
if (git_env_bool("GIT_TEST_SPARSE_INDEX", 0)) {
|
||||
int err = enable_sparse_index(istate->repo);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
test_env = git_env_bool("GIT_TEST_SPARSE_INDEX", -1);
|
||||
if (test_env >= 0)
|
||||
set_sparse_index_config(istate->repo, test_env);
|
||||
|
||||
/*
|
||||
* Only convert to sparse if index.sparse is set.
|
||||
|
@ -5,4 +5,7 @@ struct index_state;
|
||||
void ensure_full_index(struct index_state *istate);
|
||||
int convert_to_sparse(struct index_state *istate);
|
||||
|
||||
struct repository;
|
||||
int set_sparse_index_config(struct repository *repo, int enable);
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@ test_description='compare full workdir to sparse workdir'
|
||||
# So, disable the check until that integration is complete.
|
||||
GIT_TEST_CHECK_CACHE_TREE=0
|
||||
GIT_TEST_SPLIT_INDEX=0
|
||||
GIT_TEST_SPARSE_INDEX=
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
@ -100,25 +101,26 @@ init_repos () {
|
||||
# initialize sparse-checkout definitions
|
||||
git -C sparse-checkout sparse-checkout init --cone &&
|
||||
git -C sparse-checkout sparse-checkout set deep &&
|
||||
GIT_TEST_SPARSE_INDEX=1 git -C sparse-index sparse-checkout init --cone &&
|
||||
GIT_TEST_SPARSE_INDEX=1 git -C sparse-index sparse-checkout set deep
|
||||
git -C sparse-index sparse-checkout init --cone --sparse-index &&
|
||||
test_cmp_config -C sparse-index true index.sparse &&
|
||||
git -C sparse-index sparse-checkout set deep
|
||||
}
|
||||
|
||||
run_on_sparse () {
|
||||
(
|
||||
cd sparse-checkout &&
|
||||
GIT_TEST_SPARSE_INDEX=0 "$@" >../sparse-checkout-out 2>../sparse-checkout-err
|
||||
"$@" >../sparse-checkout-out 2>../sparse-checkout-err
|
||||
) &&
|
||||
(
|
||||
cd sparse-index &&
|
||||
GIT_TEST_SPARSE_INDEX=1 "$@" >../sparse-index-out 2>../sparse-index-err
|
||||
"$@" >../sparse-index-out 2>../sparse-index-err
|
||||
)
|
||||
}
|
||||
|
||||
run_on_all () {
|
||||
(
|
||||
cd full-checkout &&
|
||||
GIT_TEST_SPARSE_INDEX=0 "$@" >../full-checkout-out 2>../full-checkout-err
|
||||
"$@" >../full-checkout-out 2>../full-checkout-err
|
||||
) &&
|
||||
run_on_sparse "$@"
|
||||
}
|
||||
@ -148,7 +150,7 @@ test_expect_success 'sparse-index contents' '
|
||||
|| return 1
|
||||
done &&
|
||||
|
||||
GIT_TEST_SPARSE_INDEX=1 git -C sparse-index sparse-checkout set folder1 &&
|
||||
git -C sparse-index sparse-checkout set folder1 &&
|
||||
|
||||
test-tool -C sparse-index read-cache --table >cache &&
|
||||
for dir in deep folder2 x
|
||||
@ -158,7 +160,7 @@ test_expect_success 'sparse-index contents' '
|
||||
|| return 1
|
||||
done &&
|
||||
|
||||
GIT_TEST_SPARSE_INDEX=1 git -C sparse-index sparse-checkout set deep/deeper1 &&
|
||||
git -C sparse-index sparse-checkout set deep/deeper1 &&
|
||||
|
||||
test-tool -C sparse-index read-cache --table >cache &&
|
||||
for dir in deep/deeper2 folder1 folder2 x
|
||||
@ -166,7 +168,14 @@ test_expect_success 'sparse-index contents' '
|
||||
TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
|
||||
grep "040000 tree $TREE $dir/" cache \
|
||||
|| return 1
|
||||
done
|
||||
done &&
|
||||
|
||||
# Disabling the sparse-index removes tree entries with full ones
|
||||
git -C sparse-index sparse-checkout init --no-sparse-index &&
|
||||
|
||||
test-tool -C sparse-index read-cache --table >cache &&
|
||||
! grep "040000 tree" cache &&
|
||||
test_sparse_match test-tool read-cache --table
|
||||
'
|
||||
|
||||
test_expect_success 'expanded in-memory index matches full index' '
|
||||
@ -396,19 +405,15 @@ test_expect_success 'submodule handling' '
|
||||
test_expect_success 'sparse-index is expanded and converted back' '
|
||||
init_repos &&
|
||||
|
||||
(
|
||||
GIT_TEST_SPARSE_INDEX=1 &&
|
||||
export GIT_TEST_SPARSE_INDEX &&
|
||||
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
|
||||
git -C sparse-index -c core.fsmonitor="" reset --hard &&
|
||||
test_region index convert_to_sparse trace2.txt &&
|
||||
test_region index ensure_full_index trace2.txt &&
|
||||
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
|
||||
git -C sparse-index -c core.fsmonitor="" reset --hard &&
|
||||
test_region index convert_to_sparse trace2.txt &&
|
||||
test_region index ensure_full_index trace2.txt &&
|
||||
|
||||
rm trace2.txt &&
|
||||
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
|
||||
git -C sparse-index -c core.fsmonitor="" status -uno &&
|
||||
test_region index ensure_full_index trace2.txt
|
||||
)
|
||||
rm trace2.txt &&
|
||||
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
|
||||
git -C sparse-index -c core.fsmonitor="" status -uno &&
|
||||
test_region index ensure_full_index trace2.txt
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user