diff-files: integrate with sparse index

Remove full index requirement for `git diff-files`. Refactor the ensure_expanded and ensure_not_expanded functions by introducing a common helper function, ensure_index_state. Add test to ensure the index is no expanded in `git diff-files`. The `p2000` tests demonstrate a ~96% execution time reduction for 'git diff-files' and a ~97% execution time reduction for 'git diff-files' for a file using a sparse index: Test before after ----------------------------------------------------------------------- 2000.94: git diff-files (full-v3) 0.09 0.08 -11.1% 2000.95: git diff-files (full-v4) 0.09 0.09 +0.0% 2000.96: git diff-files (sparse-v3) 0.52 0.02 -96.2% 2000.97: git diff-files (sparse-v4) 0.51 0.02 -96.1% 2000.98: git diff-files -- f2/f4/a (full-v3) 0.06 0.07 +16.7% 2000.99: git diff-files -- f2/f4/a (full-v4) 0.08 0.08 +0.0% 2000.100: git diff-files -- f2/f4/a (sparse-v3) 0.46 0.01 -97.8% 2000.101: git diff-files -- f2/f4/a (sparse-v4) 0.51 0.02 -96.1% Signed-off-by: Shuqi Liang <cheskaqiqi@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Shuqi Liang committed May 9, 2023 at 15:42 UTC 8c30be9176784b5e4fbfc2ca6e8275c13cbf6e4a
3 files changed +31 -2
builtin/diff-files.c
+4
@@ -27,6 +27,10 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
27 usage(diff_files_usage);
28
29 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
30 +
31 + prepare_repo_settings(the_repository);
32 + the_repository->settings.command_requires_full_index = 0;
33 +
34 repo_init_revisions(the_repository, &rev, prefix);
35 rev.abbrev = 0;
36
t/perf/p2000-sparse-operations.sh
+2
@@ -129,5 +129,7 @@ test_perf_on_all git grep --cached bogus -- "f2/f1/f1/*"
129 test_perf_on_all git write-tree
130 test_perf_on_all git describe --dirty
131 test_perf_on_all 'echo >>new && git describe --dirty'
132 +test_perf_on_all git diff-files
133 +test_perf_on_all git diff-files -- $SPARSE_CONE/a
134
135 test_done
t/t1092-sparse-checkout-compatibility.sh
+25 -2
@@ -1377,7 +1377,7 @@ test_expect_success 'index.sparse disabled inline uses full index' '
1377 ! test_region index ensure_full_index trace2.txt
1378 '
1379
1380 -ensure_not_expanded () {
1380 +run_sparse_index_trace2 () {
1381 rm -f trace2.txt &&
1382 if test -z "$WITHOUT_UNTRACKED_TXT"
1383 then
@@ -1397,7 +1397,16 @@ ensure_not_expanded () {
1397 git -C sparse-index "$@" \
1398 >sparse-index-out \
1399 2>sparse-index-error || return 1
1400 - fi &&
1400 + fi
1401 +}
1402 +
1403 +ensure_expanded () {
1404 + run_sparse_index_trace2 "$@" &&
1405 + test_region index ensure_full_index trace2.txt
1406 +}
1407 +
1408 +ensure_not_expanded () {
1409 + run_sparse_index_trace2 "$@" &&
1410 test_region ! index ensure_full_index trace2.txt
1411 }
1412
@@ -2147,4 +2156,18 @@ test_expect_success 'diff-files with pathspec outside sparse definition' '
2156 test_all_match git diff-files -- "folder*/a"
2157 '
2158
2159 +test_expect_success 'sparse index is not expanded: diff-files' '
2160 + init_repos &&
2161 +
2162 + write_script edit-contents <<-\EOF &&
2163 + echo text >>"$1"
2164 + EOF
2165 +
2166 + run_on_all ../edit-contents deep/a &&
2167 +
2168 + ensure_not_expanded diff-files &&
2169 + ensure_not_expanded diff-files -- deep/a &&
2170 + ensure_not_expanded diff-files -- "deep/*"
2171 +'
2172 +
2173 test_done