Skip to content

Commit 9802479

Browse files
committed
Sparse index: git diff
This change enables running the `diff` builtin command without expanding the full index in a cone-mode sparse checkout. It adds basic infrastructure to "light up" sparse index for this command. Additionally, it includes tests to verify sparse index is working as expected. These tests ensure that: 1. The index is not expanded for `diff` and `diff --staged` (which both involve reading from the index). 2. `diff` and `diff --staged` behave the same in full checkout, sparse checkout, and sparse index repositories in the following partially-staged scenarios (i.e. the index, HEAD, and working directory differ at a given path): 1. Path is within sparse-checkout cone. 2. Path is outside sparse-checkout cone. 3. Merge conflict for paths outside sparse-checkout cone.
1 parent f28fc01 commit 9802479

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

builtin/diff.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
437437

438438
prefix = setup_git_directory_gently(&nongit);
439439

440+
prepare_repo_settings(the_repository);
441+
the_repository->settings.command_requires_full_index = 0;
442+
440443
if (!no_index) {
441444
/*
442445
* Treat git diff with at least one path outside of the

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,55 @@ test_expect_success 'diff --staged' '
387387
test_all_match git diff --staged
388388
'
389389

390+
test_expect_success 'diff partially-staged' '
391+
init_repos &&
392+
393+
write_script add-file-in-cone <<-\EOF &&
394+
git sparse-checkout set deep
395+
echo >deep/testfile
396+
git add deep/testfile
397+
echo a new line >>deep/testfile
398+
EOF
399+
run_on_all ../add-file-in-cone &&
400+
401+
test_all_match git diff &&
402+
test_all_match git diff --staged &&
403+
404+
write_script add-file-outside-cone <<-\EOF &&
405+
git reset --hard
406+
mkdir newdirectory
407+
echo >newdirectory/testfile
408+
git sparse-checkout set newdirectory
409+
git add newdirectory/testfile
410+
echo a new line >>newdirectory/testfile
411+
git sparse-checkout set
412+
EOF
413+
run_on_all ../add-file-outside-cone &&
414+
415+
test_all_match git diff &&
416+
test_all_match git diff --staged &&
417+
418+
write_script merge-conflict-outside-cone <<-\EOF &&
419+
git reset --hard
420+
for side in left right
421+
do
422+
git checkout -b merge-$side base &&
423+
git sparse-checkout set deep folder1 folder2
424+
echo $side >>deep/deeper2/a &&
425+
echo $side >>folder1/a &&
426+
echo $side >>folder2/a &&
427+
git add . &&
428+
git commit -m "$side" || return 1
429+
git sparse-checkout set
430+
done
431+
git merge merge-left
432+
EOF
433+
run_on_all ../merge-conflict-outside-cone &&
434+
435+
test_all_match git diff &&
436+
test_all_match git diff --staged
437+
'
438+
390439
# NEEDSWORK: sparse-checkout behaves differently from full-checkout when
391440
# running this test with 'df-conflict-2' after 'df-conflict-1'.
392441
test_expect_success 'diff with renames and conflicts' '
@@ -822,6 +871,12 @@ test_expect_success 'sparse-index is not expanded' '
822871
ensure_not_expanded reset base -- folder1 &&
823872
824873
ensure_not_expanded reset --hard update-deep &&
874+
875+
echo a test change >> sparse-index/README.md &&
876+
ensure_not_expanded diff &&
877+
git -C sparse-index add README.md &&
878+
ensure_not_expanded diff --staged &&
879+
825880
ensure_not_expanded checkout -f update-deep &&
826881
(
827882
sane_unset GIT_TEST_MERGE_ALGORITHM &&

0 commit comments

Comments
 (0)