From 43d600ef30fe97422d7f1ec14143aecdc743e31f Mon Sep 17 00:00:00 2001 From: Victoria Dye Date: Wed, 22 Sep 2021 13:44:48 -0400 Subject: [PATCH 1/3] fixup! checkout-index: add `--sparse` option Needed to maintain existing behavior for stash. This should not cause a major performance hit, since the index being checked-out contains only the untracked files stashed with a prior `git stash -u`. Signed-off-by: Victoria Dye --- builtin/stash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/stash.c b/builtin/stash.c index 9647b29efe8680..b54bccdd065f40 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -350,7 +350,7 @@ static int restore_untracked(struct object_id *u_tree) child_process_init(&cp); cp.git_cmd = 1; - strvec_pushl(&cp.args, "checkout-index", "--all", NULL); + strvec_pushl(&cp.args, "checkout-index", "--all", "--sparse", NULL); strvec_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); From 626751a063934ac741b90f7203fc409fe96ffd44 Mon Sep 17 00:00:00 2001 From: Victoria Dye Date: Wed, 22 Sep 2021 12:15:00 -0400 Subject: [PATCH 2/3] clean: integrate with sparse index Add repository setting to not require full index and test to verify index is not expanded in `git clean`. Existing test for `git clean` expanded to verify behavior when cleaning untracked files in sparse directories is consistent. Signed-off-by: Victoria Dye --- builtin/clean.c | 3 +++ t/t1092-sparse-checkout-compatibility.sh | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/builtin/clean.c b/builtin/clean.c index d0ec5e9963917f..92ad3148b4f5c1 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -1010,6 +1010,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix) dir.flags |= DIR_KEEP_UNTRACKED_CONTENTS; } + prepare_repo_settings(the_repository); + the_repository->settings.command_requires_full_index = 0; + if (read_cache() < 0) die(_("index file corrupt")); enable_fscache(active_nr); diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 508cf99187d82b..033ef5fcc353bc 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -1068,23 +1068,42 @@ test_expect_success 'clean' ' test_all_match git commit -m "ignore bogus files" && run_on_sparse mkdir folder1 && + run_on_all mkdir -p deep/untracked-deep && run_on_all touch folder1/bogus && + run_on_all touch folder1/untracked && + run_on_all touch deep/untracked-deep/bogus && + run_on_all touch deep/untracked-deep/untracked && test_all_match git status --porcelain=v2 && test_all_match git clean -f && test_all_match git status --porcelain=v2 && test_sparse_match ls && test_sparse_match ls folder1 && + run_on_all test_path_exists folder1/bogus && + run_on_all test_path_is_missing folder1/untracked && + run_on_all test_path_exists deep/untracked-deep/bogus && + run_on_all test_path_exists deep/untracked-deep/untracked && + + test_all_match git clean -fd && + test_all_match git status --porcelain=v2 && + test_sparse_match ls && + test_sparse_match ls folder1 && + run_on_all test_path_exists folder1/bogus && + run_on_all test_path_exists deep/untracked-deep/bogus && + run_on_all test_path_is_missing deep/untracked-deep/untracked && test_all_match git clean -xf && test_all_match git status --porcelain=v2 && test_sparse_match ls && test_sparse_match ls folder1 && + run_on_all test_path_is_missing folder1/bogus && + run_on_all test_path_exists deep/untracked-deep/bogus && test_all_match git clean -xdf && test_all_match git status --porcelain=v2 && test_sparse_match ls && test_sparse_match ls folder1 && + run_on_all test_path_is_missing deep/untracked-deep/bogus && test_sparse_match test_path_is_dir folder1 ' @@ -1202,6 +1221,8 @@ test_expect_success 'sparse-index is not expanded' ' git -C sparse-index add README.md && ensure_not_expanded diff --staged && + ensure_not_expanded clean -fd && + ensure_not_expanded checkout -f update-deep && ( sane_unset GIT_TEST_MERGE_ALGORITHM && From 0c0633935a4c278a5528884fb745886eb32a7c3c Mon Sep 17 00:00:00 2001 From: Victoria Dye Date: Wed, 22 Sep 2021 14:02:21 -0400 Subject: [PATCH 3/3] stash: expand testing for `git stash -u` Test cases specific to handling untracked files in `git stash` a) ensure that files outside the sparse checkout definition are handled as-expected and b) document the index expansion inside of `git stash -u`. Note that, in b), it is not the full repository index that is expanded - it is the temporary, standalone index containing the stashed untracked files only. Signed-off-by: Victoria Dye --- t/perf/p2000-sparse-operations.sh | 1 + t/t1092-sparse-checkout-compatibility.sh | 40 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh index 92a2fbdfbf9e37..1259d22222b5cd 100755 --- a/t/perf/p2000-sparse-operations.sh +++ b/t/perf/p2000-sparse-operations.sh @@ -107,6 +107,7 @@ test_perf_on_all () { test_perf_on_all git status test_perf_on_all 'git stash && git stash pop' +test_perf_on_all 'echo >>new && git stash -u && git stash pop' test_perf_on_all git add -A test_perf_on_all git add . test_perf_on_all git commit -a -m A diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 033ef5fcc353bc..bd2e54f259e545 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -1301,6 +1301,46 @@ test_expect_success 'sparse index is not expanded: read-tree' ' ensure_not_expanded read-tree --prefix=deep/deeper2 -u deepest ' +# NEEDSWORK: although the full repository's index is _not_ expanded as part of +# stash, a temporary index, which is _not_ sparse, is created when stashing and +# applying a stash of untracked files. As a result, the test reports that it +# finds an instance of `ensure_full_index`, but it does not carry with it the +# performance implications of expanding the full repository index. +test_expect_success 'sparse index is not expanded: stash -u' ' + init_repos && + + mkdir -p sparse-index/folder1 && + echo >>sparse-index/README.md && + echo >>sparse-index/a && + echo >>sparse-index/folder1/new && + + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \ + git -C sparse-index stash -u && + test_region index ensure_full_index trace2.txt && + + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \ + git -C sparse-index stash pop && + test_region index ensure_full_index trace2.txt +' + +# NEEDSWORK: similar to `git add`, untracked files outside of the sparse +# checkout definition are successfully stashed and unstashed. +test_expect_success 'stash -u outside sparse checkout definition' ' + init_repos && + + write_script edit-contents <<-\EOF && + echo text >>$1 + EOF + + run_on_sparse mkdir -p folder1 && + run_on_all ../edit-contents folder1/new && + test_all_match git stash -u && + test_all_match git status --porcelain=v2 && + + test_all_match git stash pop -q && + test_all_match git status --porcelain=v2 +' + # NEEDSWORK: a sparse-checkout behaves differently from a full checkout # in this scenario, but it shouldn't. test_expect_success 'reset mixed and checkout orphan' '