@@ -95,6 +95,25 @@ test_expect_success 'setup' '
95
95
git add . &&
96
96
git commit -m "rename deep/deeper1/... to folder1/..." &&
97
97
98
+ git checkout -b df-conflict-1 base &&
99
+ rm -rf folder1 &&
100
+ echo content >folder1 &&
101
+ git add . &&
102
+ git commit -m "dir to file" &&
103
+
104
+ git checkout -b df-conflict-2 base &&
105
+ rm -rf folder2 &&
106
+ echo content >folder2 &&
107
+ git add . &&
108
+ git commit -m "dir to file" &&
109
+
110
+ git checkout -b fd-conflict base &&
111
+ rm a &&
112
+ mkdir a &&
113
+ echo content >a/a &&
114
+ git add . &&
115
+ git commit -m "file to dir" &&
116
+
98
117
git checkout -b deepest base &&
99
118
echo "updated deepest" >deep/deeper1/deepest/a &&
100
119
git commit -a -m "update deepest" &&
@@ -262,6 +281,34 @@ test_expect_success 'add, commit, checkout' '
262
281
test_all_match git checkout -
263
282
'
264
283
284
+ test_expect_success ' commit including unstaged changes' '
285
+ init_repos &&
286
+
287
+ write_script edit-file <<-\EOF &&
288
+ echo $1 >$2
289
+ EOF
290
+
291
+ run_on_all ../edit-file 1 a &&
292
+ run_on_all ../edit-file 1 deep/a &&
293
+
294
+ test_all_match git commit -m "-a" -a &&
295
+ test_all_match git status --porcelain=v2 &&
296
+
297
+ run_on_all ../edit-file 2 a &&
298
+ run_on_all ../edit-file 2 deep/a &&
299
+
300
+ test_all_match git commit -m "--include" --include deep/a &&
301
+ test_all_match git status --porcelain=v2 &&
302
+ test_all_match git commit -m "--include" --include a &&
303
+ test_all_match git status --porcelain=v2 &&
304
+
305
+ run_on_all ../edit-file 3 a &&
306
+ run_on_all ../edit-file 3 deep/a &&
307
+
308
+ test_all_match git commit -m "--amend" -a --amend &&
309
+ test_all_match git status --porcelain=v2
310
+ '
311
+
265
312
test_expect_success ' status/add: outside sparse cone' '
266
313
init_repos &&
267
314
@@ -330,10 +377,16 @@ test_expect_success 'diff --staged' '
330
377
test_all_match git diff --staged
331
378
'
332
379
380
+ # NEEDSWORK: sparse-checkout behaves differently from full-checkout when
381
+ # running this test with 'df-conflict-2' after 'df-conflict-1'.
333
382
test_expect_success ' diff with renames and conflicts' '
334
383
init_repos &&
335
384
336
- for branch in rename-out-to-out rename-out-to-in rename-in-to-out
385
+ for branch in rename-out-to-out \
386
+ rename-out-to-in \
387
+ rename-in-to-out \
388
+ df-conflict-1 \
389
+ fd-conflict
337
390
do
338
391
test_all_match git checkout rename-base &&
339
392
test_all_match git checkout $branch -- . &&
@@ -346,7 +399,12 @@ test_expect_success 'diff with renames and conflicts' '
346
399
test_expect_success ' diff with directory/file conflicts' '
347
400
init_repos &&
348
401
349
- for branch in rename-out-to-out rename-out-to-in rename-in-to-out
402
+ for branch in rename-out-to-out \
403
+ rename-out-to-in \
404
+ rename-in-to-out \
405
+ df-conflict-1 \
406
+ df-conflict-2 \
407
+ fd-conflict
350
408
do
351
409
git -C full-checkout reset --hard &&
352
410
test_sparse_match git reset --hard &&
@@ -514,14 +572,33 @@ test_expect_success 'sparse-index is expanded and converted back' '
514
572
test_region index ensure_full_index trace2.txt
515
573
'
516
574
517
- test_expect_success ' sparse-index is not expanded' '
518
- init_repos &&
519
-
575
+ ensure_not_expanded () {
520
576
rm -f trace2.txt &&
521
577
echo >> sparse-index/untracked.txt &&
522
578
GIT_TRACE2_EVENT=" $( pwd) /trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
523
- git -C sparse-index status &&
579
+ git -C sparse-index " $@ " &&
524
580
test_region ! index ensure_full_index trace2.txt
581
+ }
582
+
583
+ test_expect_success ' sparse-index is not expanded' '
584
+ init_repos &&
585
+
586
+ ensure_not_expanded status &&
587
+ ensure_not_expanded commit --allow-empty -m empty &&
588
+ echo >>sparse-index/a &&
589
+ ensure_not_expanded commit -a -m a &&
590
+ echo >>sparse-index/a &&
591
+ ensure_not_expanded commit --include a -m a &&
592
+ echo >>sparse-index/deep/deeper1/a &&
593
+ ensure_not_expanded commit --include deep/deeper1/a -m deeper &&
594
+ ensure_not_expanded checkout rename-out-to-out &&
595
+ ensure_not_expanded checkout - &&
596
+ ensure_not_expanded switch rename-out-to-out &&
597
+ ensure_not_expanded switch - &&
598
+ git -C sparse-index reset --hard &&
599
+ ensure_not_expanded checkout rename-out-to-out -- deep/deeper1 &&
600
+ git -C sparse-index reset --hard &&
601
+ ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1
525
602
'
526
603
527
604
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
@@ -559,4 +636,112 @@ test_expect_success 'add everything with deep new file' '
559
636
test_all_match git status --porcelain=v2
560
637
'
561
638
639
+ # NEEDSWORK: 'git checkout' behaves incorrectly in the case of
640
+ # directory/file conflicts, even without sparse-checkout. Use this
641
+ # test only as a documentation of the incorrect behavior, not a
642
+ # measure of how it _should_ behave.
643
+ test_expect_success ' checkout behaves oddly with df-conflict-1' '
644
+ init_repos &&
645
+
646
+ test_sparse_match git sparse-checkout disable &&
647
+
648
+ write_script edit-content <<-\EOF &&
649
+ echo content >>folder1/larger-content
650
+ git add folder1
651
+ EOF
652
+
653
+ run_on_all ../edit-content &&
654
+ test_all_match git status --porcelain=v2 &&
655
+
656
+ git -C sparse-checkout sparse-checkout init --cone &&
657
+ git -C sparse-index sparse-checkout init --cone --sparse-index &&
658
+
659
+ test_all_match git status --porcelain=v2 &&
660
+
661
+ # This checkout command should fail, because we have a staged
662
+ # change to folder1/larger-content, but the destination changes
663
+ # folder1 to a file.
664
+ git -C full-checkout checkout df-conflict-1 \
665
+ 1>full-checkout-out \
666
+ 2>full-checkout-err &&
667
+ git -C sparse-checkout checkout df-conflict-1 \
668
+ 1>sparse-checkout-out \
669
+ 2>sparse-checkout-err &&
670
+ git -C sparse-index checkout df-conflict-1 \
671
+ 1>sparse-index-out \
672
+ 2>sparse-index-err &&
673
+
674
+ # Instead, the checkout deletes the folder1 file and adds the
675
+ # folder1/larger-content file, leaving all other paths that were
676
+ # in folder1/ as deleted (without any warning).
677
+ cat >expect <<-EOF &&
678
+ D folder1
679
+ A folder1/larger-content
680
+ EOF
681
+ test_cmp expect full-checkout-out &&
682
+ test_cmp expect sparse-checkout-out &&
683
+
684
+ # The sparse-index reports no output
685
+ test_must_be_empty sparse-index-out &&
686
+
687
+ # stderr: Switched to branch df-conflict-1
688
+ test_cmp full-checkout-err sparse-checkout-err &&
689
+ test_cmp full-checkout-err sparse-checkout-err
690
+ '
691
+
692
+ # NEEDSWORK: 'git checkout' behaves incorrectly in the case of
693
+ # directory/file conflicts, even without sparse-checkout. Use this
694
+ # test only as a documentation of the incorrect behavior, not a
695
+ # measure of how it _should_ behave.
696
+ test_expect_success ' checkout behaves oddly with df-conflict-2' '
697
+ init_repos &&
698
+
699
+ test_sparse_match git sparse-checkout disable &&
700
+
701
+ write_script edit-content <<-\EOF &&
702
+ echo content >>folder2/larger-content
703
+ git add folder2
704
+ EOF
705
+
706
+ run_on_all ../edit-content &&
707
+ test_all_match git status --porcelain=v2 &&
708
+
709
+ git -C sparse-checkout sparse-checkout init --cone &&
710
+ git -C sparse-index sparse-checkout init --cone --sparse-index &&
711
+
712
+ test_all_match git status --porcelain=v2 &&
713
+
714
+ # This checkout command should fail, because we have a staged
715
+ # change to folder1/larger-content, but the destination changes
716
+ # folder1 to a file.
717
+ git -C full-checkout checkout df-conflict-2 \
718
+ 1>full-checkout-out \
719
+ 2>full-checkout-err &&
720
+ git -C sparse-checkout checkout df-conflict-2 \
721
+ 1>sparse-checkout-out \
722
+ 2>sparse-checkout-err &&
723
+ git -C sparse-index checkout df-conflict-2 \
724
+ 1>sparse-index-out \
725
+ 2>sparse-index-err &&
726
+
727
+ # The full checkout deviates from the df-conflict-1 case here!
728
+ # It drops the change to folder1/larger-content and leaves the
729
+ # folder1 path as-is on disk. The sparse-index behaves the same.
730
+ test_must_be_empty full-checkout-out &&
731
+ test_must_be_empty sparse-index-out &&
732
+
733
+ # In the sparse-checkout case, the checkout deletes the folder1
734
+ # file and adds the folder1/larger-content file, leaving all other
735
+ # paths that were in folder1/ as deleted (without any warning).
736
+ cat >expect <<-EOF &&
737
+ D folder2
738
+ A folder2/larger-content
739
+ EOF
740
+ test_cmp expect sparse-checkout-out &&
741
+
742
+ # Switched to branch df-conflict-1
743
+ test_cmp full-checkout-err sparse-checkout-err &&
744
+ test_cmp full-checkout-err sparse-index-err
745
+ '
746
+
562
747
test_done
0 commit comments