From 54ea0984e9498eb01524de3d67b599e6c61b3643 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Thu, 22 Aug 2024 10:58:56 -0400 Subject: [PATCH] diff-index: integrate with the sparse index The sparse index allows focusing the index data structure on the files present in the sparse-checkout, leaving only tree entries for directories not within the sparse-checkout. Each builtin needs a repository setting to indicate that it has been tested with the sparse index before Git will allow the index to be loaded into memory in its sparse form. This is a safety precaution. There are still some builtins that haven't been integrated due to the complexity of the integration and the lack of significant use. However, 'git diff-index' was neglected only because of initial data showing low usage. The diff machinery was already integrated and there is no more work to be done there but add some tests to be sure 'git diff-index' behaves as expected. For this purpose, we can follow the testing pattern used in 51ba65b5c35 (diff: enable and test the sparse index, 2021-12-06). One difference here is that we only verify that the sparse index case agrees with the full index case, but do not generate the expected output. The 'git diff' tests use the '--name-status' option to ease the creation of the expected output, but that's not an option for 'diff-index'. Since the underlying diff machinery is the same, a simple comparison is sufficient to give some coverage. Signed-off-by: Derrick Stolee --- builtin/diff-index.c | 4 ++ t/t1092-sparse-checkout-compatibility.sh | 54 +++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 3e05260ac0e040..685b60284fd9e7 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -25,6 +25,10 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) usage(diff_cache_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + + prepare_repo_settings(the_repository); + the_repository->settings.command_requires_full_index = 0; + repo_init_revisions(the_repository, &rev, prefix); rev.abbrev = 0; prefix = precompose_argv_prefix(argc, argv, prefix); diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index a2c0e1b4dcc564..2164bfe74d24a8 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -803,6 +803,8 @@ test_expect_success 'update-index --remove outside sparse definition' ' test_sparse_match git diff --cached --name-status && test_cmp expect sparse-checkout-out && + test_sparse_match git diff-index --cached HEAD && + # Reset the state test_all_match git reset --hard && @@ -812,6 +814,8 @@ test_expect_success 'update-index --remove outside sparse definition' ' test_sparse_match git diff --cached --name-status && test_must_be_empty sparse-checkout-out && + test_sparse_match git diff-index --cached HEAD && + # Reset the state test_all_match git reset --hard && @@ -823,7 +827,9 @@ test_expect_success 'update-index --remove outside sparse definition' ' D folder1/a EOF test_sparse_match git diff --cached --name-status && - test_cmp expect sparse-checkout-out + test_cmp expect sparse-checkout-out && + + test_sparse_match git diff-index --cached HEAD ' test_expect_success 'update-index with directories' ' @@ -1597,6 +1603,52 @@ test_expect_success 'sparse index is not expanded: diff' ' ensure_not_expanded diff --cached ' +test_expect_success 'sparse index is not expanded: diff-index' ' + init_repos && + + write_script edit-contents <<-\EOF && + echo text >>$1 + EOF + + # Add file within cone + test_sparse_match git sparse-checkout set deep && + run_on_all ../edit-contents deep/testfile && + test_all_match git add deep/testfile && + run_on_all ../edit-contents deep/testfile && + + test_all_match git diff-index HEAD && + test_all_match git diff-index --cached HEAD && + ensure_not_expanded diff-index HEAD && + ensure_not_expanded diff-index --cached HEAD && + + # Add file outside cone + test_all_match git reset --hard && + run_on_all mkdir newdirectory && + run_on_all ../edit-contents newdirectory/testfile && + test_sparse_match git sparse-checkout set newdirectory && + test_all_match git add newdirectory/testfile && + run_on_all ../edit-contents newdirectory/testfile && + test_sparse_match git sparse-checkout set && + + test_all_match git diff-index HEAD && + test_all_match git diff-index --cached HEAD && + ensure_not_expanded diff-index HEAD && + ensure_not_expanded diff-index --cached HEAD && + + # Merge conflict outside cone + # The sparse checkout will report a warning that is not in the + # full checkout, so we use `run_on_all` instead of + # `test_all_match` + run_on_all git reset --hard && + test_all_match git checkout merge-left && + test_all_match test_must_fail git merge merge-right && + + test_all_match git diff-index HEAD && + test_all_match git diff-index --cached HEAD && + ensure_not_expanded diff-index HEAD && + ensure_not_expanded diff-index --cached HEAD +' + test_expect_success 'sparse index is not expanded: show and rev-parse' ' init_repos &&