@@ -390,22 +390,26 @@ test_expect_success 'diff --staged' '
390
390
test_expect_success ' diff partially-staged' '
391
391
init_repos &&
392
392
393
+ write_script edit-contents <<-\EOF &&
394
+ echo text >>$1
395
+ EOF
396
+
393
397
# Add file within cone
394
398
test_all_match git sparse-checkout set deep &&
395
- run_on_all ' echo > deep/testfile' &&
399
+ run_on_all ../edit-contents deep/testfile &&
396
400
test_all_match git add deep/testfile &&
397
- run_on_all ' echo a new line >> deep/testfile' &&
401
+ run_on_all ../edit-contents deep/testfile &&
398
402
399
403
test_all_match git diff &&
400
404
test_all_match git diff --staged &&
401
405
402
406
# Add file outside cone
403
407
test_all_match git reset --hard &&
404
408
run_on_all mkdir newdirectory &&
405
- run_on_all ' echo > newdirectory/testfile' &&
409
+ run_on_all ../edit-contents newdirectory/testfile &&
406
410
test_all_match git sparse-checkout set newdirectory &&
407
411
test_all_match git add newdirectory/testfile &&
408
- run_on_all ' echo a new line >> newdirectory/testfile' &&
412
+ run_on_all ../edit-contents newdirectory/testfile &&
409
413
test_all_match git sparse-checkout set &&
410
414
411
415
test_all_match git diff &&
@@ -771,6 +775,117 @@ test_expect_success 'update-index --cacheinfo' '
771
775
test_sparse_match git status --porcelain=v2
772
776
'
773
777
778
+ test_expect_success ' read-tree --merge with files outside sparse definition' '
779
+ init_repos &&
780
+
781
+ test_all_match git checkout -b test-branch update-folder1 &&
782
+ for MERGE_TREES in "base HEAD update-folder2" \
783
+ "update-folder1 update-folder2" \
784
+ "update-folder2"
785
+ do
786
+ # Clean up and remove on-disk files
787
+ test_all_match git reset --hard HEAD &&
788
+ test_sparse_match git sparse-checkout reapply &&
789
+
790
+ # Although the index matches, without --no-sparse-checkout, outside-of-
791
+ # definition files will not exist on disk for sparse checkouts
792
+ test_all_match git read-tree -mu $MERGE_TREES &&
793
+ test_all_match git status --porcelain=v2 &&
794
+ test_path_is_missing sparse-checkout/folder2 &&
795
+ test_path_is_missing sparse-index/folder2 &&
796
+
797
+ test_all_match git read-tree --reset -u HEAD &&
798
+ test_all_match git status --porcelain=v2 &&
799
+
800
+ test_all_match git read-tree -mu --no-sparse-checkout $MERGE_TREES &&
801
+ test_all_match git status --porcelain=v2 &&
802
+ test_cmp sparse-checkout/folder2/a sparse-index/folder2/a &&
803
+ test_cmp sparse-checkout/folder2/a full-checkout/folder2/a || return 1
804
+ done
805
+ '
806
+
807
+ test_expect_success ' read-tree --merge with edit/edit conflicts in sparse directories' '
808
+ init_repos &&
809
+
810
+ # Merge of multiple changes to same directory (but not same files) should
811
+ # succeed
812
+ test_all_match git read-tree -mu base rename-base update-folder1 &&
813
+ test_all_match git status --porcelain=v2 &&
814
+
815
+ test_all_match git reset --hard &&
816
+
817
+ test_all_match git read-tree -mu rename-base update-folder2 &&
818
+ test_all_match git status --porcelain=v2 &&
819
+
820
+ test_all_match git reset --hard &&
821
+
822
+ test_all_match test_must_fail git read-tree -mu base update-folder1 rename-out-to-in &&
823
+ test_all_match test_must_fail git read-tree -mu rename-out-to-in update-folder1
824
+ '
825
+
826
+ test_expect_success ' read-tree --merge with modified file outside definition' '
827
+ init_repos &&
828
+
829
+ write_script edit-contents <<-\EOF &&
830
+ echo text >>$1
831
+ EOF
832
+
833
+ test_all_match git checkout -b test-branch update-folder1 &&
834
+ run_on_sparse mkdir -p folder2 &&
835
+ run_on_all ../edit-contents folder2/a &&
836
+
837
+ # With manually-modified file, full-checkout cannot merge, but it is ignored
838
+ # in sparse checkouts
839
+ test_must_fail git -C full-checkout read-tree -mu update-folder2 &&
840
+ test_sparse_match git read-tree -mu update-folder2 &&
841
+ test_sparse_match git status --porcelain=v2 &&
842
+
843
+ # Reset only the sparse checkouts to "undo" the merge. All three checkouts
844
+ # now have matching indexes and matching folder2/a on disk.
845
+ test_sparse_match git read-tree --reset -u HEAD &&
846
+
847
+ # When --no-sparse-checkout is specified, sparse checkouts identify the file
848
+ # on disk and prevent the merge
849
+ test_all_match test_must_fail git read-tree -mu --no-sparse-checkout update-folder2
850
+ '
851
+
852
+ test_expect_success ' read-tree --prefix outside sparse definition' '
853
+ init_repos &&
854
+
855
+ # Cannot read-tree --prefix with a single argument when files exist within
856
+ # prefix
857
+ test_all_match test_must_fail git read-tree --prefix=folder1/ -u update-folder1 &&
858
+
859
+ test_all_match git read-tree --prefix=folder2/0 -u rename-base &&
860
+ test_path_is_missing sparse-checkout/folder2 &&
861
+ test_path_is_missing sparse-index/folder2 &&
862
+
863
+ test_all_match git read-tree --reset -u HEAD &&
864
+ test_all_match git read-tree --prefix=folder2/0 -u --no-sparse-checkout rename-base &&
865
+ test_cmp sparse-checkout/folder2/0/a sparse-index/folder2/0/a &&
866
+ test_cmp sparse-checkout/folder2/0/a full-checkout/folder2/0/a
867
+ '
868
+
869
+ test_expect_success ' read-tree --merge with directory-file conflicts' '
870
+ init_repos &&
871
+
872
+ test_all_match git checkout -b test-branch rename-base &&
873
+
874
+ # Although the index matches, without --no-sparse-checkout, outside-of-
875
+ # definition files will not exist on disk for sparse checkouts
876
+ test_sparse_match git read-tree -mu rename-out-to-out &&
877
+ test_sparse_match git status --porcelain=v2 &&
878
+ test_path_is_missing sparse-checkout/folder2 &&
879
+ test_path_is_missing sparse-index/folder2 &&
880
+
881
+ test_sparse_match git read-tree --reset -u HEAD &&
882
+ test_sparse_match git status --porcelain=v2 &&
883
+
884
+ test_sparse_match git read-tree -mu --no-sparse-checkout rename-out-to-out &&
885
+ test_sparse_match git status --porcelain=v2 &&
886
+ test_cmp sparse-checkout/folder2/0/1 sparse-index/folder2/0/1
887
+ '
888
+
774
889
test_expect_success ' merge, cherry-pick, and rebase' '
775
890
init_repos &&
776
891
@@ -995,7 +1110,7 @@ test_expect_success 'sparse-index is expanded and converted back' '
995
1110
init_repos &&
996
1111
997
1112
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
998
- git -C sparse-index -c core.fsmonitor="" read-tree -mu HEAD &&
1113
+ git -C sparse-index -c core.fsmonitor="" mv a b &&
999
1114
test_region index convert_to_sparse trace2.txt &&
1000
1115
test_region index ensure_full_index trace2.txt
1001
1116
'
@@ -1050,7 +1165,7 @@ test_expect_success 'sparse-index is not expanded' '
1050
1165
do
1051
1166
echo >>sparse-index/README.md &&
1052
1167
ensure_not_expanded reset --mixed $ref
1053
- ensure_not_expanded reset --hard $ref
1168
+ ensure_not_expanded reset --hard $ref || return 1
1054
1169
done &&
1055
1170
1056
1171
ensure_not_expanded reset --hard update-deep &&
@@ -1135,6 +1250,23 @@ test_expect_success 'sparse index is not expanded: update-index' '
1135
1250
ensure_not_expanded update-index --add --remove --again
1136
1251
'
1137
1252
1253
+ test_expect_success ' sparse index is not expanded: read-tree' '
1254
+ init_repos &&
1255
+
1256
+ ensure_not_expanded checkout -b test-branch update-folder1 &&
1257
+ for MERGE_TREES in "update-folder2"
1258
+ do
1259
+ ensure_not_expanded read-tree -mu $MERGE_TREES &&
1260
+ ensure_not_expanded reset --hard HEAD || return 1
1261
+ done &&
1262
+
1263
+ rm -rf sparse-index/deep/deeper2 &&
1264
+ ensure_not_expanded add . &&
1265
+ ensure_not_expanded commit -m "test" &&
1266
+
1267
+ ensure_not_expanded read-tree --prefix=deep/deeper2 -u deepest
1268
+ '
1269
+
1138
1270
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
1139
1271
# in this scenario, but it shouldn't.
1140
1272
test_expect_success ' reset mixed and checkout orphan' '
0 commit comments