Git 2.45
[git/gitster.git] / t / t4015-diff-whitespace.sh
blobb443626afd7271a6e58ccfc45429759b9b8c00ca
1 #!/bin/sh
3 # Copyright (c) 2006 Johannes E. Schindelin
4 # Copyright (c) 2023 Google LLC
6 test_description='Test special whitespace in diff engine.
10 TEST_PASSES_SANITIZE_LEAK=true
11 . ./test-lib.sh
12 . "$TEST_DIRECTORY"/lib-diff.sh
14 for opt_res in --patch --quiet -s --stat --shortstat --dirstat=lines \
15 --raw! --name-only! --name-status!
17 opts=${opt_res%!} expect_failure=
18 test "$opts" = "$opt_res" ||
19 expect_failure="test_expect_code 1"
21 test_expect_success "status with $opts (different)" '
22 echo foo >x &&
23 git add x &&
24 echo bar >x &&
25 test_expect_code 1 git diff -w $opts --exit-code x
28 test_expect_success POSIXPERM "status with $opts (mode differs)" '
29 test_when_finished "git update-index --chmod=-x x" &&
30 echo foo >x &&
31 git add x &&
32 git update-index --chmod=+x x &&
33 test_expect_code 1 git diff -w $opts --exit-code x
36 test_expect_success "status with $opts (removing an empty file)" '
37 : >x &&
38 git add x &&
39 rm x &&
40 test_expect_code 1 git diff -w $opts --exit-code -- x
43 test_expect_success "status with $opts (different but equivalent)" '
44 echo foo >x &&
45 git add x &&
46 echo " foo" >x &&
47 $expect_failure git diff -w $opts --exit-code x
49 done
51 test_expect_success "Ray Lehtiniemi's example" '
52 cat <<-\EOF >x &&
53 do {
54 nothing;
55 } while (0);
56 EOF
57 git update-index --add x &&
58 old_hash_x=$(git hash-object x) &&
59 before=$(git rev-parse --short "$old_hash_x") &&
61 cat <<-\EOF >x &&
64 nothing;
66 while (0);
67 EOF
68 new_hash_x=$(git hash-object x) &&
69 after=$(git rev-parse --short "$new_hash_x") &&
71 cat <<-EOF >expect &&
72 diff --git a/x b/x
73 index $before..$after 100644
74 --- a/x
75 +++ b/x
76 @@ -1,3 +1,5 @@
77 -do {
78 +do
80 nothing;
81 -} while (0);
83 +while (0);
84 EOF
86 git diff >out &&
87 test_cmp expect out &&
89 git diff -w >out &&
90 test_cmp expect out &&
92 git diff -b >out &&
93 test_cmp expect out
96 test_expect_success 'another test, without options' '
97 tr Q "\015" <<-\EOF >x &&
98 whitespace at beginning
99 whitespace change
100 whitespace in the middle
101 whitespace at end
102 unchanged line
103 CR at endQ
106 git update-index x &&
107 old_hash_x=$(git hash-object x) &&
108 before=$(git rev-parse --short "$old_hash_x") &&
110 tr "_" " " <<-\EOF >x &&
111 _ whitespace at beginning
112 whitespace change
113 white space in the middle
114 whitespace at end__
115 unchanged line
116 CR at end
118 new_hash_x=$(git hash-object x) &&
119 after=$(git rev-parse --short "$new_hash_x") &&
121 tr "Q_" "\015 " <<-EOF >expect &&
122 diff --git a/x b/x
123 index $before..$after 100644
124 --- a/x
125 +++ b/x
126 @@ -1,6 +1,6 @@
127 -whitespace at beginning
128 -whitespace change
129 -whitespace in the middle
130 -whitespace at end
131 + whitespace at beginning
132 +whitespace change
133 +white space in the middle
134 +whitespace at end__
135 unchanged line
136 -CR at endQ
137 +CR at end
140 git diff >out &&
141 test_cmp expect out &&
143 git diff -w >out &&
144 test_must_be_empty out &&
146 git diff -w -b >out &&
147 test_must_be_empty out &&
149 git diff -w --ignore-space-at-eol >out &&
150 test_must_be_empty out &&
152 git diff -w -b --ignore-space-at-eol >out &&
153 test_must_be_empty out &&
155 git diff -w --ignore-cr-at-eol >out &&
156 test_must_be_empty out &&
158 tr "Q_" "\015 " <<-EOF >expect &&
159 diff --git a/x b/x
160 index $before..$after 100644
161 --- a/x
162 +++ b/x
163 @@ -1,6 +1,6 @@
164 -whitespace at beginning
165 +_ whitespace at beginning
166 whitespace change
167 -whitespace in the middle
168 +white space in the middle
169 whitespace at end__
170 unchanged line
171 CR at end
173 git diff -b >out &&
174 test_cmp expect out &&
176 git diff -b --ignore-space-at-eol >out &&
177 test_cmp expect out &&
179 git diff -b --ignore-cr-at-eol >out &&
180 test_cmp expect out &&
182 tr "Q_" "\015 " <<-EOF >expect &&
183 diff --git a/x b/x
184 index $before..$after 100644
185 --- a/x
186 +++ b/x
187 @@ -1,6 +1,6 @@
188 -whitespace at beginning
189 -whitespace change
190 -whitespace in the middle
191 +_ whitespace at beginning
192 +whitespace change
193 +white space in the middle
194 whitespace at end__
195 unchanged line
196 CR at end
198 git diff --ignore-space-at-eol >out &&
199 test_cmp expect out &&
201 git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
202 test_cmp expect out &&
204 tr "Q_" "\015 " <<-EOF >expect &&
205 diff --git a/x b/x
206 index_$before..$after 100644
207 --- a/x
208 +++ b/x
209 @@ -1,6 +1,6 @@
210 -whitespace at beginning
211 -whitespace change
212 -whitespace in the middle
213 -whitespace at end
214 +_ whitespace at beginning
215 +whitespace_ _change
216 +white space in the middle
217 +whitespace at end__
218 unchanged line
219 CR at end
221 git diff --ignore-cr-at-eol >out &&
222 test_cmp expect out
225 test_expect_success 'ignore-blank-lines: only new lines' '
226 test_seq 5 >x &&
227 git update-index x &&
228 test_seq 5 | sed "/3/i\\
229 " >x &&
230 git diff --ignore-blank-lines >out &&
231 test_must_be_empty out
234 test_expect_success 'ignore-blank-lines: only new lines with space' '
235 test_seq 5 >x &&
236 git update-index x &&
237 test_seq 5 | sed "/3/i\\
238 " >x &&
239 git diff -w --ignore-blank-lines >out &&
240 test_must_be_empty out
243 test_expect_success 'ignore-blank-lines: after change' '
244 cat <<-\EOF >x &&
255 git update-index x &&
256 cat <<-\EOF >x &&
257 change
268 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
269 cat <<-\EOF >expected &&
270 diff --git a/x b/x
271 --- a/x
272 +++ b/x
273 @@ -1,6 +1,7 @@
274 +change
283 compare_diff_patch expected out.tmp
286 test_expect_success 'ignore-blank-lines: before change' '
287 cat <<-\EOF >x &&
297 git update-index x &&
298 cat <<-\EOF >x &&
308 change
310 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
311 cat <<-\EOF >expected &&
312 diff --git a/x b/x
313 --- a/x
314 +++ b/x
315 @@ -4,5 +4,7 @@
322 +change
324 compare_diff_patch expected out.tmp
327 test_expect_success 'ignore-blank-lines: between changes' '
328 cat <<-\EOF >x &&
342 git update-index x &&
343 cat <<-\EOF >x &&
344 change
357 change
359 git diff --ignore-blank-lines >out.tmp &&
360 cat <<-\EOF >expected &&
361 diff --git a/x b/x
362 --- a/x
363 +++ b/x
364 @@ -1,5 +1,7 @@
365 +change
372 @@ -8,5 +8,7 @@
379 +change
381 compare_diff_patch expected out.tmp
384 test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
385 test_seq 10 >x &&
386 git update-index x &&
387 cat <<-\EOF >x &&
388 change
402 change
404 git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
405 cat <<-\EOF >expected &&
406 diff --git a/x b/x
407 --- a/x
408 +++ b/x
409 @@ -1,10 +1,15 @@
410 +change
424 +change
426 compare_diff_patch expected out.tmp
429 test_expect_success 'ignore-blank-lines: scattered spaces' '
430 test_seq 10 >x &&
431 git update-index x &&
432 cat <<-\EOF >x &&
433 change
450 change
452 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
453 cat <<-\EOF >expected &&
454 diff --git a/x b/x
455 --- a/x
456 +++ b/x
457 @@ -1,3 +1,4 @@
458 +change
462 @@ -8,3 +15,4 @@
466 +change
468 compare_diff_patch expected out.tmp
471 test_expect_success 'ignore-blank-lines: spaces coalesce' '
472 test_seq 6 >x &&
473 git update-index x &&
474 cat <<-\EOF >x &&
475 change
485 change
487 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
488 cat <<-\EOF >expected &&
489 diff --git a/x b/x
490 --- a/x
491 +++ b/x
492 @@ -1,6 +1,11 @@
493 +change
503 +change
505 compare_diff_patch expected out.tmp
508 test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
509 test_seq 16 >x &&
510 git update-index x &&
511 cat <<-\EOF >x &&
512 change
519 change
527 change
534 change
536 git diff --ignore-blank-lines >out.tmp &&
537 cat <<-\EOF >expected &&
538 diff --git a/x b/x
539 --- a/x
540 +++ b/x
541 @@ -1,8 +1,11 @@
542 +change
549 +change
553 @@ -9,8 +13,11 @@
557 +change
564 +change
566 compare_diff_patch expected out.tmp
569 test_expect_success 'check mixed spaces and tabs in indent' '
570 # This is indented with SP HT SP.
571 echo " foo();" >x &&
572 test_must_fail git diff --check >check &&
573 grep "space before tab in indent" check
576 test_expect_success 'check mixed tabs and spaces in indent' '
577 # This is indented with HT SP HT.
578 echo " foo();" >x &&
579 test_must_fail git diff --check >check &&
580 grep "space before tab in indent" check
583 test_expect_success 'check with no whitespace errors' '
584 git commit -m "snapshot" &&
585 echo "foo();" >x &&
586 git diff --check
589 test_expect_success 'check with trailing whitespace' '
590 echo "foo(); " >x &&
591 test_must_fail git diff --check
594 test_expect_success 'check with space before tab in indent' '
595 # indent has space followed by hard tab
596 echo " foo();" >x &&
597 test_must_fail git diff --check
600 test_expect_success '--check and --exit-code are not exclusive' '
601 git checkout x &&
602 git diff --check --exit-code
605 test_expect_success '--check and --quiet are not exclusive' '
606 git diff --check --quiet
609 test_expect_success '-w and --exit-code interact sensibly' '
610 test_when_finished "git checkout x" &&
612 test_seq 15 &&
613 echo " 16"
614 } >x &&
615 test_must_fail git diff --exit-code &&
616 git diff -w >actual &&
617 test_must_be_empty actual &&
618 git diff -w --exit-code
621 test_expect_success '-I and --exit-code interact sensibly' '
622 test_when_finished "git checkout x" &&
624 test_seq 15 &&
625 echo " 16"
626 } >x &&
627 test_must_fail git diff --exit-code &&
628 git diff -I. >actual &&
629 test_must_be_empty actual &&
630 git diff -I. --exit-code
633 test_expect_success 'check staged with no whitespace errors' '
634 echo "foo();" >x &&
635 git add x &&
636 git diff --cached --check
639 test_expect_success 'check staged with trailing whitespace' '
640 echo "foo(); " >x &&
641 git add x &&
642 test_must_fail git diff --cached --check
645 test_expect_success 'check staged with space before tab in indent' '
646 # indent has space followed by hard tab
647 echo " foo();" >x &&
648 git add x &&
649 test_must_fail git diff --cached --check
652 test_expect_success 'check with no whitespace errors (diff-index)' '
653 echo "foo();" >x &&
654 git add x &&
655 git diff-index --check HEAD
658 test_expect_success 'check with trailing whitespace (diff-index)' '
659 echo "foo(); " >x &&
660 git add x &&
661 test_must_fail git diff-index --check HEAD
664 test_expect_success 'check with space before tab in indent (diff-index)' '
665 # indent has space followed by hard tab
666 echo " foo();" >x &&
667 git add x &&
668 test_must_fail git diff-index --check HEAD
671 test_expect_success 'check staged with no whitespace errors (diff-index)' '
672 echo "foo();" >x &&
673 git add x &&
674 git diff-index --cached --check HEAD
677 test_expect_success 'check staged with trailing whitespace (diff-index)' '
678 echo "foo(); " >x &&
679 git add x &&
680 test_must_fail git diff-index --cached --check HEAD
683 test_expect_success 'check staged with space before tab in indent (diff-index)' '
684 # indent has space followed by hard tab
685 echo " foo();" >x &&
686 git add x &&
687 test_must_fail git diff-index --cached --check HEAD
690 test_expect_success 'check with no whitespace errors (diff-tree)' '
691 echo "foo();" >x &&
692 git commit -m "new commit" x &&
693 git diff-tree --check HEAD^ HEAD
696 test_expect_success 'check with trailing whitespace (diff-tree)' '
697 echo "foo(); " >x &&
698 git commit -m "another commit" x &&
699 test_must_fail git diff-tree --check HEAD^ HEAD
702 test_expect_success 'check with space before tab in indent (diff-tree)' '
703 # indent has space followed by hard tab
704 echo " foo();" >x &&
705 git commit -m "yet another" x &&
706 test_must_fail git diff-tree --check HEAD^ HEAD
709 test_expect_success 'check with ignored trailing whitespace attr (diff-tree)' '
710 test_when_finished "git reset --hard HEAD^" &&
712 # create a whitespace error that should be ignored
713 echo "* -whitespace" >.gitattributes &&
714 git add .gitattributes &&
715 echo "foo(); " >x &&
716 git add x &&
717 git commit -m "add trailing space" &&
719 # with a worktree diff-tree ignores the whitespace error
720 git diff-tree --root --check HEAD &&
722 # without a worktree diff-tree still ignores the whitespace error
723 git -C .git diff-tree --root --check HEAD
726 test_expect_success 'check trailing whitespace (trailing-space: off)' '
727 git config core.whitespace "-trailing-space" &&
728 echo "foo (); " >x &&
729 git diff --check
732 test_expect_success 'check trailing whitespace (trailing-space: on)' '
733 git config core.whitespace "trailing-space" &&
734 echo "foo (); " >x &&
735 test_must_fail git diff --check
738 test_expect_success 'check space before tab in indent (space-before-tab: off)' '
739 # indent contains space followed by HT
740 git config core.whitespace "-space-before-tab" &&
741 echo " foo ();" >x &&
742 git diff --check
745 test_expect_success 'check space before tab in indent (space-before-tab: on)' '
746 # indent contains space followed by HT
747 git config core.whitespace "space-before-tab" &&
748 echo " foo (); " >x &&
749 test_must_fail git diff --check
752 test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
753 git config core.whitespace "-indent-with-non-tab" &&
754 echo " foo ();" >x &&
755 git diff --check
758 test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
759 git config core.whitespace "indent-with-non-tab" &&
760 echo " foo ();" >x &&
761 test_must_fail git diff --check
764 test_expect_success 'ditto, but tabwidth=9' '
765 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
766 git diff --check
769 test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
770 git config core.whitespace "indent-with-non-tab" &&
771 echo " foo ();" >x &&
772 test_must_fail git diff --check
775 test_expect_success 'ditto, but tabwidth=10' '
776 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
777 test_must_fail git diff --check
780 test_expect_success 'ditto, but tabwidth=20' '
781 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
782 git diff --check
785 test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
786 git config core.whitespace "-tab-in-indent" &&
787 echo " foo ();" >x &&
788 git diff --check
791 test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
792 git config core.whitespace "tab-in-indent" &&
793 echo " foo ();" >x &&
794 test_must_fail git diff --check
797 test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
798 git config core.whitespace "tab-in-indent" &&
799 echo " foo ();" >x &&
800 test_must_fail git diff --check
803 test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
804 git config core.whitespace "tab-in-indent,tabwidth=1" &&
805 test_must_fail git diff --check
808 test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
809 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
810 echo "foo ();" >x &&
811 test_must_fail git diff --check
814 test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
815 git config --unset core.whitespace &&
816 echo "x whitespace" >.gitattributes &&
817 echo " foo ();" >x &&
818 git diff --check &&
819 rm -f .gitattributes
822 test_expect_success 'line numbers in --check output are correct' '
823 echo "" >x &&
824 echo "foo(); " >>x &&
825 test_must_fail git diff --check >check &&
826 grep "x:2:" check
829 test_expect_success 'checkdiff detects new trailing blank lines (1)' '
830 echo "foo();" >x &&
831 echo "" >>x &&
832 test_must_fail git diff --check >check &&
833 grep "new blank line" check
836 test_expect_success 'checkdiff detects new trailing blank lines (2)' '
837 test_write_lines a b "" "" >x &&
838 git add x &&
839 test_write_lines a "" "" "" "" >x &&
840 test_must_fail git diff --check >check &&
841 grep "new blank line" check
844 test_expect_success 'checkdiff allows new blank lines' '
845 git checkout x &&
846 mv x y &&
848 echo "/* This is new */" &&
849 echo "" &&
850 cat y
851 ) >x &&
852 git diff --check
855 test_expect_success 'whitespace-only changes not reported (diff)' '
856 git reset --hard &&
857 echo >x "hello world" &&
858 git add x &&
859 git commit -m "hello 1" &&
860 echo >x "hello world" &&
861 git diff -b >actual &&
862 test_must_be_empty actual
865 test_expect_success 'whitespace-only changes not reported (diffstat)' '
866 # reuse state from previous test
867 git diff --stat -b >actual &&
868 test_must_be_empty actual
871 test_expect_success 'whitespace changes with modification reported (diffstat)' '
872 git reset --hard &&
873 echo >x "hello world" &&
874 git update-index --chmod=+x x &&
875 git diff --stat --cached -b >actual &&
876 cat <<-EOF >expect &&
877 x | 0
878 1 file changed, 0 insertions(+), 0 deletions(-)
880 test_cmp expect actual
883 test_expect_success 'whitespace-only changes reported across renames (diffstat)' '
884 git reset --hard &&
885 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i" || return 1; done >x &&
886 git add x &&
887 git commit -m "base" &&
888 sed -e "5s/^/ /" x >z &&
889 git rm x &&
890 git add z &&
891 git diff -w -M --cached --stat >actual &&
892 cat <<-EOF >expect &&
893 x => z | 0
894 1 file changed, 0 insertions(+), 0 deletions(-)
896 test_cmp expect actual
899 test_expect_success 'whitespace-only changes reported across renames' '
900 git reset --hard HEAD~1 &&
901 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i" || return 1; done >x &&
902 git add x &&
903 hash_x=$(git hash-object x) &&
904 before=$(git rev-parse --short "$hash_x") &&
905 git commit -m "base" &&
906 sed -e "5s/^/ /" x >z &&
907 git rm x &&
908 git add z &&
909 hash_z=$(git hash-object z) &&
910 after=$(git rev-parse --short "$hash_z") &&
911 git diff -w -M --cached >actual.raw &&
912 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" actual.raw >actual &&
913 cat <<-EOF >expect &&
914 diff --git a/x b/z
915 similarity index NUM%
916 rename from x
917 rename to z
918 index $before..$after 100644
920 test_cmp expect actual
923 cat >expected <<\EOF
924 diff --git a/empty b/void
925 similarity index 100%
926 rename from empty
927 rename to void
930 test_expect_success 'rename empty' '
931 git reset --hard &&
932 >empty &&
933 git add empty &&
934 git commit -m empty &&
935 git mv empty void &&
936 git diff -w --cached -M >current &&
937 test_cmp expected current
940 test_expect_success 'combined diff with autocrlf conversion' '
942 git reset --hard &&
943 test_commit "one side" x hello one-side &&
944 git checkout HEAD^ &&
945 echo >x goodbye &&
946 git commit -m "the other side" x &&
947 git config core.autocrlf true &&
948 test_must_fail git merge one-side >actual &&
949 test_grep "Automatic merge failed" actual &&
951 git diff >actual.raw &&
952 sed -e "1,/^@@@/d" actual.raw >actual &&
953 ! grep "^-" actual
957 # Start testing the colored format for whitespace checks
959 test_expect_success 'setup diff colors' '
960 git config color.diff.plain normal &&
961 git config color.diff.meta bold &&
962 git config color.diff.frag cyan &&
963 git config color.diff.func normal &&
964 git config color.diff.old red &&
965 git config color.diff.new green &&
966 git config color.diff.commit yellow &&
967 git config color.diff.whitespace blue &&
969 git config core.autocrlf false
972 test_expect_success 'diff that introduces a line with only tabs' '
973 git config core.whitespace blank-at-eol &&
974 git reset --hard &&
975 echo "test" >x &&
976 old_hash_x=$(git hash-object x) &&
977 before=$(git rev-parse --short "$old_hash_x") &&
978 git commit -m "initial" x &&
979 echo "{NTN}" | tr "NT" "\n\t" >>x &&
980 new_hash_x=$(git hash-object x) &&
981 after=$(git rev-parse --short "$new_hash_x") &&
982 git diff --color >current.raw &&
983 test_decode_color <current.raw >current &&
985 cat >expected <<-EOF &&
986 <BOLD>diff --git a/x b/x<RESET>
987 <BOLD>index $before..$after 100644<RESET>
988 <BOLD>--- a/x<RESET>
989 <BOLD>+++ b/x<RESET>
990 <CYAN>@@ -1 +1,4 @@<RESET>
991 test<RESET>
992 <GREEN>+<RESET><GREEN>{<RESET>
993 <GREEN>+<RESET><BLUE> <RESET>
994 <GREEN>+<RESET><GREEN>}<RESET>
997 test_cmp expected current
1000 test_expect_success 'diff that introduces and removes ws breakages' '
1001 git reset --hard &&
1003 echo "0. blank-at-eol " &&
1004 echo "1. blank-at-eol "
1005 } >x &&
1006 old_hash_x=$(git hash-object x) &&
1007 before=$(git rev-parse --short "$old_hash_x") &&
1008 git commit -a --allow-empty -m preimage &&
1010 echo "0. blank-at-eol " &&
1011 echo "1. still-blank-at-eol " &&
1012 echo "2. and a new line "
1013 } >x &&
1014 new_hash_x=$(git hash-object x) &&
1015 after=$(git rev-parse --short "$new_hash_x") &&
1017 git diff --color >current.raw &&
1018 test_decode_color <current.raw >current &&
1020 cat >expected <<-EOF &&
1021 <BOLD>diff --git a/x b/x<RESET>
1022 <BOLD>index $before..$after 100644<RESET>
1023 <BOLD>--- a/x<RESET>
1024 <BOLD>+++ b/x<RESET>
1025 <CYAN>@@ -1,2 +1,3 @@<RESET>
1026 0. blank-at-eol <RESET>
1027 <RED>-1. blank-at-eol <RESET>
1028 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1029 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1032 test_cmp expected current
1035 test_expect_success 'ws-error-highlight test setup' '
1037 git reset --hard &&
1039 echo "0. blank-at-eol " &&
1040 echo "1. blank-at-eol "
1041 } >x &&
1042 old_hash_x=$(git hash-object x) &&
1043 before=$(git rev-parse --short "$old_hash_x") &&
1044 git commit -a --allow-empty -m preimage &&
1046 echo "0. blank-at-eol " &&
1047 echo "1. still-blank-at-eol " &&
1048 echo "2. and a new line "
1049 } >x &&
1050 new_hash_x=$(git hash-object x) &&
1051 after=$(git rev-parse --short "$new_hash_x") &&
1053 cat >expect.default-old <<-EOF &&
1054 <BOLD>diff --git a/x b/x<RESET>
1055 <BOLD>index $before..$after 100644<RESET>
1056 <BOLD>--- a/x<RESET>
1057 <BOLD>+++ b/x<RESET>
1058 <CYAN>@@ -1,2 +1,3 @@<RESET>
1059 0. blank-at-eol <RESET>
1060 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1061 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1062 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1065 cat >expect.all <<-EOF &&
1066 <BOLD>diff --git a/x b/x<RESET>
1067 <BOLD>index $before..$after 100644<RESET>
1068 <BOLD>--- a/x<RESET>
1069 <BOLD>+++ b/x<RESET>
1070 <CYAN>@@ -1,2 +1,3 @@<RESET>
1071 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
1072 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1073 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1074 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1077 cat >expect.none <<-EOF
1078 <BOLD>diff --git a/x b/x<RESET>
1079 <BOLD>index $before..$after 100644<RESET>
1080 <BOLD>--- a/x<RESET>
1081 <BOLD>+++ b/x<RESET>
1082 <CYAN>@@ -1,2 +1,3 @@<RESET>
1083 0. blank-at-eol <RESET>
1084 <RED>-1. blank-at-eol <RESET>
1085 <GREEN>+1. still-blank-at-eol <RESET>
1086 <GREEN>+2. and a new line <RESET>
1091 test_expect_success 'test --ws-error-highlight option' '
1093 git diff --color --ws-error-highlight=default,old >current.raw &&
1094 test_decode_color <current.raw >current &&
1095 test_cmp expect.default-old current &&
1097 git diff --color --ws-error-highlight=all >current.raw &&
1098 test_decode_color <current.raw >current &&
1099 test_cmp expect.all current &&
1101 git diff --color --ws-error-highlight=none >current.raw &&
1102 test_decode_color <current.raw >current &&
1103 test_cmp expect.none current
1107 test_expect_success 'test diff.wsErrorHighlight config' '
1109 git -c diff.wsErrorHighlight=default,old diff --color >current.raw &&
1110 test_decode_color <current.raw >current &&
1111 test_cmp expect.default-old current &&
1113 git -c diff.wsErrorHighlight=all diff --color >current.raw &&
1114 test_decode_color <current.raw >current &&
1115 test_cmp expect.all current &&
1117 git -c diff.wsErrorHighlight=none diff --color >current.raw &&
1118 test_decode_color <current.raw >current &&
1119 test_cmp expect.none current
1123 test_expect_success 'option overrides diff.wsErrorHighlight' '
1125 git -c diff.wsErrorHighlight=none \
1126 diff --color --ws-error-highlight=default,old >current.raw &&
1127 test_decode_color <current.raw >current &&
1128 test_cmp expect.default-old current &&
1130 git -c diff.wsErrorHighlight=default \
1131 diff --color --ws-error-highlight=all >current.raw &&
1132 test_decode_color <current.raw >current &&
1133 test_cmp expect.all current &&
1135 git -c diff.wsErrorHighlight=all \
1136 diff --color --ws-error-highlight=none >current.raw &&
1137 test_decode_color <current.raw >current &&
1138 test_cmp expect.none current
1142 test_expect_success 'detect moved code, complete file' '
1143 git reset --hard &&
1144 cat <<-\EOF >test.c &&
1145 #include<stdio.h>
1146 main()
1148 printf("Hello World");
1151 git add test.c &&
1152 git commit -m "add main function" &&
1153 file=$(git rev-parse --short HEAD:test.c) &&
1154 git mv test.c main.c &&
1155 test_config color.diff.oldMoved "normal red" &&
1156 test_config color.diff.newMoved "normal green" &&
1157 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1158 test_decode_color <actual.raw >actual &&
1159 cat >expected <<-EOF &&
1160 <BOLD>diff --git a/main.c b/main.c<RESET>
1161 <BOLD>new file mode 100644<RESET>
1162 <BOLD>index 0000000..$file<RESET>
1163 <BOLD>--- /dev/null<RESET>
1164 <BOLD>+++ b/main.c<RESET>
1165 <CYAN>@@ -0,0 +1,5 @@<RESET>
1166 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1167 <BGREEN>+<RESET><BGREEN>main()<RESET>
1168 <BGREEN>+<RESET><BGREEN>{<RESET>
1169 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1170 <BGREEN>+<RESET><BGREEN>}<RESET>
1171 <BOLD>diff --git a/test.c b/test.c<RESET>
1172 <BOLD>deleted file mode 100644<RESET>
1173 <BOLD>index $file..0000000<RESET>
1174 <BOLD>--- a/test.c<RESET>
1175 <BOLD>+++ /dev/null<RESET>
1176 <CYAN>@@ -1,5 +0,0 @@<RESET>
1177 <BRED>-#include<stdio.h><RESET>
1178 <BRED>-main()<RESET>
1179 <BRED>-{<RESET>
1180 <BRED>-printf("Hello World");<RESET>
1181 <BRED>-}<RESET>
1184 test_cmp expected actual
1187 test_expect_success 'detect malicious moved code, inside file' '
1188 test_config color.diff.oldMoved "normal red" &&
1189 test_config color.diff.newMoved "normal green" &&
1190 test_config color.diff.oldMovedAlternative "blue" &&
1191 test_config color.diff.newMovedAlternative "yellow" &&
1192 git reset --hard &&
1193 cat <<-\EOF >main.c &&
1194 #include<stdio.h>
1195 int stuff()
1197 printf("Hello ");
1198 printf("World\n");
1201 int secure_foo(struct user *u)
1203 if (!u->is_allowed_foo)
1204 return;
1205 foo(u);
1208 int main()
1210 foo();
1213 cat <<-\EOF >test.c &&
1214 #include<stdio.h>
1215 int bar()
1217 printf("Hello World, but different\n");
1220 int another_function()
1222 bar();
1225 git add main.c test.c &&
1226 git commit -m "add main and test file" &&
1227 before_main=$(git rev-parse --short HEAD:main.c) &&
1228 before_test=$(git rev-parse --short HEAD:test.c) &&
1229 cat <<-\EOF >main.c &&
1230 #include<stdio.h>
1231 int stuff()
1233 printf("Hello ");
1234 printf("World\n");
1237 int main()
1239 foo();
1242 cat <<-\EOF >test.c &&
1243 #include<stdio.h>
1244 int bar()
1246 printf("Hello World, but different\n");
1249 int secure_foo(struct user *u)
1251 foo(u);
1252 if (!u->is_allowed_foo)
1253 return;
1256 int another_function()
1258 bar();
1261 hash_main=$(git hash-object main.c) &&
1262 after_main=$(git rev-parse --short "$hash_main") &&
1263 hash_test=$(git hash-object test.c) &&
1264 after_test=$(git rev-parse --short "$hash_test") &&
1265 git diff HEAD --no-renames --color-moved=zebra --color >actual.raw &&
1266 test_decode_color <actual.raw >actual &&
1267 cat <<-EOF >expected &&
1268 <BOLD>diff --git a/main.c b/main.c<RESET>
1269 <BOLD>index $before_main..$after_main 100644<RESET>
1270 <BOLD>--- a/main.c<RESET>
1271 <BOLD>+++ b/main.c<RESET>
1272 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1273 printf("World\n");<RESET>
1274 }<RESET>
1275 <RESET>
1276 <BRED>-int secure_foo(struct user *u)<RESET>
1277 <BRED>-{<RESET>
1278 <BLUE>-if (!u->is_allowed_foo)<RESET>
1279 <BLUE>-return;<RESET>
1280 <RED>-foo(u);<RESET>
1281 <RED>-}<RESET>
1282 <RED>-<RESET>
1283 int main()<RESET>
1284 {<RESET>
1285 foo();<RESET>
1286 <BOLD>diff --git a/test.c b/test.c<RESET>
1287 <BOLD>index $before_test..$after_test 100644<RESET>
1288 <BOLD>--- a/test.c<RESET>
1289 <BOLD>+++ b/test.c<RESET>
1290 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1291 printf("Hello World, but different\n");<RESET>
1292 }<RESET>
1293 <RESET>
1294 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1295 <BGREEN>+<RESET><BGREEN>{<RESET>
1296 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1297 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1298 <BGREEN>+<RESET><BGREEN>return;<RESET>
1299 <GREEN>+<RESET><GREEN>}<RESET>
1300 <GREEN>+<RESET>
1301 int another_function()<RESET>
1302 {<RESET>
1303 bar();<RESET>
1306 test_cmp expected actual
1309 test_expect_success 'plain moved code, inside file' '
1310 test_config color.diff.oldMoved "normal red" &&
1311 test_config color.diff.newMoved "normal green" &&
1312 test_config color.diff.oldMovedAlternative "blue" &&
1313 test_config color.diff.newMovedAlternative "yellow" &&
1314 # needs previous test as setup
1315 git diff HEAD --no-renames --color-moved=plain --color >actual.raw &&
1316 test_decode_color <actual.raw >actual &&
1317 cat <<-EOF >expected &&
1318 <BOLD>diff --git a/main.c b/main.c<RESET>
1319 <BOLD>index $before_main..$after_main 100644<RESET>
1320 <BOLD>--- a/main.c<RESET>
1321 <BOLD>+++ b/main.c<RESET>
1322 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1323 printf("World\n");<RESET>
1324 }<RESET>
1325 <RESET>
1326 <BRED>-int secure_foo(struct user *u)<RESET>
1327 <BRED>-{<RESET>
1328 <BRED>-if (!u->is_allowed_foo)<RESET>
1329 <BRED>-return;<RESET>
1330 <BRED>-foo(u);<RESET>
1331 <BRED>-}<RESET>
1332 <BRED>-<RESET>
1333 int main()<RESET>
1334 {<RESET>
1335 foo();<RESET>
1336 <BOLD>diff --git a/test.c b/test.c<RESET>
1337 <BOLD>index $before_test..$after_test 100644<RESET>
1338 <BOLD>--- a/test.c<RESET>
1339 <BOLD>+++ b/test.c<RESET>
1340 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1341 printf("Hello World, but different\n");<RESET>
1342 }<RESET>
1343 <RESET>
1344 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1345 <BGREEN>+<RESET><BGREEN>{<RESET>
1346 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1347 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1348 <BGREEN>+<RESET><BGREEN>return;<RESET>
1349 <BGREEN>+<RESET><BGREEN>}<RESET>
1350 <BGREEN>+<RESET>
1351 int another_function()<RESET>
1352 {<RESET>
1353 bar();<RESET>
1356 test_cmp expected actual
1359 test_expect_success 'detect blocks of moved code' '
1360 git reset --hard &&
1361 cat <<-\EOF >lines.txt &&
1362 long line 1
1363 long line 2
1364 long line 3
1365 line 4
1366 line 5
1367 line 6
1368 line 7
1369 line 8
1370 line 9
1371 line 10
1372 line 11
1373 line 12
1374 line 13
1375 long line 14
1376 long line 15
1377 long line 16
1379 git add lines.txt &&
1380 git commit -m "add poetry" &&
1381 cat <<-\EOF >lines.txt &&
1382 line 4
1383 line 5
1384 line 6
1385 line 7
1386 line 8
1387 line 9
1388 long line 1
1389 long line 2
1390 long line 3
1391 long line 14
1392 long line 15
1393 long line 16
1394 line 10
1395 line 11
1396 line 12
1397 line 13
1399 test_config color.diff.oldMoved "magenta" &&
1400 test_config color.diff.newMoved "cyan" &&
1401 test_config color.diff.oldMovedAlternative "blue" &&
1402 test_config color.diff.newMovedAlternative "yellow" &&
1403 test_config color.diff.oldMovedDimmed "normal magenta" &&
1404 test_config color.diff.newMovedDimmed "normal cyan" &&
1405 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1406 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1407 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1408 grep -v "index" actual.raw | test_decode_color >actual &&
1409 cat <<-\EOF >expected &&
1410 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1411 <BOLD>--- a/lines.txt<RESET>
1412 <BOLD>+++ b/lines.txt<RESET>
1413 <CYAN>@@ -1,16 +1,16 @@<RESET>
1414 <MAGENTA>-long line 1<RESET>
1415 <MAGENTA>-long line 2<RESET>
1416 <MAGENTA>-long line 3<RESET>
1417 line 4<RESET>
1418 line 5<RESET>
1419 line 6<RESET>
1420 line 7<RESET>
1421 line 8<RESET>
1422 line 9<RESET>
1423 <CYAN>+<RESET><CYAN>long line 1<RESET>
1424 <CYAN>+<RESET><CYAN>long line 2<RESET>
1425 <CYAN>+<RESET><CYAN>long line 3<RESET>
1426 <CYAN>+<RESET><CYAN>long line 14<RESET>
1427 <CYAN>+<RESET><CYAN>long line 15<RESET>
1428 <CYAN>+<RESET><CYAN>long line 16<RESET>
1429 line 10<RESET>
1430 line 11<RESET>
1431 line 12<RESET>
1432 line 13<RESET>
1433 <MAGENTA>-long line 14<RESET>
1434 <MAGENTA>-long line 15<RESET>
1435 <MAGENTA>-long line 16<RESET>
1437 test_cmp expected actual
1441 test_expect_success 'detect permutations inside moved code -- dimmed-zebra' '
1442 # reuse setup from test before!
1443 test_config color.diff.oldMoved "magenta" &&
1444 test_config color.diff.newMoved "cyan" &&
1445 test_config color.diff.oldMovedAlternative "blue" &&
1446 test_config color.diff.newMovedAlternative "yellow" &&
1447 test_config color.diff.oldMovedDimmed "normal magenta" &&
1448 test_config color.diff.newMovedDimmed "normal cyan" &&
1449 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1450 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1451 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1452 grep -v "index" actual.raw | test_decode_color >actual &&
1453 cat <<-\EOF >expected &&
1454 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1455 <BOLD>--- a/lines.txt<RESET>
1456 <BOLD>+++ b/lines.txt<RESET>
1457 <CYAN>@@ -1,16 +1,16 @@<RESET>
1458 <BMAGENTA>-long line 1<RESET>
1459 <BMAGENTA>-long line 2<RESET>
1460 <BMAGENTA>-long line 3<RESET>
1461 line 4<RESET>
1462 line 5<RESET>
1463 line 6<RESET>
1464 line 7<RESET>
1465 line 8<RESET>
1466 line 9<RESET>
1467 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1468 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1469 <CYAN>+<RESET><CYAN>long line 3<RESET>
1470 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1471 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1472 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1473 line 10<RESET>
1474 line 11<RESET>
1475 line 12<RESET>
1476 line 13<RESET>
1477 <BMAGENTA>-long line 14<RESET>
1478 <BMAGENTA>-long line 15<RESET>
1479 <BMAGENTA>-long line 16<RESET>
1481 test_cmp expected actual
1484 test_expect_success 'zebra alternate color is only used when necessary' '
1485 cat >old.txt <<-\EOF &&
1486 line 1A should be marked as oldMoved newMovedAlternate
1487 line 1B should be marked as oldMoved newMovedAlternate
1488 unchanged
1489 line 2A should be marked as oldMoved newMovedAlternate
1490 line 2B should be marked as oldMoved newMovedAlternate
1491 line 3A should be marked as oldMovedAlternate newMoved
1492 line 3B should be marked as oldMovedAlternate newMoved
1493 unchanged
1494 line 4A should be marked as oldMoved newMovedAlternate
1495 line 4B should be marked as oldMoved newMovedAlternate
1496 line 5A should be marked as oldMovedAlternate newMoved
1497 line 5B should be marked as oldMovedAlternate newMoved
1498 line 6A should be marked as oldMoved newMoved
1499 line 6B should be marked as oldMoved newMoved
1501 cat >new.txt <<-\EOF &&
1502 line 1A should be marked as oldMoved newMovedAlternate
1503 line 1B should be marked as oldMoved newMovedAlternate
1504 unchanged
1505 line 3A should be marked as oldMovedAlternate newMoved
1506 line 3B should be marked as oldMovedAlternate newMoved
1507 line 2A should be marked as oldMoved newMovedAlternate
1508 line 2B should be marked as oldMoved newMovedAlternate
1509 unchanged
1510 line 6A should be marked as oldMoved newMoved
1511 line 6B should be marked as oldMoved newMoved
1512 line 4A should be marked as oldMoved newMovedAlternate
1513 line 4B should be marked as oldMoved newMovedAlternate
1514 line 5A should be marked as oldMovedAlternate newMoved
1515 line 5B should be marked as oldMovedAlternate newMoved
1517 test_expect_code 1 git diff --no-index --color --color-moved=zebra \
1518 --color-moved-ws=allow-indentation-change \
1519 old.txt new.txt >output &&
1520 grep -v index output | test_decode_color >actual &&
1521 cat >expected <<-\EOF &&
1522 <BOLD>diff --git a/old.txt b/new.txt<RESET>
1523 <BOLD>--- a/old.txt<RESET>
1524 <BOLD>+++ b/new.txt<RESET>
1525 <CYAN>@@ -1,14 +1,14 @@<RESET>
1526 <BOLD;MAGENTA>-line 1A should be marked as oldMoved newMovedAlternate<RESET>
1527 <BOLD;MAGENTA>-line 1B should be marked as oldMoved newMovedAlternate<RESET>
1528 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 1A should be marked as oldMoved newMovedAlternate<RESET>
1529 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 1B should be marked as oldMoved newMovedAlternate<RESET>
1530 unchanged<RESET>
1531 <BOLD;MAGENTA>-line 2A should be marked as oldMoved newMovedAlternate<RESET>
1532 <BOLD;MAGENTA>-line 2B should be marked as oldMoved newMovedAlternate<RESET>
1533 <BOLD;BLUE>-line 3A should be marked as oldMovedAlternate newMoved<RESET>
1534 <BOLD;BLUE>-line 3B should be marked as oldMovedAlternate newMoved<RESET>
1535 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 3A should be marked as oldMovedAlternate newMoved<RESET>
1536 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 3B should be marked as oldMovedAlternate newMoved<RESET>
1537 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 2A should be marked as oldMoved newMovedAlternate<RESET>
1538 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 2B should be marked as oldMoved newMovedAlternate<RESET>
1539 unchanged<RESET>
1540 <BOLD;MAGENTA>-line 4A should be marked as oldMoved newMovedAlternate<RESET>
1541 <BOLD;MAGENTA>-line 4B should be marked as oldMoved newMovedAlternate<RESET>
1542 <BOLD;BLUE>-line 5A should be marked as oldMovedAlternate newMoved<RESET>
1543 <BOLD;BLUE>-line 5B should be marked as oldMovedAlternate newMoved<RESET>
1544 <BOLD;MAGENTA>-line 6A should be marked as oldMoved newMoved<RESET>
1545 <BOLD;MAGENTA>-line 6B should be marked as oldMoved newMoved<RESET>
1546 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 6A should be marked as oldMoved newMoved<RESET>
1547 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 6B should be marked as oldMoved newMoved<RESET>
1548 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 4A should be marked as oldMoved newMovedAlternate<RESET>
1549 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 4B should be marked as oldMoved newMovedAlternate<RESET>
1550 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 5A should be marked as oldMovedAlternate newMoved<RESET>
1551 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 5B should be marked as oldMovedAlternate newMoved<RESET>
1553 test_cmp expected actual
1556 test_expect_success 'short lines of opposite sign do not get marked as moved' '
1557 cat >old.txt <<-\EOF &&
1558 this line should be marked as moved
1559 unchanged
1560 unchanged
1561 unchanged
1562 unchanged
1563 too short
1564 this line should be marked as oldMoved newMoved
1565 this line should be marked as oldMovedAlternate newMoved
1566 unchanged 1
1567 unchanged 2
1568 unchanged 3
1569 unchanged 4
1570 this line should be marked as oldMoved newMoved/newMovedAlternate
1572 cat >new.txt <<-\EOF &&
1573 too short
1574 unchanged
1575 unchanged
1576 this line should be marked as moved
1577 too short
1578 unchanged
1579 unchanged
1580 this line should be marked as oldMoved newMoved/newMovedAlternate
1581 unchanged 1
1582 unchanged 2
1583 this line should be marked as oldMovedAlternate newMoved
1584 this line should be marked as oldMoved newMoved/newMovedAlternate
1585 unchanged 3
1586 this line should be marked as oldMoved newMoved
1587 unchanged 4
1589 test_expect_code 1 git diff --no-index --color --color-moved=zebra \
1590 old.txt new.txt >output && cat output &&
1591 grep -v index output | test_decode_color >actual &&
1592 cat >expect <<-\EOF &&
1593 <BOLD>diff --git a/old.txt b/new.txt<RESET>
1594 <BOLD>--- a/old.txt<RESET>
1595 <BOLD>+++ b/new.txt<RESET>
1596 <CYAN>@@ -1,13 +1,15 @@<RESET>
1597 <BOLD;MAGENTA>-this line should be marked as moved<RESET>
1598 <GREEN>+<RESET><GREEN>too short<RESET>
1599 unchanged<RESET>
1600 unchanged<RESET>
1601 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as moved<RESET>
1602 <GREEN>+<RESET><GREEN>too short<RESET>
1603 unchanged<RESET>
1604 unchanged<RESET>
1605 <RED>-too short<RESET>
1606 <BOLD;MAGENTA>-this line should be marked as oldMoved newMoved<RESET>
1607 <BOLD;BLUE>-this line should be marked as oldMovedAlternate newMoved<RESET>
1608 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as oldMoved newMoved/newMovedAlternate<RESET>
1609 unchanged 1<RESET>
1610 unchanged 2<RESET>
1611 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as oldMovedAlternate newMoved<RESET>
1612 <BOLD;YELLOW>+<RESET><BOLD;YELLOW>this line should be marked as oldMoved newMoved/newMovedAlternate<RESET>
1613 unchanged 3<RESET>
1614 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as oldMoved newMoved<RESET>
1615 unchanged 4<RESET>
1616 <BOLD;MAGENTA>-this line should be marked as oldMoved newMoved/newMovedAlternate<RESET>
1618 test_cmp expect actual
1621 test_expect_success 'cmd option assumes configured colored-moved' '
1622 test_config color.diff.oldMoved "magenta" &&
1623 test_config color.diff.newMoved "cyan" &&
1624 test_config color.diff.oldMovedAlternative "blue" &&
1625 test_config color.diff.newMovedAlternative "yellow" &&
1626 test_config color.diff.oldMovedDimmed "normal magenta" &&
1627 test_config color.diff.newMovedDimmed "normal cyan" &&
1628 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1629 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1630 test_config diff.colorMoved zebra &&
1631 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1632 grep -v "index" actual.raw | test_decode_color >actual &&
1633 cat <<-\EOF >expected &&
1634 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1635 <BOLD>--- a/lines.txt<RESET>
1636 <BOLD>+++ b/lines.txt<RESET>
1637 <CYAN>@@ -1,16 +1,16 @@<RESET>
1638 <MAGENTA>-long line 1<RESET>
1639 <MAGENTA>-long line 2<RESET>
1640 <MAGENTA>-long line 3<RESET>
1641 line 4<RESET>
1642 line 5<RESET>
1643 line 6<RESET>
1644 line 7<RESET>
1645 line 8<RESET>
1646 line 9<RESET>
1647 <CYAN>+<RESET><CYAN>long line 1<RESET>
1648 <CYAN>+<RESET><CYAN>long line 2<RESET>
1649 <CYAN>+<RESET><CYAN>long line 3<RESET>
1650 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1651 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1652 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1653 line 10<RESET>
1654 line 11<RESET>
1655 line 12<RESET>
1656 line 13<RESET>
1657 <MAGENTA>-long line 14<RESET>
1658 <MAGENTA>-long line 15<RESET>
1659 <MAGENTA>-long line 16<RESET>
1661 test_cmp expected actual
1664 test_expect_success 'no effect on diff from --color-moved with --word-diff' '
1665 cat <<-\EOF >text.txt &&
1666 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1668 git add text.txt &&
1669 git commit -a -m "clean state" &&
1670 cat <<-\EOF >text.txt &&
1671 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1673 git diff --color-moved --word-diff >actual &&
1674 git diff --word-diff >expect &&
1675 test_cmp expect actual
1678 test_expect_success 'no effect on show from --color-moved with --word-diff' '
1679 git show --color-moved --word-diff >actual &&
1680 git show --word-diff >expect &&
1681 test_cmp expect actual
1684 test_expect_success 'set up whitespace tests' '
1685 git reset --hard &&
1686 # Note that these lines have no leading or trailing whitespace.
1687 cat <<-\EOF >lines.txt &&
1688 line 1
1689 line 2
1690 line 3
1691 line 4
1692 line 5
1693 long line 6
1694 long line 7
1695 long line 8
1696 long line 9
1698 git add lines.txt &&
1699 git commit -m "add poetry" &&
1700 git config color.diff.oldMoved "magenta" &&
1701 git config color.diff.newMoved "cyan"
1704 test_expect_success 'move detection ignoring whitespace ' '
1705 q_to_tab <<-\EOF >lines.txt &&
1706 Qlong line 6
1707 Qlong line 7
1708 Qlong line 8
1709 Qchanged long line 9
1710 line 1
1711 line 2
1712 line 3
1713 line 4
1714 line 5
1716 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1717 grep -v "index" actual.raw | test_decode_color >actual &&
1718 cat <<-\EOF >expected &&
1719 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1720 <BOLD>--- a/lines.txt<RESET>
1721 <BOLD>+++ b/lines.txt<RESET>
1722 <CYAN>@@ -1,9 +1,9 @@<RESET>
1723 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1724 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1725 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1726 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1727 line 1<RESET>
1728 line 2<RESET>
1729 line 3<RESET>
1730 line 4<RESET>
1731 line 5<RESET>
1732 <RED>-long line 6<RESET>
1733 <RED>-long line 7<RESET>
1734 <RED>-long line 8<RESET>
1735 <RED>-long line 9<RESET>
1737 test_cmp expected actual &&
1739 git diff HEAD --no-renames --color-moved --color \
1740 --color-moved-ws=ignore-all-space >actual.raw &&
1741 grep -v "index" actual.raw | test_decode_color >actual &&
1742 cat <<-\EOF >expected &&
1743 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1744 <BOLD>--- a/lines.txt<RESET>
1745 <BOLD>+++ b/lines.txt<RESET>
1746 <CYAN>@@ -1,9 +1,9 @@<RESET>
1747 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1748 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1749 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1750 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1751 line 1<RESET>
1752 line 2<RESET>
1753 line 3<RESET>
1754 line 4<RESET>
1755 line 5<RESET>
1756 <MAGENTA>-long line 6<RESET>
1757 <MAGENTA>-long line 7<RESET>
1758 <MAGENTA>-long line 8<RESET>
1759 <RED>-long line 9<RESET>
1761 test_cmp expected actual
1764 test_expect_success 'move detection ignoring whitespace changes' '
1765 git reset --hard &&
1766 # Lines 6-8 have a space change, but 9 is new whitespace
1767 q_to_tab <<-\EOF >lines.txt &&
1768 longQline 6
1769 longQline 7
1770 longQline 8
1771 long liQne 9
1772 line 1
1773 line 2
1774 line 3
1775 line 4
1776 line 5
1779 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1780 grep -v "index" actual.raw | test_decode_color >actual &&
1781 cat <<-\EOF >expected &&
1782 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1783 <BOLD>--- a/lines.txt<RESET>
1784 <BOLD>+++ b/lines.txt<RESET>
1785 <CYAN>@@ -1,9 +1,9 @@<RESET>
1786 <GREEN>+<RESET><GREEN>long line 6<RESET>
1787 <GREEN>+<RESET><GREEN>long line 7<RESET>
1788 <GREEN>+<RESET><GREEN>long line 8<RESET>
1789 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1790 line 1<RESET>
1791 line 2<RESET>
1792 line 3<RESET>
1793 line 4<RESET>
1794 line 5<RESET>
1795 <RED>-long line 6<RESET>
1796 <RED>-long line 7<RESET>
1797 <RED>-long line 8<RESET>
1798 <RED>-long line 9<RESET>
1800 test_cmp expected actual &&
1802 git diff HEAD --no-renames --color-moved --color \
1803 --color-moved-ws=ignore-space-change >actual.raw &&
1804 grep -v "index" actual.raw | test_decode_color >actual &&
1805 cat <<-\EOF >expected &&
1806 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1807 <BOLD>--- a/lines.txt<RESET>
1808 <BOLD>+++ b/lines.txt<RESET>
1809 <CYAN>@@ -1,9 +1,9 @@<RESET>
1810 <CYAN>+<RESET><CYAN>long line 6<RESET>
1811 <CYAN>+<RESET><CYAN>long line 7<RESET>
1812 <CYAN>+<RESET><CYAN>long line 8<RESET>
1813 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1814 line 1<RESET>
1815 line 2<RESET>
1816 line 3<RESET>
1817 line 4<RESET>
1818 line 5<RESET>
1819 <MAGENTA>-long line 6<RESET>
1820 <MAGENTA>-long line 7<RESET>
1821 <MAGENTA>-long line 8<RESET>
1822 <RED>-long line 9<RESET>
1824 test_cmp expected actual
1827 test_expect_success 'move detection ignoring whitespace at eol' '
1828 git reset --hard &&
1829 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1830 q_to_tab <<-\EOF >lines.txt &&
1831 long line 6Q
1832 long line 7Q
1833 long line 8Q
1834 longQline 9Q
1835 line 1
1836 line 2
1837 line 3
1838 line 4
1839 line 5
1842 # avoid cluttering the output with complaints about our eol whitespace
1843 test_config core.whitespace -blank-at-eol &&
1845 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1846 grep -v "index" actual.raw | test_decode_color >actual &&
1847 cat <<-\EOF >expected &&
1848 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1849 <BOLD>--- a/lines.txt<RESET>
1850 <BOLD>+++ b/lines.txt<RESET>
1851 <CYAN>@@ -1,9 +1,9 @@<RESET>
1852 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1853 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1854 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1855 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1856 line 1<RESET>
1857 line 2<RESET>
1858 line 3<RESET>
1859 line 4<RESET>
1860 line 5<RESET>
1861 <RED>-long line 6<RESET>
1862 <RED>-long line 7<RESET>
1863 <RED>-long line 8<RESET>
1864 <RED>-long line 9<RESET>
1866 test_cmp expected actual &&
1868 git diff HEAD --no-renames --color-moved --color \
1869 --color-moved-ws=ignore-space-at-eol >actual.raw &&
1870 grep -v "index" actual.raw | test_decode_color >actual &&
1871 cat <<-\EOF >expected &&
1872 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1873 <BOLD>--- a/lines.txt<RESET>
1874 <BOLD>+++ b/lines.txt<RESET>
1875 <CYAN>@@ -1,9 +1,9 @@<RESET>
1876 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1877 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1878 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1879 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1880 line 1<RESET>
1881 line 2<RESET>
1882 line 3<RESET>
1883 line 4<RESET>
1884 line 5<RESET>
1885 <MAGENTA>-long line 6<RESET>
1886 <MAGENTA>-long line 7<RESET>
1887 <MAGENTA>-long line 8<RESET>
1888 <RED>-long line 9<RESET>
1890 test_cmp expected actual
1893 test_expect_success 'clean up whitespace-test colors' '
1894 git config --unset color.diff.oldMoved &&
1895 git config --unset color.diff.newMoved
1898 test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1899 git reset --hard &&
1900 >bar &&
1901 cat <<-\EOF >foo &&
1902 irrelevant_line
1903 line1
1905 git add foo bar &&
1906 git commit -m x &&
1908 cat <<-\EOF >bar &&
1909 line1
1911 cat <<-\EOF >foo &&
1912 irrelevant_line
1915 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1916 grep -v "index" actual.raw | test_decode_color >actual &&
1917 cat >expected <<-\EOF &&
1918 <BOLD>diff --git a/bar b/bar<RESET>
1919 <BOLD>--- a/bar<RESET>
1920 <BOLD>+++ b/bar<RESET>
1921 <CYAN>@@ -0,0 +1 @@<RESET>
1922 <GREEN>+<RESET><GREEN>line1<RESET>
1923 <BOLD>diff --git a/foo b/foo<RESET>
1924 <BOLD>--- a/foo<RESET>
1925 <BOLD>+++ b/foo<RESET>
1926 <CYAN>@@ -1,2 +1 @@<RESET>
1927 irrelevant_line<RESET>
1928 <RED>-line1<RESET>
1931 test_cmp expected actual
1934 test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
1935 git reset --hard &&
1936 cat <<-\EOF >foo &&
1937 nineteen chars 456789
1938 irrelevant_line
1939 twenty chars 234567890
1941 >bar &&
1942 git add foo bar &&
1943 git commit -m x &&
1945 cat <<-\EOF >foo &&
1946 irrelevant_line
1948 cat <<-\EOF >bar &&
1949 twenty chars 234567890
1950 nineteen chars 456789
1953 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1954 grep -v "index" actual.raw | test_decode_color >actual &&
1955 cat >expected <<-\EOF &&
1956 <BOLD>diff --git a/bar b/bar<RESET>
1957 <BOLD>--- a/bar<RESET>
1958 <BOLD>+++ b/bar<RESET>
1959 <CYAN>@@ -0,0 +1,2 @@<RESET>
1960 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1961 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1962 <BOLD>diff --git a/foo b/foo<RESET>
1963 <BOLD>--- a/foo<RESET>
1964 <BOLD>+++ b/foo<RESET>
1965 <CYAN>@@ -1,3 +1 @@<RESET>
1966 <RED>-nineteen chars 456789<RESET>
1967 irrelevant_line<RESET>
1968 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1971 test_cmp expected actual
1974 test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1975 git reset --hard &&
1976 cat <<-\EOF >foo &&
1977 7charsA
1978 irrelevant_line
1979 7charsB
1980 7charsC
1982 >bar &&
1983 git add foo bar &&
1984 git commit -m x &&
1986 cat <<-\EOF >foo &&
1987 irrelevant_line
1989 cat <<-\EOF >bar &&
1990 7charsB
1991 7charsC
1992 7charsA
1995 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1996 grep -v "index" actual.raw | test_decode_color >actual &&
1997 cat >expected <<-\EOF &&
1998 <BOLD>diff --git a/bar b/bar<RESET>
1999 <BOLD>--- a/bar<RESET>
2000 <BOLD>+++ b/bar<RESET>
2001 <CYAN>@@ -0,0 +1,3 @@<RESET>
2002 <GREEN>+<RESET><GREEN>7charsB<RESET>
2003 <GREEN>+<RESET><GREEN>7charsC<RESET>
2004 <GREEN>+<RESET><GREEN>7charsA<RESET>
2005 <BOLD>diff --git a/foo b/foo<RESET>
2006 <BOLD>--- a/foo<RESET>
2007 <BOLD>+++ b/foo<RESET>
2008 <CYAN>@@ -1,4 +1 @@<RESET>
2009 <RED>-7charsA<RESET>
2010 irrelevant_line<RESET>
2011 <RED>-7charsB<RESET>
2012 <RED>-7charsC<RESET>
2015 test_cmp expected actual
2018 test_expect_success '--color-moved rewinds for MIN_ALNUM_COUNT' '
2019 git reset --hard &&
2020 test_write_lines >file \
2021 A B C one two three four five six seven D E F G H I J &&
2022 git add file &&
2023 test_write_lines >file \
2024 one two A B C D E F G H I J two three four five six seven &&
2025 git diff --color-moved=zebra -- file &&
2027 git diff --color-moved=zebra --color -- file >actual.raw &&
2028 grep -v "index" actual.raw | test_decode_color >actual &&
2029 cat >expected <<-\EOF &&
2030 <BOLD>diff --git a/file b/file<RESET>
2031 <BOLD>--- a/file<RESET>
2032 <BOLD>+++ b/file<RESET>
2033 <CYAN>@@ -1,13 +1,8 @@<RESET>
2034 <GREEN>+<RESET><GREEN>one<RESET>
2035 <GREEN>+<RESET><GREEN>two<RESET>
2036 A<RESET>
2037 B<RESET>
2038 C<RESET>
2039 <RED>-one<RESET>
2040 <BOLD;MAGENTA>-two<RESET>
2041 <BOLD;MAGENTA>-three<RESET>
2042 <BOLD;MAGENTA>-four<RESET>
2043 <BOLD;MAGENTA>-five<RESET>
2044 <BOLD;MAGENTA>-six<RESET>
2045 <BOLD;MAGENTA>-seven<RESET>
2046 D<RESET>
2047 E<RESET>
2048 F<RESET>
2049 <CYAN>@@ -15,3 +10,9 @@<RESET> <RESET>G<RESET>
2050 H<RESET>
2051 I<RESET>
2052 J<RESET>
2053 <BOLD;CYAN>+<RESET><BOLD;CYAN>two<RESET>
2054 <BOLD;CYAN>+<RESET><BOLD;CYAN>three<RESET>
2055 <BOLD;CYAN>+<RESET><BOLD;CYAN>four<RESET>
2056 <BOLD;CYAN>+<RESET><BOLD;CYAN>five<RESET>
2057 <BOLD;CYAN>+<RESET><BOLD;CYAN>six<RESET>
2058 <BOLD;CYAN>+<RESET><BOLD;CYAN>seven<RESET>
2061 test_cmp expected actual
2064 test_expect_success 'move detection with submodules' '
2065 test_create_repo bananas &&
2066 echo ripe >bananas/recipe &&
2067 git -C bananas add recipe &&
2068 test_commit fruit &&
2069 test_commit -C bananas recipe &&
2070 git submodule add ./bananas &&
2071 git add bananas &&
2072 git commit -a -m "bananas are like a heavy library?" &&
2073 echo foul >bananas/recipe &&
2074 echo ripe >fruit.t &&
2076 git diff --submodule=diff --color-moved --color >actual &&
2078 # no move detection as the moved line is across repository boundaries.
2079 test_decode_color <actual >decoded_actual &&
2080 ! grep BGREEN decoded_actual &&
2081 ! grep BRED decoded_actual &&
2083 # nor did we mess with it another way
2084 git diff --submodule=diff --color >expect.raw &&
2085 test_decode_color <expect.raw >expect &&
2086 test_cmp expect decoded_actual &&
2087 rm -rf bananas &&
2088 git submodule deinit bananas
2091 test_expect_success 'only move detection ignores white spaces' '
2092 git reset --hard &&
2093 q_to_tab <<-\EOF >text.txt &&
2094 a long line to exceed per-line minimum
2095 another long line to exceed per-line minimum
2096 original file
2098 git add text.txt &&
2099 git commit -m "add text" &&
2100 q_to_tab <<-\EOF >text.txt &&
2101 Qa long line to exceed per-line minimum
2102 Qanother long line to exceed per-line minimum
2103 new file
2106 # Make sure we get a different diff using -w
2107 git diff --color --color-moved -w >actual.raw &&
2108 grep -v "index" actual.raw | test_decode_color >actual &&
2109 q_to_tab <<-\EOF >expected &&
2110 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2111 <BOLD>--- a/text.txt<RESET>
2112 <BOLD>+++ b/text.txt<RESET>
2113 <CYAN>@@ -1,3 +1,3 @@<RESET>
2114 Qa long line to exceed per-line minimum<RESET>
2115 Qanother long line to exceed per-line minimum<RESET>
2116 <RED>-original file<RESET>
2117 <GREEN>+<RESET><GREEN>new file<RESET>
2119 test_cmp expected actual &&
2121 # And now ignoring white space only in the move detection
2122 git diff --color --color-moved \
2123 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
2124 grep -v "index" actual.raw | test_decode_color >actual &&
2125 q_to_tab <<-\EOF >expected &&
2126 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2127 <BOLD>--- a/text.txt<RESET>
2128 <BOLD>+++ b/text.txt<RESET>
2129 <CYAN>@@ -1,3 +1,3 @@<RESET>
2130 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
2131 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
2132 <RED>-original file<RESET>
2133 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>a long line to exceed per-line minimum<RESET>
2134 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>another long line to exceed per-line minimum<RESET>
2135 <GREEN>+<RESET><GREEN>new file<RESET>
2137 test_cmp expected actual
2140 test_expect_success 'compare whitespace delta across moved blocks' '
2142 git reset --hard &&
2143 q_to_tab <<-\EOF >text.txt &&
2144 QIndented
2145 QText across
2146 Qsome lines
2147 QBut! <- this stands out
2148 QAdjusting with
2149 QQdifferent starting
2150 Qwhite spaces
2151 QAnother outlier
2152 QQQIndented
2153 QQQText across
2154 QQQfive lines
2155 QQQthat has similar lines
2156 QQQto previous blocks, but with different indent
2157 QQQYetQAnotherQoutlierQ
2158 QLine with internal w h i t e s p a c e change
2161 git add text.txt &&
2162 git commit -m "add text.txt" &&
2164 q_to_tab <<-\EOF >text.txt &&
2165 QQIndented
2166 QQText across
2167 QQsome lines
2168 QQQBut! <- this stands out
2169 Adjusting with
2170 Qdifferent starting
2171 white spaces
2172 AnotherQoutlier
2173 QQIndented
2174 QQText across
2175 QQfive lines
2176 QQthat has similar lines
2177 QQto previous blocks, but with different indent
2178 QQYetQAnotherQoutlier
2179 QLine with internal whitespace change
2182 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
2183 grep -v "index" actual.raw | test_decode_color >actual &&
2185 q_to_tab <<-\EOF >expected &&
2186 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2187 <BOLD>--- a/text.txt<RESET>
2188 <BOLD>+++ b/text.txt<RESET>
2189 <CYAN>@@ -1,15 +1,15 @@<RESET>
2190 <BOLD;MAGENTA>-QIndented<RESET>
2191 <BOLD;MAGENTA>-QText across<RESET>
2192 <BOLD;MAGENTA>-Qsome lines<RESET>
2193 <RED>-QBut! <- this stands out<RESET>
2194 <BOLD;MAGENTA>-QAdjusting with<RESET>
2195 <BOLD;MAGENTA>-QQdifferent starting<RESET>
2196 <BOLD;MAGENTA>-Qwhite spaces<RESET>
2197 <RED>-QAnother outlier<RESET>
2198 <BOLD;MAGENTA>-QQQIndented<RESET>
2199 <BOLD;MAGENTA>-QQQText across<RESET>
2200 <BOLD;MAGENTA>-QQQfive lines<RESET>
2201 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
2202 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
2203 <RED>-QQQYetQAnotherQoutlierQ<RESET>
2204 <RED>-QLine with internal w h i t e s p a c e change<RESET>
2205 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
2206 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
2207 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
2208 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
2209 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
2210 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
2211 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
2212 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
2213 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
2214 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
2215 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
2216 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
2217 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
2218 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
2219 <GREEN>+<RESET>Q<GREEN>Line with internal whitespace change<RESET>
2222 test_cmp expected actual
2225 test_expect_success 'bogus settings in move detection erroring out' '
2226 test_must_fail git diff --color-moved=bogus 2>err &&
2227 test_grep "must be one of" err &&
2228 test_grep bogus err &&
2230 test_must_fail git -c diff.colormoved=bogus diff 2>err &&
2231 test_grep "must be one of" err &&
2232 test_grep "from command-line config" err &&
2234 test_must_fail git diff --color-moved-ws=bogus 2>err &&
2235 test_grep "possible values" err &&
2236 test_grep bogus err &&
2238 test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
2239 test_grep "possible values" err &&
2240 test_grep "from command-line config" err
2243 test_expect_success 'compare whitespace delta incompatible with other space options' '
2244 test_must_fail git diff \
2245 --color-moved-ws=allow-indentation-change,ignore-all-space \
2246 2>err &&
2247 test_grep allow-indentation-change err
2250 EMPTY=''
2251 test_expect_success 'compare mixed whitespace delta across moved blocks' '
2253 git reset --hard &&
2254 tr "^|Q_" "\f\v\t " <<-EOF >text.txt &&
2256 |____too short without
2258 ___being grouped across blank line
2259 ${EMPTY}
2260 context
2261 lines
2263 anchor
2264 ____Indented text to
2265 _Q____be further indented by four spaces across
2266 ____Qseveral lines
2267 QQ____These two lines have had their
2268 ____indentation reduced by four spaces
2269 Qdifferent indentation change
2270 ____too short
2273 git add text.txt &&
2274 git commit -m "add text.txt" &&
2276 tr "^|Q_" "\f\v\t " <<-EOF >text.txt &&
2277 context
2278 lines
2280 anchor
2281 QIndented text to
2282 QQbe further indented by four spaces across
2283 Q____several lines
2284 ${EMPTY}
2285 QQtoo short without
2286 ${EMPTY}
2287 ^Q_______being grouped across blank line
2288 ${EMPTY}
2289 Q_QThese two lines have had their
2290 indentation reduced by four spaces
2291 QQdifferent indentation change
2292 __Qtoo short
2295 git -c color.diff.whitespace="normal red" \
2296 -c core.whitespace=space-before-tab \
2297 diff --color --color-moved --ws-error-highlight=all \
2298 --color-moved-ws=allow-indentation-change >actual.raw &&
2299 grep -v "index" actual.raw | tr "\f\v" "^|" | test_decode_color >actual &&
2301 cat <<-\EOF >expected &&
2302 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2303 <BOLD>--- a/text.txt<RESET>
2304 <BOLD>+++ b/text.txt<RESET>
2305 <CYAN>@@ -1,16 +1,16 @@<RESET>
2306 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA>^<RESET><BRED> <RESET>
2307 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA>| too short without<RESET>
2308 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA>^<RESET>
2309 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
2310 <BOLD;MAGENTA>-<RESET>
2311 <RESET>context<RESET>
2312 <RESET>lines<RESET>
2313 <RESET>to<RESET>
2314 <RESET>anchor<RESET>
2315 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
2316 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
2317 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
2318 <BOLD;BLUE>-<RESET> <BOLD;BLUE> These two lines have had their<RESET>
2319 <BOLD;BLUE>-<RESET><BOLD;BLUE> indentation reduced by four spaces<RESET>
2320 <BOLD;MAGENTA>-<RESET> <BOLD;MAGENTA>different indentation change<RESET>
2321 <RED>-<RESET><RED> too short<RESET>
2322 <BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
2323 <BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
2324 <BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
2325 <BOLD;YELLOW>+<RESET>
2326 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
2327 <BOLD;YELLOW>+<RESET>
2328 <BOLD;YELLOW>+<RESET><BOLD;YELLOW>^ being grouped across blank line<RESET>
2329 <BOLD;YELLOW>+<RESET>
2330 <BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
2331 <BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
2332 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
2333 <GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
2336 test_cmp expected actual
2339 test_expect_success 'combine --ignore-blank-lines with --function-context' '
2340 test_write_lines 1 "" 2 3 4 5 >a &&
2341 test_write_lines 1 2 3 4 >b &&
2342 test_must_fail git diff --no-index \
2343 --ignore-blank-lines --function-context a b >actual.raw &&
2344 sed -n "/@@/,\$p" <actual.raw >actual &&
2345 cat <<-\EOF >expect &&
2346 @@ -1,6 +1,4 @@
2354 test_cmp expect actual
2357 test_expect_success 'combine --ignore-blank-lines with --function-context 2' '
2358 test_write_lines a b c "" function 1 2 3 4 5 "" 6 7 8 9 >a &&
2359 test_write_lines "" a b c "" function 1 2 3 4 5 6 7 8 >b &&
2360 test_must_fail git diff --no-index \
2361 --ignore-blank-lines --function-context a b >actual.raw &&
2362 sed -n "/@@/,\$p" <actual.raw >actual &&
2363 cat <<-\EOF >expect &&
2364 @@ -5,11 +6,9 @@ c
2365 function
2377 test_cmp expect actual
2380 test_done