t4015: prefer --color to -c color.diff=always
[git.git] / t / t4015-diff-whitespace.sh
blob94597ff284da22ac55f0bfd6bc00434e5df7d40b
1 #!/bin/sh
3 # Copyright (c) 2006 Johannes E. Schindelin
6 test_description='Test special whitespace in diff engine.
9 . ./test-lib.sh
10 . "$TEST_DIRECTORY"/diff-lib.sh
12 test_expect_success "Ray Lehtiniemi's example" '
13 cat <<-\EOF >x &&
14 do {
15 nothing;
16 } while (0);
17 EOF
18 git update-index --add x &&
20 cat <<-\EOF >x &&
23 nothing;
25 while (0);
26 EOF
28 cat <<-\EOF >expect &&
29 diff --git a/x b/x
30 index adf3937..6edc172 100644
31 --- a/x
32 +++ b/x
33 @@ -1,3 +1,5 @@
34 -do {
35 +do
37 nothing;
38 -} while (0);
40 +while (0);
41 EOF
43 git diff >out &&
44 test_cmp expect out &&
46 git diff -w >out &&
47 test_cmp expect out &&
49 git diff -b >out &&
50 test_cmp expect out
53 test_expect_success 'another test, without options' '
54 tr Q "\015" <<-\EOF >x &&
55 whitespace at beginning
56 whitespace change
57 whitespace in the middle
58 whitespace at end
59 unchanged line
60 CR at endQ
61 EOF
63 git update-index x &&
65 tr "_" " " <<-\EOF >x &&
66 _ whitespace at beginning
67 whitespace change
68 white space in the middle
69 whitespace at end__
70 unchanged line
71 CR at end
72 EOF
74 tr "Q_" "\015 " <<-\EOF >expect &&
75 diff --git a/x b/x
76 index d99af23..22d9f73 100644
77 --- a/x
78 +++ b/x
79 @@ -1,6 +1,6 @@
80 -whitespace at beginning
81 -whitespace change
82 -whitespace in the middle
83 -whitespace at end
84 + whitespace at beginning
85 +whitespace change
86 +white space in the middle
87 +whitespace at end__
88 unchanged line
89 -CR at endQ
90 +CR at end
91 EOF
93 git diff >out &&
94 test_cmp expect out &&
96 >expect &&
97 git diff -w >out &&
98 test_cmp expect out &&
100 git diff -w -b >out &&
101 test_cmp expect out &&
103 git diff -w --ignore-space-at-eol >out &&
104 test_cmp expect out &&
106 git diff -w -b --ignore-space-at-eol >out &&
107 test_cmp expect out &&
110 tr "Q_" "\015 " <<-\EOF >expect &&
111 diff --git a/x b/x
112 index d99af23..22d9f73 100644
113 --- a/x
114 +++ b/x
115 @@ -1,6 +1,6 @@
116 -whitespace at beginning
117 +_ whitespace at beginning
118 whitespace change
119 -whitespace in the middle
120 +white space in the middle
121 whitespace at end__
122 unchanged line
123 CR at end
125 git diff -b >out &&
126 test_cmp expect out &&
128 git diff -b --ignore-space-at-eol >out &&
129 test_cmp expect out &&
131 tr "Q_" "\015 " <<-\EOF >expect &&
132 diff --git a/x b/x
133 index d99af23..22d9f73 100644
134 --- a/x
135 +++ b/x
136 @@ -1,6 +1,6 @@
137 -whitespace at beginning
138 -whitespace change
139 -whitespace in the middle
140 +_ whitespace at beginning
141 +whitespace change
142 +white space in the middle
143 whitespace at end__
144 unchanged line
145 CR at end
147 git diff --ignore-space-at-eol >out &&
148 test_cmp expect out
151 test_expect_success 'ignore-blank-lines: only new lines' '
152 test_seq 5 >x &&
153 git update-index x &&
154 test_seq 5 | sed "/3/i\\
155 " >x &&
156 git diff --ignore-blank-lines >out &&
157 >expect &&
158 test_cmp out expect
161 test_expect_success 'ignore-blank-lines: only new lines with space' '
162 test_seq 5 >x &&
163 git update-index x &&
164 test_seq 5 | sed "/3/i\\
165 " >x &&
166 git diff -w --ignore-blank-lines >out &&
167 >expect &&
168 test_cmp out expect
171 test_expect_success 'ignore-blank-lines: after change' '
172 cat <<-\EOF >x &&
183 git update-index x &&
184 cat <<-\EOF >x &&
185 change
196 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
197 cat <<-\EOF >expected &&
198 diff --git a/x b/x
199 --- a/x
200 +++ b/x
201 @@ -1,6 +1,7 @@
202 +change
211 compare_diff_patch expected out.tmp
214 test_expect_success 'ignore-blank-lines: before change' '
215 cat <<-\EOF >x &&
225 git update-index x &&
226 cat <<-\EOF >x &&
236 change
238 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
239 cat <<-\EOF >expected &&
240 diff --git a/x b/x
241 --- a/x
242 +++ b/x
243 @@ -4,5 +4,7 @@
250 +change
252 compare_diff_patch expected out.tmp
255 test_expect_success 'ignore-blank-lines: between changes' '
256 cat <<-\EOF >x &&
270 git update-index x &&
271 cat <<-\EOF >x &&
272 change
285 change
287 git diff --ignore-blank-lines >out.tmp &&
288 cat <<-\EOF >expected &&
289 diff --git a/x b/x
290 --- a/x
291 +++ b/x
292 @@ -1,5 +1,7 @@
293 +change
300 @@ -8,5 +8,7 @@
307 +change
309 compare_diff_patch expected out.tmp
312 test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
313 test_seq 10 >x &&
314 git update-index x &&
315 cat <<-\EOF >x &&
316 change
330 change
332 git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
333 cat <<-\EOF >expected &&
334 diff --git a/x b/x
335 --- a/x
336 +++ b/x
337 @@ -1,10 +1,15 @@
338 +change
352 +change
354 compare_diff_patch expected out.tmp
357 test_expect_success 'ignore-blank-lines: scattered spaces' '
358 test_seq 10 >x &&
359 git update-index x &&
360 cat <<-\EOF >x &&
361 change
378 change
380 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
381 cat <<-\EOF >expected &&
382 diff --git a/x b/x
383 --- a/x
384 +++ b/x
385 @@ -1,3 +1,4 @@
386 +change
390 @@ -8,3 +15,4 @@
394 +change
396 compare_diff_patch expected out.tmp
399 test_expect_success 'ignore-blank-lines: spaces coalesce' '
400 test_seq 6 >x &&
401 git update-index x &&
402 cat <<-\EOF >x &&
403 change
413 change
415 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
416 cat <<-\EOF >expected &&
417 diff --git a/x b/x
418 --- a/x
419 +++ b/x
420 @@ -1,6 +1,11 @@
421 +change
431 +change
433 compare_diff_patch expected out.tmp
436 test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
437 test_seq 16 >x &&
438 git update-index x &&
439 cat <<-\EOF >x &&
440 change
447 change
455 change
462 change
464 git diff --ignore-blank-lines >out.tmp &&
465 cat <<-\EOF >expected &&
466 diff --git a/x b/x
467 --- a/x
468 +++ b/x
469 @@ -1,8 +1,11 @@
470 +change
477 +change
481 @@ -9,8 +13,11 @@
485 +change
492 +change
494 compare_diff_patch expected out.tmp
497 test_expect_success 'check mixed spaces and tabs in indent' '
498 # This is indented with SP HT SP.
499 echo " foo();" >x &&
500 git diff --check | grep "space before tab in indent"
503 test_expect_success 'check mixed tabs and spaces in indent' '
504 # This is indented with HT SP HT.
505 echo " foo();" >x &&
506 git diff --check | grep "space before tab in indent"
509 test_expect_success 'check with no whitespace errors' '
510 git commit -m "snapshot" &&
511 echo "foo();" >x &&
512 git diff --check
515 test_expect_success 'check with trailing whitespace' '
516 echo "foo(); " >x &&
517 test_must_fail git diff --check
520 test_expect_success 'check with space before tab in indent' '
521 # indent has space followed by hard tab
522 echo " foo();" >x &&
523 test_must_fail git diff --check
526 test_expect_success '--check and --exit-code are not exclusive' '
527 git checkout x &&
528 git diff --check --exit-code
531 test_expect_success '--check and --quiet are not exclusive' '
532 git diff --check --quiet
535 test_expect_success 'check staged with no whitespace errors' '
536 echo "foo();" >x &&
537 git add x &&
538 git diff --cached --check
541 test_expect_success 'check staged with trailing whitespace' '
542 echo "foo(); " >x &&
543 git add x &&
544 test_must_fail git diff --cached --check
547 test_expect_success 'check staged with space before tab in indent' '
548 # indent has space followed by hard tab
549 echo " foo();" >x &&
550 git add x &&
551 test_must_fail git diff --cached --check
554 test_expect_success 'check with no whitespace errors (diff-index)' '
555 echo "foo();" >x &&
556 git add x &&
557 git diff-index --check HEAD
560 test_expect_success 'check with trailing whitespace (diff-index)' '
561 echo "foo(); " >x &&
562 git add x &&
563 test_must_fail git diff-index --check HEAD
566 test_expect_success 'check with space before tab in indent (diff-index)' '
567 # indent has space followed by hard tab
568 echo " foo();" >x &&
569 git add x &&
570 test_must_fail git diff-index --check HEAD
573 test_expect_success 'check staged with no whitespace errors (diff-index)' '
574 echo "foo();" >x &&
575 git add x &&
576 git diff-index --cached --check HEAD
579 test_expect_success 'check staged with trailing whitespace (diff-index)' '
580 echo "foo(); " >x &&
581 git add x &&
582 test_must_fail git diff-index --cached --check HEAD
585 test_expect_success 'check staged with space before tab in indent (diff-index)' '
586 # indent has space followed by hard tab
587 echo " foo();" >x &&
588 git add x &&
589 test_must_fail git diff-index --cached --check HEAD
592 test_expect_success 'check with no whitespace errors (diff-tree)' '
593 echo "foo();" >x &&
594 git commit -m "new commit" x &&
595 git diff-tree --check HEAD^ HEAD
598 test_expect_success 'check with trailing whitespace (diff-tree)' '
599 echo "foo(); " >x &&
600 git commit -m "another commit" x &&
601 test_must_fail git diff-tree --check HEAD^ HEAD
604 test_expect_success 'check with space before tab in indent (diff-tree)' '
605 # indent has space followed by hard tab
606 echo " foo();" >x &&
607 git commit -m "yet another" x &&
608 test_must_fail git diff-tree --check HEAD^ HEAD
611 test_expect_success 'check trailing whitespace (trailing-space: off)' '
612 git config core.whitespace "-trailing-space" &&
613 echo "foo (); " >x &&
614 git diff --check
617 test_expect_success 'check trailing whitespace (trailing-space: on)' '
618 git config core.whitespace "trailing-space" &&
619 echo "foo (); " >x &&
620 test_must_fail git diff --check
623 test_expect_success 'check space before tab in indent (space-before-tab: off)' '
624 # indent contains space followed by HT
625 git config core.whitespace "-space-before-tab" &&
626 echo " foo ();" >x &&
627 git diff --check
630 test_expect_success 'check space before tab in indent (space-before-tab: on)' '
631 # indent contains space followed by HT
632 git config core.whitespace "space-before-tab" &&
633 echo " foo (); " >x &&
634 test_must_fail git diff --check
637 test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
638 git config core.whitespace "-indent-with-non-tab" &&
639 echo " foo ();" >x &&
640 git diff --check
643 test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
644 git config core.whitespace "indent-with-non-tab" &&
645 echo " foo ();" >x &&
646 test_must_fail git diff --check
649 test_expect_success 'ditto, but tabwidth=9' '
650 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
651 git diff --check
654 test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
655 git config core.whitespace "indent-with-non-tab" &&
656 echo " foo ();" >x &&
657 test_must_fail git diff --check
660 test_expect_success 'ditto, but tabwidth=10' '
661 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
662 test_must_fail git diff --check
665 test_expect_success 'ditto, but tabwidth=20' '
666 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
667 git diff --check
670 test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
671 git config core.whitespace "-tab-in-indent" &&
672 echo " foo ();" >x &&
673 git diff --check
676 test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
677 git config core.whitespace "tab-in-indent" &&
678 echo " foo ();" >x &&
679 test_must_fail git diff --check
682 test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
683 git config core.whitespace "tab-in-indent" &&
684 echo " foo ();" >x &&
685 test_must_fail git diff --check
688 test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
689 git config core.whitespace "tab-in-indent,tabwidth=1" &&
690 test_must_fail git diff --check
693 test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
694 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
695 echo "foo ();" >x &&
696 test_must_fail git diff --check
699 test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
700 git config --unset core.whitespace &&
701 echo "x whitespace" >.gitattributes &&
702 echo " foo ();" >x &&
703 git diff --check &&
704 rm -f .gitattributes
707 test_expect_success 'line numbers in --check output are correct' '
708 echo "" >x &&
709 echo "foo(); " >>x &&
710 git diff --check | grep "x:2:"
713 test_expect_success 'checkdiff detects new trailing blank lines (1)' '
714 echo "foo();" >x &&
715 echo "" >>x &&
716 git diff --check | grep "new blank line"
719 test_expect_success 'checkdiff detects new trailing blank lines (2)' '
720 { echo a; echo b; echo; echo; } >x &&
721 git add x &&
722 { echo a; echo; echo; echo; echo; } >x &&
723 git diff --check | grep "new blank line"
726 test_expect_success 'checkdiff allows new blank lines' '
727 git checkout x &&
728 mv x y &&
730 echo "/* This is new */" &&
731 echo "" &&
732 cat y
733 ) >x &&
734 git diff --check
737 cat <<EOF >expect
739 test_expect_success 'whitespace-only changes not reported' '
740 git reset --hard &&
741 echo >x "hello world" &&
742 git add x &&
743 git commit -m "hello 1" &&
744 echo >x "hello world" &&
745 git diff -b >actual &&
746 test_cmp expect actual
749 cat <<EOF >expect
750 diff --git a/x b/z
751 similarity index NUM%
752 rename from x
753 rename to z
754 index 380c32a..a97b785 100644
756 test_expect_success 'whitespace-only changes reported across renames' '
757 git reset --hard &&
758 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
759 git add x &&
760 git commit -m "base" &&
761 sed -e "5s/^/ /" x >z &&
762 git rm x &&
763 git add z &&
764 git diff -w -M --cached |
765 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual &&
766 test_cmp expect actual
769 cat >expected <<\EOF
770 diff --git a/empty b/void
771 similarity index 100%
772 rename from empty
773 rename to void
776 test_expect_success 'rename empty' '
777 git reset --hard &&
778 >empty &&
779 git add empty &&
780 git commit -m empty &&
781 git mv empty void &&
782 git diff -w --cached -M >current &&
783 test_cmp expected current
786 test_expect_success 'combined diff with autocrlf conversion' '
788 git reset --hard &&
789 echo >x hello &&
790 git commit -m "one side" x &&
791 git checkout HEAD^ &&
792 echo >x goodbye &&
793 git commit -m "the other side" x &&
794 git config core.autocrlf true &&
795 test_must_fail git merge master &&
797 git diff | sed -e "1,/^@@@/d" >actual &&
798 ! grep "^-" actual
802 # Start testing the colored format for whitespace checks
804 test_expect_success 'setup diff colors' '
805 git config color.diff always &&
806 git config color.diff.plain normal &&
807 git config color.diff.meta bold &&
808 git config color.diff.frag cyan &&
809 git config color.diff.func normal &&
810 git config color.diff.old red &&
811 git config color.diff.new green &&
812 git config color.diff.commit yellow &&
813 git config color.diff.whitespace blue &&
815 git config core.autocrlf false
818 test_expect_success 'diff that introduces a line with only tabs' '
819 git config core.whitespace blank-at-eol &&
820 git reset --hard &&
821 echo "test" >x &&
822 git commit -m "initial" x &&
823 echo "{NTN}" | tr "NT" "\n\t" >>x &&
824 git diff --color | test_decode_color >current &&
826 cat >expected <<-\EOF &&
827 <BOLD>diff --git a/x b/x<RESET>
828 <BOLD>index 9daeafb..2874b91 100644<RESET>
829 <BOLD>--- a/x<RESET>
830 <BOLD>+++ b/x<RESET>
831 <CYAN>@@ -1 +1,4 @@<RESET>
832 test<RESET>
833 <GREEN>+<RESET><GREEN>{<RESET>
834 <GREEN>+<RESET><BLUE> <RESET>
835 <GREEN>+<RESET><GREEN>}<RESET>
838 test_cmp expected current
841 test_expect_success 'diff that introduces and removes ws breakages' '
842 git reset --hard &&
844 echo "0. blank-at-eol " &&
845 echo "1. blank-at-eol "
846 } >x &&
847 git commit -a --allow-empty -m preimage &&
849 echo "0. blank-at-eol " &&
850 echo "1. still-blank-at-eol " &&
851 echo "2. and a new line "
852 } >x &&
854 git diff --color |
855 test_decode_color >current &&
857 cat >expected <<-\EOF &&
858 <BOLD>diff --git a/x b/x<RESET>
859 <BOLD>index d0233a2..700886e 100644<RESET>
860 <BOLD>--- a/x<RESET>
861 <BOLD>+++ b/x<RESET>
862 <CYAN>@@ -1,2 +1,3 @@<RESET>
863 0. blank-at-eol <RESET>
864 <RED>-1. blank-at-eol <RESET>
865 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
866 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
869 test_cmp expected current
872 test_expect_success 'ws-error-highlight test setup' '
874 git reset --hard &&
876 echo "0. blank-at-eol " &&
877 echo "1. blank-at-eol "
878 } >x &&
879 git commit -a --allow-empty -m preimage &&
881 echo "0. blank-at-eol " &&
882 echo "1. still-blank-at-eol " &&
883 echo "2. and a new line "
884 } >x &&
886 cat >expect.default-old <<-\EOF &&
887 <BOLD>diff --git a/x b/x<RESET>
888 <BOLD>index d0233a2..700886e 100644<RESET>
889 <BOLD>--- a/x<RESET>
890 <BOLD>+++ b/x<RESET>
891 <CYAN>@@ -1,2 +1,3 @@<RESET>
892 0. blank-at-eol <RESET>
893 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
894 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
895 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
898 cat >expect.all <<-\EOF &&
899 <BOLD>diff --git a/x b/x<RESET>
900 <BOLD>index d0233a2..700886e 100644<RESET>
901 <BOLD>--- a/x<RESET>
902 <BOLD>+++ b/x<RESET>
903 <CYAN>@@ -1,2 +1,3 @@<RESET>
904 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
905 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
906 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
907 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
910 cat >expect.none <<-\EOF
911 <BOLD>diff --git a/x b/x<RESET>
912 <BOLD>index d0233a2..700886e 100644<RESET>
913 <BOLD>--- a/x<RESET>
914 <BOLD>+++ b/x<RESET>
915 <CYAN>@@ -1,2 +1,3 @@<RESET>
916 0. blank-at-eol <RESET>
917 <RED>-1. blank-at-eol <RESET>
918 <GREEN>+1. still-blank-at-eol <RESET>
919 <GREEN>+2. and a new line <RESET>
924 test_expect_success 'test --ws-error-highlight option' '
926 git diff --color --ws-error-highlight=default,old |
927 test_decode_color >current &&
928 test_cmp expect.default-old current &&
930 git diff --color --ws-error-highlight=all |
931 test_decode_color >current &&
932 test_cmp expect.all current &&
934 git diff --color --ws-error-highlight=none |
935 test_decode_color >current &&
936 test_cmp expect.none current
940 test_expect_success 'test diff.wsErrorHighlight config' '
942 git -c diff.wsErrorHighlight=default,old diff --color |
943 test_decode_color >current &&
944 test_cmp expect.default-old current &&
946 git -c diff.wsErrorHighlight=all diff --color |
947 test_decode_color >current &&
948 test_cmp expect.all current &&
950 git -c diff.wsErrorHighlight=none diff --color |
951 test_decode_color >current &&
952 test_cmp expect.none current
956 test_expect_success 'option overrides diff.wsErrorHighlight' '
958 git -c diff.wsErrorHighlight=none \
959 diff --color --ws-error-highlight=default,old |
960 test_decode_color >current &&
961 test_cmp expect.default-old current &&
963 git -c diff.wsErrorHighlight=default \
964 diff --color --ws-error-highlight=all |
965 test_decode_color >current &&
966 test_cmp expect.all current &&
968 git -c diff.wsErrorHighlight=all \
969 diff --color --ws-error-highlight=none |
970 test_decode_color >current &&
971 test_cmp expect.none current
975 test_done