use strpbrk(3) to search for characters from a given set
[git/debian.git] / t / t4015-diff-whitespace.sh
blob88d3026894f87f4d86cb6f4178898b6879630e73
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 &&
19 old_hash_x=$(git hash-object x) &&
20 before=$(git rev-parse --short "$old_hash_x") &&
22 cat <<-\EOF >x &&
25 nothing;
27 while (0);
28 EOF
29 new_hash_x=$(git hash-object x) &&
30 after=$(git rev-parse --short "$new_hash_x") &&
32 cat <<-EOF >expect &&
33 diff --git a/x b/x
34 index $before..$after 100644
35 --- a/x
36 +++ b/x
37 @@ -1,3 +1,5 @@
38 -do {
39 +do
41 nothing;
42 -} while (0);
44 +while (0);
45 EOF
47 git diff >out &&
48 test_cmp expect out &&
50 git diff -w >out &&
51 test_cmp expect out &&
53 git diff -b >out &&
54 test_cmp expect out
57 test_expect_success 'another test, without options' '
58 tr Q "\015" <<-\EOF >x &&
59 whitespace at beginning
60 whitespace change
61 whitespace in the middle
62 whitespace at end
63 unchanged line
64 CR at endQ
65 EOF
67 git update-index x &&
68 old_hash_x=$(git hash-object x) &&
69 before=$(git rev-parse --short "$old_hash_x") &&
71 tr "_" " " <<-\EOF >x &&
72 _ whitespace at beginning
73 whitespace change
74 white space in the middle
75 whitespace at end__
76 unchanged line
77 CR at end
78 EOF
79 new_hash_x=$(git hash-object x) &&
80 after=$(git rev-parse --short "$new_hash_x") &&
82 tr "Q_" "\015 " <<-EOF >expect &&
83 diff --git a/x b/x
84 index $before..$after 100644
85 --- a/x
86 +++ b/x
87 @@ -1,6 +1,6 @@
88 -whitespace at beginning
89 -whitespace change
90 -whitespace in the middle
91 -whitespace at end
92 + whitespace at beginning
93 +whitespace change
94 +white space in the middle
95 +whitespace at end__
96 unchanged line
97 -CR at endQ
98 +CR at end
99 EOF
101 git diff >out &&
102 test_cmp expect out &&
104 git diff -w >out &&
105 test_must_be_empty out &&
107 git diff -w -b >out &&
108 test_must_be_empty out &&
110 git diff -w --ignore-space-at-eol >out &&
111 test_must_be_empty out &&
113 git diff -w -b --ignore-space-at-eol >out &&
114 test_must_be_empty out &&
116 git diff -w --ignore-cr-at-eol >out &&
117 test_must_be_empty out &&
119 tr "Q_" "\015 " <<-EOF >expect &&
120 diff --git a/x b/x
121 index $before..$after 100644
122 --- a/x
123 +++ b/x
124 @@ -1,6 +1,6 @@
125 -whitespace at beginning
126 +_ whitespace at beginning
127 whitespace change
128 -whitespace in the middle
129 +white space in the middle
130 whitespace at end__
131 unchanged line
132 CR at end
134 git diff -b >out &&
135 test_cmp expect out &&
137 git diff -b --ignore-space-at-eol >out &&
138 test_cmp expect out &&
140 git diff -b --ignore-cr-at-eol >out &&
141 test_cmp expect out &&
143 tr "Q_" "\015 " <<-EOF >expect &&
144 diff --git a/x b/x
145 index $before..$after 100644
146 --- a/x
147 +++ b/x
148 @@ -1,6 +1,6 @@
149 -whitespace at beginning
150 -whitespace change
151 -whitespace in the middle
152 +_ whitespace at beginning
153 +whitespace change
154 +white space in the middle
155 whitespace at end__
156 unchanged line
157 CR at end
159 git diff --ignore-space-at-eol >out &&
160 test_cmp expect out &&
162 git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
163 test_cmp expect out &&
165 tr "Q_" "\015 " <<-EOF >expect &&
166 diff --git a/x b/x
167 index_$before..$after 100644
168 --- a/x
169 +++ b/x
170 @@ -1,6 +1,6 @@
171 -whitespace at beginning
172 -whitespace change
173 -whitespace in the middle
174 -whitespace at end
175 +_ whitespace at beginning
176 +whitespace_ _change
177 +white space in the middle
178 +whitespace at end__
179 unchanged line
180 CR at end
182 git diff --ignore-cr-at-eol >out &&
183 test_cmp expect out
186 test_expect_success 'ignore-blank-lines: only new lines' '
187 test_seq 5 >x &&
188 git update-index x &&
189 test_seq 5 | sed "/3/i\\
190 " >x &&
191 git diff --ignore-blank-lines >out &&
192 test_must_be_empty out
195 test_expect_success 'ignore-blank-lines: only new lines with space' '
196 test_seq 5 >x &&
197 git update-index x &&
198 test_seq 5 | sed "/3/i\\
199 " >x &&
200 git diff -w --ignore-blank-lines >out &&
201 test_must_be_empty out
204 test_expect_success 'ignore-blank-lines: after change' '
205 cat <<-\EOF >x &&
216 git update-index x &&
217 cat <<-\EOF >x &&
218 change
229 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
230 cat <<-\EOF >expected &&
231 diff --git a/x b/x
232 --- a/x
233 +++ b/x
234 @@ -1,6 +1,7 @@
235 +change
244 compare_diff_patch expected out.tmp
247 test_expect_success 'ignore-blank-lines: before change' '
248 cat <<-\EOF >x &&
258 git update-index x &&
259 cat <<-\EOF >x &&
269 change
271 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
272 cat <<-\EOF >expected &&
273 diff --git a/x b/x
274 --- a/x
275 +++ b/x
276 @@ -4,5 +4,7 @@
283 +change
285 compare_diff_patch expected out.tmp
288 test_expect_success 'ignore-blank-lines: between changes' '
289 cat <<-\EOF >x &&
303 git update-index x &&
304 cat <<-\EOF >x &&
305 change
318 change
320 git diff --ignore-blank-lines >out.tmp &&
321 cat <<-\EOF >expected &&
322 diff --git a/x b/x
323 --- a/x
324 +++ b/x
325 @@ -1,5 +1,7 @@
326 +change
333 @@ -8,5 +8,7 @@
340 +change
342 compare_diff_patch expected out.tmp
345 test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
346 test_seq 10 >x &&
347 git update-index x &&
348 cat <<-\EOF >x &&
349 change
363 change
365 git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
366 cat <<-\EOF >expected &&
367 diff --git a/x b/x
368 --- a/x
369 +++ b/x
370 @@ -1,10 +1,15 @@
371 +change
385 +change
387 compare_diff_patch expected out.tmp
390 test_expect_success 'ignore-blank-lines: scattered spaces' '
391 test_seq 10 >x &&
392 git update-index x &&
393 cat <<-\EOF >x &&
394 change
411 change
413 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
414 cat <<-\EOF >expected &&
415 diff --git a/x b/x
416 --- a/x
417 +++ b/x
418 @@ -1,3 +1,4 @@
419 +change
423 @@ -8,3 +15,4 @@
427 +change
429 compare_diff_patch expected out.tmp
432 test_expect_success 'ignore-blank-lines: spaces coalesce' '
433 test_seq 6 >x &&
434 git update-index x &&
435 cat <<-\EOF >x &&
436 change
446 change
448 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
449 cat <<-\EOF >expected &&
450 diff --git a/x b/x
451 --- a/x
452 +++ b/x
453 @@ -1,6 +1,11 @@
454 +change
464 +change
466 compare_diff_patch expected out.tmp
469 test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
470 test_seq 16 >x &&
471 git update-index x &&
472 cat <<-\EOF >x &&
473 change
480 change
488 change
495 change
497 git diff --ignore-blank-lines >out.tmp &&
498 cat <<-\EOF >expected &&
499 diff --git a/x b/x
500 --- a/x
501 +++ b/x
502 @@ -1,8 +1,11 @@
503 +change
510 +change
514 @@ -9,8 +13,11 @@
518 +change
525 +change
527 compare_diff_patch expected out.tmp
530 test_expect_success 'check mixed spaces and tabs in indent' '
531 # This is indented with SP HT SP.
532 echo " foo();" >x &&
533 test_must_fail git diff --check >check &&
534 grep "space before tab in indent" check
537 test_expect_success 'check mixed tabs and spaces in indent' '
538 # This is indented with HT SP HT.
539 echo " foo();" >x &&
540 test_must_fail git diff --check >check &&
541 grep "space before tab in indent" check
544 test_expect_success 'check with no whitespace errors' '
545 git commit -m "snapshot" &&
546 echo "foo();" >x &&
547 git diff --check
550 test_expect_success 'check with trailing whitespace' '
551 echo "foo(); " >x &&
552 test_must_fail git diff --check
555 test_expect_success 'check with space before tab in indent' '
556 # indent has space followed by hard tab
557 echo " foo();" >x &&
558 test_must_fail git diff --check
561 test_expect_success '--check and --exit-code are not exclusive' '
562 git checkout x &&
563 git diff --check --exit-code
566 test_expect_success '--check and --quiet are not exclusive' '
567 git diff --check --quiet
570 test_expect_success 'check staged with no whitespace errors' '
571 echo "foo();" >x &&
572 git add x &&
573 git diff --cached --check
576 test_expect_success 'check staged with trailing whitespace' '
577 echo "foo(); " >x &&
578 git add x &&
579 test_must_fail git diff --cached --check
582 test_expect_success 'check staged with space before tab in indent' '
583 # indent has space followed by hard tab
584 echo " foo();" >x &&
585 git add x &&
586 test_must_fail git diff --cached --check
589 test_expect_success 'check with no whitespace errors (diff-index)' '
590 echo "foo();" >x &&
591 git add x &&
592 git diff-index --check HEAD
595 test_expect_success 'check with trailing whitespace (diff-index)' '
596 echo "foo(); " >x &&
597 git add x &&
598 test_must_fail git diff-index --check HEAD
601 test_expect_success 'check with space before tab in indent (diff-index)' '
602 # indent has space followed by hard tab
603 echo " foo();" >x &&
604 git add x &&
605 test_must_fail git diff-index --check HEAD
608 test_expect_success 'check staged with no whitespace errors (diff-index)' '
609 echo "foo();" >x &&
610 git add x &&
611 git diff-index --cached --check HEAD
614 test_expect_success 'check staged with trailing whitespace (diff-index)' '
615 echo "foo(); " >x &&
616 git add x &&
617 test_must_fail git diff-index --cached --check HEAD
620 test_expect_success 'check staged with space before tab in indent (diff-index)' '
621 # indent has space followed by hard tab
622 echo " foo();" >x &&
623 git add x &&
624 test_must_fail git diff-index --cached --check HEAD
627 test_expect_success 'check with no whitespace errors (diff-tree)' '
628 echo "foo();" >x &&
629 git commit -m "new commit" x &&
630 git diff-tree --check HEAD^ HEAD
633 test_expect_success 'check with trailing whitespace (diff-tree)' '
634 echo "foo(); " >x &&
635 git commit -m "another commit" x &&
636 test_must_fail git diff-tree --check HEAD^ HEAD
639 test_expect_success 'check with space before tab in indent (diff-tree)' '
640 # indent has space followed by hard tab
641 echo " foo();" >x &&
642 git commit -m "yet another" x &&
643 test_must_fail git diff-tree --check HEAD^ HEAD
646 test_expect_success 'check with ignored trailing whitespace attr (diff-tree)' '
647 test_when_finished "git reset --hard HEAD^" &&
649 # create a whitespace error that should be ignored
650 echo "* -whitespace" >.gitattributes &&
651 git add .gitattributes &&
652 echo "foo(); " >x &&
653 git add x &&
654 git commit -m "add trailing space" &&
656 # with a worktree diff-tree ignores the whitespace error
657 git diff-tree --root --check HEAD &&
659 # without a worktree diff-tree still ignores the whitespace error
660 git -C .git diff-tree --root --check HEAD
663 test_expect_success 'check trailing whitespace (trailing-space: off)' '
664 git config core.whitespace "-trailing-space" &&
665 echo "foo (); " >x &&
666 git diff --check
669 test_expect_success 'check trailing whitespace (trailing-space: on)' '
670 git config core.whitespace "trailing-space" &&
671 echo "foo (); " >x &&
672 test_must_fail git diff --check
675 test_expect_success 'check space before tab in indent (space-before-tab: off)' '
676 # indent contains space followed by HT
677 git config core.whitespace "-space-before-tab" &&
678 echo " foo ();" >x &&
679 git diff --check
682 test_expect_success 'check space before tab in indent (space-before-tab: on)' '
683 # indent contains space followed by HT
684 git config core.whitespace "space-before-tab" &&
685 echo " foo (); " >x &&
686 test_must_fail git diff --check
689 test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
690 git config core.whitespace "-indent-with-non-tab" &&
691 echo " foo ();" >x &&
692 git diff --check
695 test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
696 git config core.whitespace "indent-with-non-tab" &&
697 echo " foo ();" >x &&
698 test_must_fail git diff --check
701 test_expect_success 'ditto, but tabwidth=9' '
702 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
703 git diff --check
706 test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
707 git config core.whitespace "indent-with-non-tab" &&
708 echo " foo ();" >x &&
709 test_must_fail git diff --check
712 test_expect_success 'ditto, but tabwidth=10' '
713 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
714 test_must_fail git diff --check
717 test_expect_success 'ditto, but tabwidth=20' '
718 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
719 git diff --check
722 test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
723 git config core.whitespace "-tab-in-indent" &&
724 echo " foo ();" >x &&
725 git diff --check
728 test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
729 git config core.whitespace "tab-in-indent" &&
730 echo " foo ();" >x &&
731 test_must_fail git diff --check
734 test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
735 git config core.whitespace "tab-in-indent" &&
736 echo " foo ();" >x &&
737 test_must_fail git diff --check
740 test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
741 git config core.whitespace "tab-in-indent,tabwidth=1" &&
742 test_must_fail git diff --check
745 test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
746 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
747 echo "foo ();" >x &&
748 test_must_fail git diff --check
751 test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
752 git config --unset core.whitespace &&
753 echo "x whitespace" >.gitattributes &&
754 echo " foo ();" >x &&
755 git diff --check &&
756 rm -f .gitattributes
759 test_expect_success 'line numbers in --check output are correct' '
760 echo "" >x &&
761 echo "foo(); " >>x &&
762 test_must_fail git diff --check >check &&
763 grep "x:2:" check
766 test_expect_success 'checkdiff detects new trailing blank lines (1)' '
767 echo "foo();" >x &&
768 echo "" >>x &&
769 test_must_fail git diff --check >check &&
770 grep "new blank line" check
773 test_expect_success 'checkdiff detects new trailing blank lines (2)' '
774 test_write_lines a b "" "" >x &&
775 git add x &&
776 test_write_lines a "" "" "" "" >x &&
777 test_must_fail git diff --check >check &&
778 grep "new blank line" check
781 test_expect_success 'checkdiff allows new blank lines' '
782 git checkout x &&
783 mv x y &&
785 echo "/* This is new */" &&
786 echo "" &&
787 cat y
788 ) >x &&
789 git diff --check
792 test_expect_success 'whitespace-only changes not reported' '
793 git reset --hard &&
794 echo >x "hello world" &&
795 git add x &&
796 git commit -m "hello 1" &&
797 echo >x "hello world" &&
798 git diff -b >actual &&
799 test_must_be_empty actual
802 test_expect_success 'whitespace-only changes reported across renames' '
803 git reset --hard &&
804 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
805 git add x &&
806 hash_x=$(git hash-object x) &&
807 before=$(git rev-parse --short "$hash_x") &&
808 git commit -m "base" &&
809 sed -e "5s/^/ /" x >z &&
810 git rm x &&
811 git add z &&
812 hash_z=$(git hash-object z) &&
813 after=$(git rev-parse --short "$hash_z") &&
814 git diff -w -M --cached >actual.raw &&
815 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" actual.raw >actual &&
816 cat <<-EOF >expect &&
817 diff --git a/x b/z
818 similarity index NUM%
819 rename from x
820 rename to z
821 index $before..$after 100644
823 test_cmp expect actual
826 cat >expected <<\EOF
827 diff --git a/empty b/void
828 similarity index 100%
829 rename from empty
830 rename to void
833 test_expect_success 'rename empty' '
834 git reset --hard &&
835 >empty &&
836 git add empty &&
837 git commit -m empty &&
838 git mv empty void &&
839 git diff -w --cached -M >current &&
840 test_cmp expected current
843 test_expect_success 'combined diff with autocrlf conversion' '
845 git reset --hard &&
846 echo >x hello &&
847 git commit -m "one side" x &&
848 git checkout HEAD^ &&
849 echo >x goodbye &&
850 git commit -m "the other side" x &&
851 git config core.autocrlf true &&
852 test_must_fail git merge master &&
854 git diff >actual.raw &&
855 sed -e "1,/^@@@/d" actual.raw >actual &&
856 ! grep "^-" actual
860 # Start testing the colored format for whitespace checks
862 test_expect_success 'setup diff colors' '
863 git config color.diff.plain normal &&
864 git config color.diff.meta bold &&
865 git config color.diff.frag cyan &&
866 git config color.diff.func normal &&
867 git config color.diff.old red &&
868 git config color.diff.new green &&
869 git config color.diff.commit yellow &&
870 git config color.diff.whitespace blue &&
872 git config core.autocrlf false
875 test_expect_success 'diff that introduces a line with only tabs' '
876 git config core.whitespace blank-at-eol &&
877 git reset --hard &&
878 echo "test" >x &&
879 old_hash_x=$(git hash-object x) &&
880 before=$(git rev-parse --short "$old_hash_x") &&
881 git commit -m "initial" x &&
882 echo "{NTN}" | tr "NT" "\n\t" >>x &&
883 new_hash_x=$(git hash-object x) &&
884 after=$(git rev-parse --short "$new_hash_x") &&
885 git diff --color >current.raw &&
886 test_decode_color <current.raw >current &&
888 cat >expected <<-EOF &&
889 <BOLD>diff --git a/x b/x<RESET>
890 <BOLD>index $before..$after 100644<RESET>
891 <BOLD>--- a/x<RESET>
892 <BOLD>+++ b/x<RESET>
893 <CYAN>@@ -1 +1,4 @@<RESET>
894 test<RESET>
895 <GREEN>+<RESET><GREEN>{<RESET>
896 <GREEN>+<RESET><BLUE> <RESET>
897 <GREEN>+<RESET><GREEN>}<RESET>
900 test_cmp expected current
903 test_expect_success 'diff that introduces and removes ws breakages' '
904 git reset --hard &&
906 echo "0. blank-at-eol " &&
907 echo "1. blank-at-eol "
908 } >x &&
909 old_hash_x=$(git hash-object x) &&
910 before=$(git rev-parse --short "$old_hash_x") &&
911 git commit -a --allow-empty -m preimage &&
913 echo "0. blank-at-eol " &&
914 echo "1. still-blank-at-eol " &&
915 echo "2. and a new line "
916 } >x &&
917 new_hash_x=$(git hash-object x) &&
918 after=$(git rev-parse --short "$new_hash_x") &&
920 git diff --color >current.raw &&
921 test_decode_color <current.raw >current &&
923 cat >expected <<-EOF &&
924 <BOLD>diff --git a/x b/x<RESET>
925 <BOLD>index $before..$after 100644<RESET>
926 <BOLD>--- a/x<RESET>
927 <BOLD>+++ b/x<RESET>
928 <CYAN>@@ -1,2 +1,3 @@<RESET>
929 0. blank-at-eol <RESET>
930 <RED>-1. blank-at-eol <RESET>
931 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
932 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
935 test_cmp expected current
938 test_expect_success 'ws-error-highlight test setup' '
940 git reset --hard &&
942 echo "0. blank-at-eol " &&
943 echo "1. blank-at-eol "
944 } >x &&
945 old_hash_x=$(git hash-object x) &&
946 before=$(git rev-parse --short "$old_hash_x") &&
947 git commit -a --allow-empty -m preimage &&
949 echo "0. blank-at-eol " &&
950 echo "1. still-blank-at-eol " &&
951 echo "2. and a new line "
952 } >x &&
953 new_hash_x=$(git hash-object x) &&
954 after=$(git rev-parse --short "$new_hash_x") &&
956 cat >expect.default-old <<-EOF &&
957 <BOLD>diff --git a/x b/x<RESET>
958 <BOLD>index $before..$after 100644<RESET>
959 <BOLD>--- a/x<RESET>
960 <BOLD>+++ b/x<RESET>
961 <CYAN>@@ -1,2 +1,3 @@<RESET>
962 0. blank-at-eol <RESET>
963 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
964 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
965 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
968 cat >expect.all <<-EOF &&
969 <BOLD>diff --git a/x b/x<RESET>
970 <BOLD>index $before..$after 100644<RESET>
971 <BOLD>--- a/x<RESET>
972 <BOLD>+++ b/x<RESET>
973 <CYAN>@@ -1,2 +1,3 @@<RESET>
974 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
975 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
976 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
977 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
980 cat >expect.none <<-EOF
981 <BOLD>diff --git a/x b/x<RESET>
982 <BOLD>index $before..$after 100644<RESET>
983 <BOLD>--- a/x<RESET>
984 <BOLD>+++ b/x<RESET>
985 <CYAN>@@ -1,2 +1,3 @@<RESET>
986 0. blank-at-eol <RESET>
987 <RED>-1. blank-at-eol <RESET>
988 <GREEN>+1. still-blank-at-eol <RESET>
989 <GREEN>+2. and a new line <RESET>
994 test_expect_success 'test --ws-error-highlight option' '
996 git diff --color --ws-error-highlight=default,old >current.raw &&
997 test_decode_color <current.raw >current &&
998 test_cmp expect.default-old current &&
1000 git diff --color --ws-error-highlight=all >current.raw &&
1001 test_decode_color <current.raw >current &&
1002 test_cmp expect.all current &&
1004 git diff --color --ws-error-highlight=none >current.raw &&
1005 test_decode_color <current.raw >current &&
1006 test_cmp expect.none current
1010 test_expect_success 'test diff.wsErrorHighlight config' '
1012 git -c diff.wsErrorHighlight=default,old diff --color >current.raw &&
1013 test_decode_color <current.raw >current &&
1014 test_cmp expect.default-old current &&
1016 git -c diff.wsErrorHighlight=all diff --color >current.raw &&
1017 test_decode_color <current.raw >current &&
1018 test_cmp expect.all current &&
1020 git -c diff.wsErrorHighlight=none diff --color >current.raw &&
1021 test_decode_color <current.raw >current &&
1022 test_cmp expect.none current
1026 test_expect_success 'option overrides diff.wsErrorHighlight' '
1028 git -c diff.wsErrorHighlight=none \
1029 diff --color --ws-error-highlight=default,old >current.raw &&
1030 test_decode_color <current.raw >current &&
1031 test_cmp expect.default-old current &&
1033 git -c diff.wsErrorHighlight=default \
1034 diff --color --ws-error-highlight=all >current.raw &&
1035 test_decode_color <current.raw >current &&
1036 test_cmp expect.all current &&
1038 git -c diff.wsErrorHighlight=all \
1039 diff --color --ws-error-highlight=none >current.raw &&
1040 test_decode_color <current.raw >current &&
1041 test_cmp expect.none current
1045 test_expect_success 'detect moved code, complete file' '
1046 git reset --hard &&
1047 cat <<-\EOF >test.c &&
1048 #include<stdio.h>
1049 main()
1051 printf("Hello World");
1054 git add test.c &&
1055 git commit -m "add main function" &&
1056 file=$(git rev-parse --short HEAD:test.c) &&
1057 git mv test.c main.c &&
1058 test_config color.diff.oldMoved "normal red" &&
1059 test_config color.diff.newMoved "normal green" &&
1060 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1061 test_decode_color <actual.raw >actual &&
1062 cat >expected <<-EOF &&
1063 <BOLD>diff --git a/main.c b/main.c<RESET>
1064 <BOLD>new file mode 100644<RESET>
1065 <BOLD>index 0000000..$file<RESET>
1066 <BOLD>--- /dev/null<RESET>
1067 <BOLD>+++ b/main.c<RESET>
1068 <CYAN>@@ -0,0 +1,5 @@<RESET>
1069 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1070 <BGREEN>+<RESET><BGREEN>main()<RESET>
1071 <BGREEN>+<RESET><BGREEN>{<RESET>
1072 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1073 <BGREEN>+<RESET><BGREEN>}<RESET>
1074 <BOLD>diff --git a/test.c b/test.c<RESET>
1075 <BOLD>deleted file mode 100644<RESET>
1076 <BOLD>index $file..0000000<RESET>
1077 <BOLD>--- a/test.c<RESET>
1078 <BOLD>+++ /dev/null<RESET>
1079 <CYAN>@@ -1,5 +0,0 @@<RESET>
1080 <BRED>-#include<stdio.h><RESET>
1081 <BRED>-main()<RESET>
1082 <BRED>-{<RESET>
1083 <BRED>-printf("Hello World");<RESET>
1084 <BRED>-}<RESET>
1087 test_cmp expected actual
1090 test_expect_success 'detect malicious moved code, inside file' '
1091 test_config color.diff.oldMoved "normal red" &&
1092 test_config color.diff.newMoved "normal green" &&
1093 test_config color.diff.oldMovedAlternative "blue" &&
1094 test_config color.diff.newMovedAlternative "yellow" &&
1095 git reset --hard &&
1096 cat <<-\EOF >main.c &&
1097 #include<stdio.h>
1098 int stuff()
1100 printf("Hello ");
1101 printf("World\n");
1104 int secure_foo(struct user *u)
1106 if (!u->is_allowed_foo)
1107 return;
1108 foo(u);
1111 int main()
1113 foo();
1116 cat <<-\EOF >test.c &&
1117 #include<stdio.h>
1118 int bar()
1120 printf("Hello World, but different\n");
1123 int another_function()
1125 bar();
1128 git add main.c test.c &&
1129 git commit -m "add main and test file" &&
1130 before_main=$(git rev-parse --short HEAD:main.c) &&
1131 before_test=$(git rev-parse --short HEAD:test.c) &&
1132 cat <<-\EOF >main.c &&
1133 #include<stdio.h>
1134 int stuff()
1136 printf("Hello ");
1137 printf("World\n");
1140 int main()
1142 foo();
1145 cat <<-\EOF >test.c &&
1146 #include<stdio.h>
1147 int bar()
1149 printf("Hello World, but different\n");
1152 int secure_foo(struct user *u)
1154 foo(u);
1155 if (!u->is_allowed_foo)
1156 return;
1159 int another_function()
1161 bar();
1164 hash_main=$(git hash-object main.c) &&
1165 after_main=$(git rev-parse --short "$hash_main") &&
1166 hash_test=$(git hash-object test.c) &&
1167 after_test=$(git rev-parse --short "$hash_test") &&
1168 git diff HEAD --no-renames --color-moved=zebra --color >actual.raw &&
1169 test_decode_color <actual.raw >actual &&
1170 cat <<-EOF >expected &&
1171 <BOLD>diff --git a/main.c b/main.c<RESET>
1172 <BOLD>index $before_main..$after_main 100644<RESET>
1173 <BOLD>--- a/main.c<RESET>
1174 <BOLD>+++ b/main.c<RESET>
1175 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1176 printf("World\n");<RESET>
1177 }<RESET>
1178 <RESET>
1179 <BRED>-int secure_foo(struct user *u)<RESET>
1180 <BRED>-{<RESET>
1181 <BLUE>-if (!u->is_allowed_foo)<RESET>
1182 <BLUE>-return;<RESET>
1183 <RED>-foo(u);<RESET>
1184 <RED>-}<RESET>
1185 <RED>-<RESET>
1186 int main()<RESET>
1187 {<RESET>
1188 foo();<RESET>
1189 <BOLD>diff --git a/test.c b/test.c<RESET>
1190 <BOLD>index $before_test..$after_test 100644<RESET>
1191 <BOLD>--- a/test.c<RESET>
1192 <BOLD>+++ b/test.c<RESET>
1193 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1194 printf("Hello World, but different\n");<RESET>
1195 }<RESET>
1196 <RESET>
1197 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1198 <BGREEN>+<RESET><BGREEN>{<RESET>
1199 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1200 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1201 <BGREEN>+<RESET><BGREEN>return;<RESET>
1202 <GREEN>+<RESET><GREEN>}<RESET>
1203 <GREEN>+<RESET>
1204 int another_function()<RESET>
1205 {<RESET>
1206 bar();<RESET>
1209 test_cmp expected actual
1212 test_expect_success 'plain moved code, inside file' '
1213 test_config color.diff.oldMoved "normal red" &&
1214 test_config color.diff.newMoved "normal green" &&
1215 test_config color.diff.oldMovedAlternative "blue" &&
1216 test_config color.diff.newMovedAlternative "yellow" &&
1217 # needs previous test as setup
1218 git diff HEAD --no-renames --color-moved=plain --color >actual.raw &&
1219 test_decode_color <actual.raw >actual &&
1220 cat <<-EOF >expected &&
1221 <BOLD>diff --git a/main.c b/main.c<RESET>
1222 <BOLD>index $before_main..$after_main 100644<RESET>
1223 <BOLD>--- a/main.c<RESET>
1224 <BOLD>+++ b/main.c<RESET>
1225 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1226 printf("World\n");<RESET>
1227 }<RESET>
1228 <RESET>
1229 <BRED>-int secure_foo(struct user *u)<RESET>
1230 <BRED>-{<RESET>
1231 <BRED>-if (!u->is_allowed_foo)<RESET>
1232 <BRED>-return;<RESET>
1233 <BRED>-foo(u);<RESET>
1234 <BRED>-}<RESET>
1235 <BRED>-<RESET>
1236 int main()<RESET>
1237 {<RESET>
1238 foo();<RESET>
1239 <BOLD>diff --git a/test.c b/test.c<RESET>
1240 <BOLD>index $before_test..$after_test 100644<RESET>
1241 <BOLD>--- a/test.c<RESET>
1242 <BOLD>+++ b/test.c<RESET>
1243 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1244 printf("Hello World, but different\n");<RESET>
1245 }<RESET>
1246 <RESET>
1247 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1248 <BGREEN>+<RESET><BGREEN>{<RESET>
1249 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1250 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1251 <BGREEN>+<RESET><BGREEN>return;<RESET>
1252 <BGREEN>+<RESET><BGREEN>}<RESET>
1253 <BGREEN>+<RESET>
1254 int another_function()<RESET>
1255 {<RESET>
1256 bar();<RESET>
1259 test_cmp expected actual
1262 test_expect_success 'detect blocks of moved code' '
1263 git reset --hard &&
1264 cat <<-\EOF >lines.txt &&
1265 long line 1
1266 long line 2
1267 long line 3
1268 line 4
1269 line 5
1270 line 6
1271 line 7
1272 line 8
1273 line 9
1274 line 10
1275 line 11
1276 line 12
1277 line 13
1278 long line 14
1279 long line 15
1280 long line 16
1282 git add lines.txt &&
1283 git commit -m "add poetry" &&
1284 cat <<-\EOF >lines.txt &&
1285 line 4
1286 line 5
1287 line 6
1288 line 7
1289 line 8
1290 line 9
1291 long line 1
1292 long line 2
1293 long line 3
1294 long line 14
1295 long line 15
1296 long line 16
1297 line 10
1298 line 11
1299 line 12
1300 line 13
1302 test_config color.diff.oldMoved "magenta" &&
1303 test_config color.diff.newMoved "cyan" &&
1304 test_config color.diff.oldMovedAlternative "blue" &&
1305 test_config color.diff.newMovedAlternative "yellow" &&
1306 test_config color.diff.oldMovedDimmed "normal magenta" &&
1307 test_config color.diff.newMovedDimmed "normal cyan" &&
1308 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1309 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1310 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1311 grep -v "index" actual.raw | test_decode_color >actual &&
1312 cat <<-\EOF >expected &&
1313 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1314 <BOLD>--- a/lines.txt<RESET>
1315 <BOLD>+++ b/lines.txt<RESET>
1316 <CYAN>@@ -1,16 +1,16 @@<RESET>
1317 <MAGENTA>-long line 1<RESET>
1318 <MAGENTA>-long line 2<RESET>
1319 <MAGENTA>-long line 3<RESET>
1320 line 4<RESET>
1321 line 5<RESET>
1322 line 6<RESET>
1323 line 7<RESET>
1324 line 8<RESET>
1325 line 9<RESET>
1326 <CYAN>+<RESET><CYAN>long line 1<RESET>
1327 <CYAN>+<RESET><CYAN>long line 2<RESET>
1328 <CYAN>+<RESET><CYAN>long line 3<RESET>
1329 <CYAN>+<RESET><CYAN>long line 14<RESET>
1330 <CYAN>+<RESET><CYAN>long line 15<RESET>
1331 <CYAN>+<RESET><CYAN>long line 16<RESET>
1332 line 10<RESET>
1333 line 11<RESET>
1334 line 12<RESET>
1335 line 13<RESET>
1336 <MAGENTA>-long line 14<RESET>
1337 <MAGENTA>-long line 15<RESET>
1338 <MAGENTA>-long line 16<RESET>
1340 test_cmp expected actual
1344 test_expect_success 'detect permutations inside moved code -- dimmed-zebra' '
1345 # reuse setup from test before!
1346 test_config color.diff.oldMoved "magenta" &&
1347 test_config color.diff.newMoved "cyan" &&
1348 test_config color.diff.oldMovedAlternative "blue" &&
1349 test_config color.diff.newMovedAlternative "yellow" &&
1350 test_config color.diff.oldMovedDimmed "normal magenta" &&
1351 test_config color.diff.newMovedDimmed "normal cyan" &&
1352 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1353 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1354 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1355 grep -v "index" actual.raw | test_decode_color >actual &&
1356 cat <<-\EOF >expected &&
1357 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1358 <BOLD>--- a/lines.txt<RESET>
1359 <BOLD>+++ b/lines.txt<RESET>
1360 <CYAN>@@ -1,16 +1,16 @@<RESET>
1361 <BMAGENTA>-long line 1<RESET>
1362 <BMAGENTA>-long line 2<RESET>
1363 <BMAGENTA>-long line 3<RESET>
1364 line 4<RESET>
1365 line 5<RESET>
1366 line 6<RESET>
1367 line 7<RESET>
1368 line 8<RESET>
1369 line 9<RESET>
1370 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1371 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1372 <CYAN>+<RESET><CYAN>long line 3<RESET>
1373 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1374 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1375 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1376 line 10<RESET>
1377 line 11<RESET>
1378 line 12<RESET>
1379 line 13<RESET>
1380 <BMAGENTA>-long line 14<RESET>
1381 <BMAGENTA>-long line 15<RESET>
1382 <BMAGENTA>-long line 16<RESET>
1384 test_cmp expected actual
1387 test_expect_success 'cmd option assumes configured colored-moved' '
1388 test_config color.diff.oldMoved "magenta" &&
1389 test_config color.diff.newMoved "cyan" &&
1390 test_config color.diff.oldMovedAlternative "blue" &&
1391 test_config color.diff.newMovedAlternative "yellow" &&
1392 test_config color.diff.oldMovedDimmed "normal magenta" &&
1393 test_config color.diff.newMovedDimmed "normal cyan" &&
1394 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1395 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1396 test_config diff.colorMoved zebra &&
1397 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1398 grep -v "index" actual.raw | test_decode_color >actual &&
1399 cat <<-\EOF >expected &&
1400 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1401 <BOLD>--- a/lines.txt<RESET>
1402 <BOLD>+++ b/lines.txt<RESET>
1403 <CYAN>@@ -1,16 +1,16 @@<RESET>
1404 <MAGENTA>-long line 1<RESET>
1405 <MAGENTA>-long line 2<RESET>
1406 <MAGENTA>-long line 3<RESET>
1407 line 4<RESET>
1408 line 5<RESET>
1409 line 6<RESET>
1410 line 7<RESET>
1411 line 8<RESET>
1412 line 9<RESET>
1413 <CYAN>+<RESET><CYAN>long line 1<RESET>
1414 <CYAN>+<RESET><CYAN>long line 2<RESET>
1415 <CYAN>+<RESET><CYAN>long line 3<RESET>
1416 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1417 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1418 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1419 line 10<RESET>
1420 line 11<RESET>
1421 line 12<RESET>
1422 line 13<RESET>
1423 <MAGENTA>-long line 14<RESET>
1424 <MAGENTA>-long line 15<RESET>
1425 <MAGENTA>-long line 16<RESET>
1427 test_cmp expected actual
1430 test_expect_success 'no effect from --color-moved with --word-diff' '
1431 cat <<-\EOF >text.txt &&
1432 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1434 git add text.txt &&
1435 git commit -a -m "clean state" &&
1436 cat <<-\EOF >text.txt &&
1437 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1439 git diff --color-moved --word-diff >actual &&
1440 git diff --word-diff >expect &&
1441 test_cmp expect actual
1444 test_expect_success 'set up whitespace tests' '
1445 git reset --hard &&
1446 # Note that these lines have no leading or trailing whitespace.
1447 cat <<-\EOF >lines.txt &&
1448 line 1
1449 line 2
1450 line 3
1451 line 4
1452 line 5
1453 long line 6
1454 long line 7
1455 long line 8
1456 long line 9
1458 git add lines.txt &&
1459 git commit -m "add poetry" &&
1460 git config color.diff.oldMoved "magenta" &&
1461 git config color.diff.newMoved "cyan"
1464 test_expect_success 'move detection ignoring whitespace ' '
1465 q_to_tab <<-\EOF >lines.txt &&
1466 Qlong line 6
1467 Qlong line 7
1468 Qlong line 8
1469 Qchanged long line 9
1470 line 1
1471 line 2
1472 line 3
1473 line 4
1474 line 5
1476 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1477 grep -v "index" actual.raw | test_decode_color >actual &&
1478 cat <<-\EOF >expected &&
1479 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1480 <BOLD>--- a/lines.txt<RESET>
1481 <BOLD>+++ b/lines.txt<RESET>
1482 <CYAN>@@ -1,9 +1,9 @@<RESET>
1483 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1484 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1485 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1486 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1487 line 1<RESET>
1488 line 2<RESET>
1489 line 3<RESET>
1490 line 4<RESET>
1491 line 5<RESET>
1492 <RED>-long line 6<RESET>
1493 <RED>-long line 7<RESET>
1494 <RED>-long line 8<RESET>
1495 <RED>-long line 9<RESET>
1497 test_cmp expected actual &&
1499 git diff HEAD --no-renames --color-moved --color \
1500 --color-moved-ws=ignore-all-space >actual.raw &&
1501 grep -v "index" actual.raw | test_decode_color >actual &&
1502 cat <<-\EOF >expected &&
1503 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1504 <BOLD>--- a/lines.txt<RESET>
1505 <BOLD>+++ b/lines.txt<RESET>
1506 <CYAN>@@ -1,9 +1,9 @@<RESET>
1507 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1508 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1509 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1510 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1511 line 1<RESET>
1512 line 2<RESET>
1513 line 3<RESET>
1514 line 4<RESET>
1515 line 5<RESET>
1516 <MAGENTA>-long line 6<RESET>
1517 <MAGENTA>-long line 7<RESET>
1518 <MAGENTA>-long line 8<RESET>
1519 <RED>-long line 9<RESET>
1521 test_cmp expected actual
1524 test_expect_success 'move detection ignoring whitespace changes' '
1525 git reset --hard &&
1526 # Lines 6-8 have a space change, but 9 is new whitespace
1527 q_to_tab <<-\EOF >lines.txt &&
1528 longQline 6
1529 longQline 7
1530 longQline 8
1531 long liQne 9
1532 line 1
1533 line 2
1534 line 3
1535 line 4
1536 line 5
1539 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1540 grep -v "index" actual.raw | test_decode_color >actual &&
1541 cat <<-\EOF >expected &&
1542 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1543 <BOLD>--- a/lines.txt<RESET>
1544 <BOLD>+++ b/lines.txt<RESET>
1545 <CYAN>@@ -1,9 +1,9 @@<RESET>
1546 <GREEN>+<RESET><GREEN>long line 6<RESET>
1547 <GREEN>+<RESET><GREEN>long line 7<RESET>
1548 <GREEN>+<RESET><GREEN>long line 8<RESET>
1549 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1550 line 1<RESET>
1551 line 2<RESET>
1552 line 3<RESET>
1553 line 4<RESET>
1554 line 5<RESET>
1555 <RED>-long line 6<RESET>
1556 <RED>-long line 7<RESET>
1557 <RED>-long line 8<RESET>
1558 <RED>-long line 9<RESET>
1560 test_cmp expected actual &&
1562 git diff HEAD --no-renames --color-moved --color \
1563 --color-moved-ws=ignore-space-change >actual.raw &&
1564 grep -v "index" actual.raw | test_decode_color >actual &&
1565 cat <<-\EOF >expected &&
1566 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1567 <BOLD>--- a/lines.txt<RESET>
1568 <BOLD>+++ b/lines.txt<RESET>
1569 <CYAN>@@ -1,9 +1,9 @@<RESET>
1570 <CYAN>+<RESET><CYAN>long line 6<RESET>
1571 <CYAN>+<RESET><CYAN>long line 7<RESET>
1572 <CYAN>+<RESET><CYAN>long line 8<RESET>
1573 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1574 line 1<RESET>
1575 line 2<RESET>
1576 line 3<RESET>
1577 line 4<RESET>
1578 line 5<RESET>
1579 <MAGENTA>-long line 6<RESET>
1580 <MAGENTA>-long line 7<RESET>
1581 <MAGENTA>-long line 8<RESET>
1582 <RED>-long line 9<RESET>
1584 test_cmp expected actual
1587 test_expect_success 'move detection ignoring whitespace at eol' '
1588 git reset --hard &&
1589 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1590 q_to_tab <<-\EOF >lines.txt &&
1591 long line 6Q
1592 long line 7Q
1593 long line 8Q
1594 longQline 9Q
1595 line 1
1596 line 2
1597 line 3
1598 line 4
1599 line 5
1602 # avoid cluttering the output with complaints about our eol whitespace
1603 test_config core.whitespace -blank-at-eol &&
1605 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1606 grep -v "index" actual.raw | test_decode_color >actual &&
1607 cat <<-\EOF >expected &&
1608 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1609 <BOLD>--- a/lines.txt<RESET>
1610 <BOLD>+++ b/lines.txt<RESET>
1611 <CYAN>@@ -1,9 +1,9 @@<RESET>
1612 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1613 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1614 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1615 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1616 line 1<RESET>
1617 line 2<RESET>
1618 line 3<RESET>
1619 line 4<RESET>
1620 line 5<RESET>
1621 <RED>-long line 6<RESET>
1622 <RED>-long line 7<RESET>
1623 <RED>-long line 8<RESET>
1624 <RED>-long line 9<RESET>
1626 test_cmp expected actual &&
1628 git diff HEAD --no-renames --color-moved --color \
1629 --color-moved-ws=ignore-space-at-eol >actual.raw &&
1630 grep -v "index" actual.raw | test_decode_color >actual &&
1631 cat <<-\EOF >expected &&
1632 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1633 <BOLD>--- a/lines.txt<RESET>
1634 <BOLD>+++ b/lines.txt<RESET>
1635 <CYAN>@@ -1,9 +1,9 @@<RESET>
1636 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1637 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1638 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1639 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1640 line 1<RESET>
1641 line 2<RESET>
1642 line 3<RESET>
1643 line 4<RESET>
1644 line 5<RESET>
1645 <MAGENTA>-long line 6<RESET>
1646 <MAGENTA>-long line 7<RESET>
1647 <MAGENTA>-long line 8<RESET>
1648 <RED>-long line 9<RESET>
1650 test_cmp expected actual
1653 test_expect_success 'clean up whitespace-test colors' '
1654 git config --unset color.diff.oldMoved &&
1655 git config --unset color.diff.newMoved
1658 test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1659 git reset --hard &&
1660 >bar &&
1661 cat <<-\EOF >foo &&
1662 irrelevant_line
1663 line1
1665 git add foo bar &&
1666 git commit -m x &&
1668 cat <<-\EOF >bar &&
1669 line1
1671 cat <<-\EOF >foo &&
1672 irrelevant_line
1675 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1676 grep -v "index" actual.raw | test_decode_color >actual &&
1677 cat >expected <<-\EOF &&
1678 <BOLD>diff --git a/bar b/bar<RESET>
1679 <BOLD>--- a/bar<RESET>
1680 <BOLD>+++ b/bar<RESET>
1681 <CYAN>@@ -0,0 +1 @@<RESET>
1682 <GREEN>+<RESET><GREEN>line1<RESET>
1683 <BOLD>diff --git a/foo b/foo<RESET>
1684 <BOLD>--- a/foo<RESET>
1685 <BOLD>+++ b/foo<RESET>
1686 <CYAN>@@ -1,2 +1 @@<RESET>
1687 irrelevant_line<RESET>
1688 <RED>-line1<RESET>
1691 test_cmp expected actual
1694 test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
1695 git reset --hard &&
1696 cat <<-\EOF >foo &&
1697 nineteen chars 456789
1698 irrelevant_line
1699 twenty chars 234567890
1701 >bar &&
1702 git add foo bar &&
1703 git commit -m x &&
1705 cat <<-\EOF >foo &&
1706 irrelevant_line
1708 cat <<-\EOF >bar &&
1709 twenty chars 234567890
1710 nineteen chars 456789
1713 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1714 grep -v "index" actual.raw | test_decode_color >actual &&
1715 cat >expected <<-\EOF &&
1716 <BOLD>diff --git a/bar b/bar<RESET>
1717 <BOLD>--- a/bar<RESET>
1718 <BOLD>+++ b/bar<RESET>
1719 <CYAN>@@ -0,0 +1,2 @@<RESET>
1720 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1721 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1722 <BOLD>diff --git a/foo b/foo<RESET>
1723 <BOLD>--- a/foo<RESET>
1724 <BOLD>+++ b/foo<RESET>
1725 <CYAN>@@ -1,3 +1 @@<RESET>
1726 <RED>-nineteen chars 456789<RESET>
1727 irrelevant_line<RESET>
1728 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1731 test_cmp expected actual
1734 test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1735 git reset --hard &&
1736 cat <<-\EOF >foo &&
1737 7charsA
1738 irrelevant_line
1739 7charsB
1740 7charsC
1742 >bar &&
1743 git add foo bar &&
1744 git commit -m x &&
1746 cat <<-\EOF >foo &&
1747 irrelevant_line
1749 cat <<-\EOF >bar &&
1750 7charsB
1751 7charsC
1752 7charsA
1755 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1756 grep -v "index" actual.raw | test_decode_color >actual &&
1757 cat >expected <<-\EOF &&
1758 <BOLD>diff --git a/bar b/bar<RESET>
1759 <BOLD>--- a/bar<RESET>
1760 <BOLD>+++ b/bar<RESET>
1761 <CYAN>@@ -0,0 +1,3 @@<RESET>
1762 <GREEN>+<RESET><GREEN>7charsB<RESET>
1763 <GREEN>+<RESET><GREEN>7charsC<RESET>
1764 <GREEN>+<RESET><GREEN>7charsA<RESET>
1765 <BOLD>diff --git a/foo b/foo<RESET>
1766 <BOLD>--- a/foo<RESET>
1767 <BOLD>+++ b/foo<RESET>
1768 <CYAN>@@ -1,4 +1 @@<RESET>
1769 <RED>-7charsA<RESET>
1770 irrelevant_line<RESET>
1771 <RED>-7charsB<RESET>
1772 <RED>-7charsC<RESET>
1775 test_cmp expected actual
1778 test_expect_success 'move detection with submodules' '
1779 test_create_repo bananas &&
1780 echo ripe >bananas/recipe &&
1781 git -C bananas add recipe &&
1782 test_commit fruit &&
1783 test_commit -C bananas recipe &&
1784 git submodule add ./bananas &&
1785 git add bananas &&
1786 git commit -a -m "bananas are like a heavy library?" &&
1787 echo foul >bananas/recipe &&
1788 echo ripe >fruit.t &&
1790 git diff --submodule=diff --color-moved --color >actual &&
1792 # no move detection as the moved line is across repository boundaries.
1793 test_decode_color <actual >decoded_actual &&
1794 ! grep BGREEN decoded_actual &&
1795 ! grep BRED decoded_actual &&
1797 # nor did we mess with it another way
1798 git diff --submodule=diff --color >expect.raw &&
1799 test_decode_color <expect.raw >expect &&
1800 test_cmp expect decoded_actual &&
1801 rm -rf bananas &&
1802 git submodule deinit bananas
1805 test_expect_success 'only move detection ignores white spaces' '
1806 git reset --hard &&
1807 q_to_tab <<-\EOF >text.txt &&
1808 a long line to exceed per-line minimum
1809 another long line to exceed per-line minimum
1810 original file
1812 git add text.txt &&
1813 git commit -m "add text" &&
1814 q_to_tab <<-\EOF >text.txt &&
1815 Qa long line to exceed per-line minimum
1816 Qanother long line to exceed per-line minimum
1817 new file
1820 # Make sure we get a different diff using -w
1821 git diff --color --color-moved -w >actual.raw &&
1822 grep -v "index" actual.raw | test_decode_color >actual &&
1823 q_to_tab <<-\EOF >expected &&
1824 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1825 <BOLD>--- a/text.txt<RESET>
1826 <BOLD>+++ b/text.txt<RESET>
1827 <CYAN>@@ -1,3 +1,3 @@<RESET>
1828 Qa long line to exceed per-line minimum<RESET>
1829 Qanother long line to exceed per-line minimum<RESET>
1830 <RED>-original file<RESET>
1831 <GREEN>+<RESET><GREEN>new file<RESET>
1833 test_cmp expected actual &&
1835 # And now ignoring white space only in the move detection
1836 git diff --color --color-moved \
1837 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
1838 grep -v "index" actual.raw | test_decode_color >actual &&
1839 q_to_tab <<-\EOF >expected &&
1840 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1841 <BOLD>--- a/text.txt<RESET>
1842 <BOLD>+++ b/text.txt<RESET>
1843 <CYAN>@@ -1,3 +1,3 @@<RESET>
1844 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
1845 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
1846 <RED>-original file<RESET>
1847 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>a long line to exceed per-line minimum<RESET>
1848 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>another long line to exceed per-line minimum<RESET>
1849 <GREEN>+<RESET><GREEN>new file<RESET>
1851 test_cmp expected actual
1854 test_expect_success 'compare whitespace delta across moved blocks' '
1856 git reset --hard &&
1857 q_to_tab <<-\EOF >text.txt &&
1858 QIndented
1859 QText across
1860 Qsome lines
1861 QBut! <- this stands out
1862 QAdjusting with
1863 QQdifferent starting
1864 Qwhite spaces
1865 QAnother outlier
1866 QQQIndented
1867 QQQText across
1868 QQQfive lines
1869 QQQthat has similar lines
1870 QQQto previous blocks, but with different indent
1871 QQQYetQAnotherQoutlierQ
1872 QLine with internal w h i t e s p a c e change
1875 git add text.txt &&
1876 git commit -m "add text.txt" &&
1878 q_to_tab <<-\EOF >text.txt &&
1879 QQIndented
1880 QQText across
1881 QQsome lines
1882 QQQBut! <- this stands out
1883 Adjusting with
1884 Qdifferent starting
1885 white spaces
1886 AnotherQoutlier
1887 QQIndented
1888 QQText across
1889 QQfive lines
1890 QQthat has similar lines
1891 QQto previous blocks, but with different indent
1892 QQYetQAnotherQoutlier
1893 QLine with internal whitespace change
1896 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
1897 grep -v "index" actual.raw | test_decode_color >actual &&
1899 q_to_tab <<-\EOF >expected &&
1900 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1901 <BOLD>--- a/text.txt<RESET>
1902 <BOLD>+++ b/text.txt<RESET>
1903 <CYAN>@@ -1,15 +1,15 @@<RESET>
1904 <BOLD;MAGENTA>-QIndented<RESET>
1905 <BOLD;MAGENTA>-QText across<RESET>
1906 <BOLD;MAGENTA>-Qsome lines<RESET>
1907 <RED>-QBut! <- this stands out<RESET>
1908 <BOLD;MAGENTA>-QAdjusting with<RESET>
1909 <BOLD;MAGENTA>-QQdifferent starting<RESET>
1910 <BOLD;MAGENTA>-Qwhite spaces<RESET>
1911 <RED>-QAnother outlier<RESET>
1912 <BOLD;MAGENTA>-QQQIndented<RESET>
1913 <BOLD;MAGENTA>-QQQText across<RESET>
1914 <BOLD;MAGENTA>-QQQfive lines<RESET>
1915 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
1916 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
1917 <RED>-QQQYetQAnotherQoutlierQ<RESET>
1918 <RED>-QLine with internal w h i t e s p a c e change<RESET>
1919 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1920 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1921 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
1922 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
1923 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
1924 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
1925 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
1926 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
1927 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1928 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1929 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
1930 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
1931 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
1932 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
1933 <GREEN>+<RESET>Q<GREEN>Line with internal whitespace change<RESET>
1936 test_cmp expected actual
1939 test_expect_success 'bogus settings in move detection erroring out' '
1940 test_must_fail git diff --color-moved=bogus 2>err &&
1941 test_i18ngrep "must be one of" err &&
1942 test_i18ngrep bogus err &&
1944 test_must_fail git -c diff.colormoved=bogus diff 2>err &&
1945 test_i18ngrep "must be one of" err &&
1946 test_i18ngrep "from command-line config" err &&
1948 test_must_fail git diff --color-moved-ws=bogus 2>err &&
1949 test_i18ngrep "possible values" err &&
1950 test_i18ngrep bogus err &&
1952 test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
1953 test_i18ngrep "possible values" err &&
1954 test_i18ngrep "from command-line config" err
1957 test_expect_success 'compare whitespace delta incompatible with other space options' '
1958 test_must_fail git diff \
1959 --color-moved-ws=allow-indentation-change,ignore-all-space \
1960 2>err &&
1961 test_i18ngrep allow-indentation-change err
1964 EMPTY=''
1965 test_expect_success 'compare mixed whitespace delta across moved blocks' '
1967 git reset --hard &&
1968 tr Q_ "\t " <<-EOF >text.txt &&
1969 ${EMPTY}
1970 ____too short without
1971 ${EMPTY}
1972 ___being grouped across blank line
1973 ${EMPTY}
1974 context
1975 lines
1977 anchor
1978 ____Indented text to
1979 _Q____be further indented by four spaces across
1980 ____Qseveral lines
1981 QQ____These two lines have had their
1982 ____indentation reduced by four spaces
1983 Qdifferent indentation change
1984 ____too short
1987 git add text.txt &&
1988 git commit -m "add text.txt" &&
1990 tr Q_ "\t " <<-EOF >text.txt &&
1991 context
1992 lines
1994 anchor
1995 QIndented text to
1996 QQbe further indented by four spaces across
1997 Q____several lines
1998 ${EMPTY}
1999 QQtoo short without
2000 ${EMPTY}
2001 Q_______being grouped across blank line
2002 ${EMPTY}
2003 Q_QThese two lines have had their
2004 indentation reduced by four spaces
2005 QQdifferent indentation change
2006 __Qtoo short
2009 git -c color.diff.whitespace="normal red" \
2010 -c core.whitespace=space-before-tab \
2011 diff --color --color-moved --ws-error-highlight=all \
2012 --color-moved-ws=allow-indentation-change >actual.raw &&
2013 grep -v "index" actual.raw | test_decode_color >actual &&
2015 cat <<-\EOF >expected &&
2016 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2017 <BOLD>--- a/text.txt<RESET>
2018 <BOLD>+++ b/text.txt<RESET>
2019 <CYAN>@@ -1,16 +1,16 @@<RESET>
2020 <BOLD;MAGENTA>-<RESET>
2021 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> too short without<RESET>
2022 <BOLD;MAGENTA>-<RESET>
2023 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
2024 <BOLD;MAGENTA>-<RESET>
2025 <RESET>context<RESET>
2026 <RESET>lines<RESET>
2027 <RESET>to<RESET>
2028 <RESET>anchor<RESET>
2029 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
2030 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
2031 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
2032 <BOLD;BLUE>-<RESET> <BOLD;BLUE> These two lines have had their<RESET>
2033 <BOLD;BLUE>-<RESET><BOLD;BLUE> indentation reduced by four spaces<RESET>
2034 <BOLD;MAGENTA>-<RESET> <BOLD;MAGENTA>different indentation change<RESET>
2035 <RED>-<RESET><RED> too short<RESET>
2036 <BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
2037 <BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
2038 <BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
2039 <BOLD;YELLOW>+<RESET>
2040 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
2041 <BOLD;YELLOW>+<RESET>
2042 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW> being grouped across blank line<RESET>
2043 <BOLD;YELLOW>+<RESET>
2044 <BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
2045 <BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
2046 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
2047 <GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
2050 test_cmp expected actual
2053 test_expect_success 'combine --ignore-blank-lines with --function-context' '
2054 test_write_lines 1 "" 2 3 4 5 >a &&
2055 test_write_lines 1 2 3 4 >b &&
2056 test_must_fail git diff --no-index \
2057 --ignore-blank-lines --function-context a b >actual.raw &&
2058 sed -n "/@@/,\$p" <actual.raw >actual &&
2059 cat <<-\EOF >expect &&
2060 @@ -1,6 +1,4 @@
2068 test_cmp expect actual
2071 test_expect_success 'combine --ignore-blank-lines with --function-context 2' '
2072 test_write_lines a b c "" function 1 2 3 4 5 "" 6 7 8 9 >a &&
2073 test_write_lines "" a b c "" function 1 2 3 4 5 6 7 8 >b &&
2074 test_must_fail git diff --no-index \
2075 --ignore-blank-lines --function-context a b >actual.raw &&
2076 sed -n "/@@/,\$p" <actual.raw >actual &&
2077 cat <<-\EOF >expect &&
2078 @@ -5,11 +6,9 @@ c
2079 function
2091 test_cmp expect actual
2094 test_done