@@ -244,6 +244,24 @@ test_expect_success 'expanded in-memory index matches full index' '
244
244
test_sparse_match git ls-files --stage
245
245
'
246
246
247
+ test_expect_success ' root directory cannot be sparse' '
248
+ init_repos &&
249
+
250
+ # Remove all in-cone files and directories from the index, collapse index
251
+ # with `git sparse-checkout reapply`
252
+ git -C sparse-index rm -r . &&
253
+ git -C sparse-index sparse-checkout reapply &&
254
+
255
+ # Verify sparse directories still present, root directory is not sparse
256
+ cat >expect <<-EOF &&
257
+ folder1/
258
+ folder2/
259
+ x/
260
+ EOF
261
+ git -C sparse-index ls-files --sparse >actual &&
262
+ test_cmp expect actual
263
+ '
264
+
247
265
test_expect_success ' status with options' '
248
266
init_repos &&
249
267
test_sparse_match ls &&
@@ -260,6 +278,13 @@ test_expect_success 'status with options' '
260
278
test_all_match git status --porcelain=v2 -uno
261
279
'
262
280
281
+ test_expect_success ' status with diff in unexpanded sparse directory' '
282
+ init_repos &&
283
+ test_all_match git checkout rename-base &&
284
+ test_all_match git reset --soft rename-out-to-out &&
285
+ test_all_match git status --porcelain=v2
286
+ '
287
+
263
288
test_expect_success ' status reports sparse-checkout' '
264
289
init_repos &&
265
290
git -C sparse-checkout status >full &&
@@ -794,6 +819,93 @@ test_expect_success 'update-index --cacheinfo' '
794
819
test_cmp expect sparse-checkout-out
795
820
'
796
821
822
+ for MERGE_TREES in " base HEAD update-folder2" \
823
+ " update-folder1 update-folder2" \
824
+ " update-folder2"
825
+ do
826
+ test_expect_success " 'read-tree -mu $MERGE_TREES ' with files outside sparse definition" '
827
+ init_repos &&
828
+
829
+ # Although the index matches, without --no-sparse-checkout, outside-of-
830
+ # definition files will not exist on disk for sparse checkouts
831
+ test_all_match git read-tree -mu $MERGE_TREES &&
832
+ test_all_match git status --porcelain=v2 &&
833
+ test_path_is_missing sparse-checkout/folder2 &&
834
+ test_path_is_missing sparse-index/folder2 &&
835
+
836
+ test_all_match git read-tree --reset -u HEAD &&
837
+ test_all_match git status --porcelain=v2 &&
838
+
839
+ test_all_match git read-tree -mu --no-sparse-checkout $MERGE_TREES &&
840
+ test_all_match git status --porcelain=v2 &&
841
+ test_cmp sparse-checkout/folder2/a sparse-index/folder2/a &&
842
+ test_cmp sparse-checkout/folder2/a full-checkout/folder2/a
843
+
844
+ '
845
+ done
846
+
847
+ test_expect_success ' read-tree --merge with edit/edit conflicts in sparse directories' '
848
+ init_repos &&
849
+
850
+ # Merge of multiple changes to same directory (but not same files) should
851
+ # succeed
852
+ test_all_match git read-tree -mu base rename-base update-folder1 &&
853
+ test_all_match git status --porcelain=v2 &&
854
+
855
+ test_all_match git reset --hard &&
856
+
857
+ test_all_match git read-tree -mu rename-base update-folder2 &&
858
+ test_all_match git status --porcelain=v2 &&
859
+
860
+ test_all_match git reset --hard &&
861
+
862
+ test_all_match test_must_fail git read-tree -mu base update-folder1 rename-out-to-in &&
863
+ test_all_match test_must_fail git read-tree -mu rename-out-to-in update-folder1
864
+ '
865
+
866
+ test_expect_success ' read-tree --prefix' '
867
+ init_repos &&
868
+
869
+ # If files differing between the index and target <commit-ish> exist
870
+ # inside the prefix, `read-tree --prefix` should fail
871
+ test_all_match test_must_fail git read-tree --prefix=deep/ deepest &&
872
+ test_all_match test_must_fail git read-tree --prefix=folder1/ update-folder1 &&
873
+
874
+ # If no differing index entries exist matching the prefix,
875
+ # `read-tree --prefix` updates the index successfully
876
+ test_all_match git rm -rf deep/deeper1/deepest/ &&
877
+ test_all_match git read-tree --prefix=deep/deeper1/deepest -u deepest &&
878
+ test_all_match git status --porcelain=v2 &&
879
+
880
+ test_all_match git rm -rf --sparse folder1/ &&
881
+ test_all_match git read-tree --prefix=folder1/ -u update-folder1 &&
882
+ test_all_match git status --porcelain=v2 &&
883
+
884
+ test_all_match git rm -rf --sparse folder2/0 &&
885
+ test_all_match git read-tree --prefix=folder2/0/ -u rename-out-to-out &&
886
+ test_all_match git status --porcelain=v2
887
+ '
888
+
889
+ test_expect_success ' read-tree --merge with directory-file conflicts' '
890
+ init_repos &&
891
+
892
+ test_all_match git checkout -b test-branch rename-base &&
893
+
894
+ # Although the index matches, without --no-sparse-checkout, outside-of-
895
+ # definition files will not exist on disk for sparse checkouts
896
+ test_sparse_match git read-tree -mu rename-out-to-out &&
897
+ test_sparse_match git status --porcelain=v2 &&
898
+ test_path_is_missing sparse-checkout/folder2 &&
899
+ test_path_is_missing sparse-index/folder2 &&
900
+
901
+ test_sparse_match git read-tree --reset -u HEAD &&
902
+ test_sparse_match git status --porcelain=v2 &&
903
+
904
+ test_sparse_match git read-tree -mu --no-sparse-checkout rename-out-to-out &&
905
+ test_sparse_match git status --porcelain=v2 &&
906
+ test_cmp sparse-checkout/folder2/0/1 sparse-index/folder2/0/1
907
+ '
908
+
797
909
test_expect_success ' merge, cherry-pick, and rebase' '
798
910
init_repos &&
799
911
@@ -1297,6 +1409,27 @@ test_expect_success 'sparse index is not expanded: fetch/pull' '
1297
1409
ensure_not_expanded pull full base
1298
1410
'
1299
1411
1412
+ test_expect_success ' sparse index is not expanded: read-tree' '
1413
+ init_repos &&
1414
+
1415
+ ensure_not_expanded checkout -b test-branch update-folder1 &&
1416
+ for MERGE_TREES in "base HEAD update-folder2" \
1417
+ "base HEAD rename-base" \
1418
+ "base update-folder2" \
1419
+ "base rename-base" \
1420
+ "update-folder2"
1421
+ do
1422
+ ensure_not_expanded read-tree -mu $MERGE_TREES &&
1423
+ ensure_not_expanded reset --hard || return 1
1424
+ done &&
1425
+
1426
+ rm -rf sparse-index/deep/deeper2 &&
1427
+ ensure_not_expanded add . &&
1428
+ ensure_not_expanded commit -m "test" &&
1429
+
1430
+ ensure_not_expanded read-tree --prefix=deep/deeper2 -u deepest
1431
+ '
1432
+
1300
1433
test_expect_success ' ls-files' '
1301
1434
init_repos &&
1302
1435
0 commit comments