3 # Copyright (c) 2006 Johannes E. Schindelin
6 test_description='Test special whitespace in diff engine.
10 . "$TEST_DIRECTORY"/diff-lib.sh
12 test_expect_success "Ray Lehtiniemi's example" '
18 git update-index --add x &&
19 before=$(git rev-parse --short $(git hash-object x)) &&
28 after=$(git rev-parse --short $(git hash-object x)) &&
32 index $before..$after 100644
46 test_cmp expect out &&
49 test_cmp expect out &&
55 test_expect_success 'another test, without options' '
56 tr Q "\015" <<-\EOF >x &&
57 whitespace at beginning
59 whitespace in the middle
66 before=$(git rev-parse --short $(git hash-object x)) &&
68 tr "_" " " <<-\EOF >x &&
69 _ whitespace at beginning
71 white space in the middle
76 after=$(git rev-parse --short $(git hash-object x)) &&
78 tr "Q_" "\015 " <<-EOF >expect &&
80 index $before..$after 100644
84 -whitespace at beginning
86 -whitespace in the middle
88 + whitespace at beginning
90 +white space in the middle
98 test_cmp expect out &&
101 test_must_be_empty out &&
103 git diff -w -b >out &&
104 test_must_be_empty out &&
106 git diff -w --ignore-space-at-eol >out &&
107 test_must_be_empty out &&
109 git diff -w -b --ignore-space-at-eol >out &&
110 test_must_be_empty out &&
112 git diff -w --ignore-cr-at-eol >out &&
113 test_must_be_empty out &&
115 tr "Q_" "\015 " <<-EOF >expect &&
117 index $before..$after 100644
121 -whitespace at beginning
122 +_ whitespace at beginning
124 -whitespace in the middle
125 +white space in the middle
131 test_cmp expect out &&
133 git diff -b --ignore-space-at-eol >out &&
134 test_cmp expect out &&
136 git diff -b --ignore-cr-at-eol >out &&
137 test_cmp expect out &&
139 tr "Q_" "\015 " <<-EOF >expect &&
141 index $before..$after 100644
145 -whitespace at beginning
147 -whitespace in the middle
148 +_ whitespace at beginning
150 +white space in the middle
155 git diff --ignore-space-at-eol >out &&
156 test_cmp expect out &&
158 git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
159 test_cmp expect out &&
161 tr "Q_" "\015 " <<-EOF >expect &&
163 index_$before..$after 100644
167 -whitespace at beginning
169 -whitespace in the middle
171 +_ whitespace at beginning
173 +white space in the middle
178 git diff --ignore-cr-at-eol >out &&
182 test_expect_success 'ignore-blank-lines: only new lines' '
184 git update-index x &&
185 test_seq 5 | sed "/3/i\\
187 git diff --ignore-blank-lines >out &&
188 test_must_be_empty out
191 test_expect_success 'ignore-blank-lines: only new lines with space' '
193 git update-index x &&
194 test_seq 5 | sed "/3/i\\
196 git diff -w --ignore-blank-lines >out &&
197 test_must_be_empty out
200 test_expect_success 'ignore-blank-lines: after change' '
212 git update-index x &&
225 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
226 cat <<-\EOF >expected &&
240 compare_diff_patch expected out.tmp
243 test_expect_success 'ignore-blank-lines: before change' '
254 git update-index x &&
267 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
268 cat <<-\EOF >expected &&
281 compare_diff_patch expected out.tmp
284 test_expect_success 'ignore-blank-lines: between changes' '
299 git update-index x &&
316 git diff --ignore-blank-lines >out.tmp &&
317 cat <<-\EOF >expected &&
338 compare_diff_patch expected out.tmp
341 test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
343 git update-index x &&
361 git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
362 cat <<-\EOF >expected &&
383 compare_diff_patch expected out.tmp
386 test_expect_success 'ignore-blank-lines: scattered spaces' '
388 git update-index x &&
409 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
410 cat <<-\EOF >expected &&
425 compare_diff_patch expected out.tmp
428 test_expect_success 'ignore-blank-lines: spaces coalesce' '
430 git update-index x &&
444 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
445 cat <<-\EOF >expected &&
462 compare_diff_patch expected out.tmp
465 test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
467 git update-index x &&
493 git diff --ignore-blank-lines >out.tmp &&
494 cat <<-\EOF >expected &&
523 compare_diff_patch expected out.tmp
526 test_expect_success 'check mixed spaces and tabs in indent' '
527 # This is indented with SP HT SP.
529 git diff --check | grep "space before tab in indent"
532 test_expect_success 'check mixed tabs and spaces in indent' '
533 # This is indented with HT SP HT.
535 git diff --check | grep "space before tab in indent"
538 test_expect_success 'check with no whitespace errors' '
539 git commit -m "snapshot" &&
544 test_expect_success 'check with trailing whitespace' '
546 test_must_fail git diff --check
549 test_expect_success 'check with space before tab in indent' '
550 # indent has space followed by hard tab
552 test_must_fail git diff --check
555 test_expect_success '--check and --exit-code are not exclusive' '
557 git diff --check --exit-code
560 test_expect_success '--check and --quiet are not exclusive' '
561 git diff --check --quiet
564 test_expect_success 'check staged with no whitespace errors' '
567 git diff --cached --check
570 test_expect_success 'check staged with trailing whitespace' '
573 test_must_fail git diff --cached --check
576 test_expect_success 'check staged with space before tab in indent' '
577 # indent has space followed by hard tab
580 test_must_fail git diff --cached --check
583 test_expect_success 'check with no whitespace errors (diff-index)' '
586 git diff-index --check HEAD
589 test_expect_success 'check with trailing whitespace (diff-index)' '
592 test_must_fail git diff-index --check HEAD
595 test_expect_success 'check with space before tab in indent (diff-index)' '
596 # indent has space followed by hard tab
599 test_must_fail git diff-index --check HEAD
602 test_expect_success 'check staged with no whitespace errors (diff-index)' '
605 git diff-index --cached --check HEAD
608 test_expect_success 'check staged with trailing whitespace (diff-index)' '
611 test_must_fail git diff-index --cached --check HEAD
614 test_expect_success 'check staged with space before tab in indent (diff-index)' '
615 # indent has space followed by hard tab
618 test_must_fail git diff-index --cached --check HEAD
621 test_expect_success 'check with no whitespace errors (diff-tree)' '
623 git commit -m "new commit" x &&
624 git diff-tree --check HEAD^ HEAD
627 test_expect_success 'check with trailing whitespace (diff-tree)' '
629 git commit -m "another commit" x &&
630 test_must_fail git diff-tree --check HEAD^ HEAD
633 test_expect_success 'check with space before tab in indent (diff-tree)' '
634 # indent has space followed by hard tab
636 git commit -m "yet another" x &&
637 test_must_fail git diff-tree --check HEAD^ HEAD
640 test_expect_success 'check with ignored trailing whitespace attr (diff-tree)' '
641 test_when_finished "git reset --hard HEAD^" &&
643 # create a whitespace error that should be ignored
644 echo "* -whitespace" >.gitattributes &&
645 git add .gitattributes &&
648 git commit -m "add trailing space" &&
650 # with a worktree diff-tree ignores the whitespace error
651 git diff-tree --root --check HEAD &&
653 # without a worktree diff-tree still ignores the whitespace error
654 git -C .git diff-tree --root --check HEAD
657 test_expect_success 'check trailing whitespace (trailing-space: off)' '
658 git config core.whitespace "-trailing-space" &&
659 echo "foo (); " >x &&
663 test_expect_success 'check trailing whitespace (trailing-space: on)' '
664 git config core.whitespace "trailing-space" &&
665 echo "foo (); " >x &&
666 test_must_fail git diff --check
669 test_expect_success 'check space before tab in indent (space-before-tab: off)' '
670 # indent contains space followed by HT
671 git config core.whitespace "-space-before-tab" &&
672 echo " foo ();" >x &&
676 test_expect_success 'check space before tab in indent (space-before-tab: on)' '
677 # indent contains space followed by HT
678 git config core.whitespace "space-before-tab" &&
679 echo " foo (); " >x &&
680 test_must_fail git diff --check
683 test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
684 git config core.whitespace "-indent-with-non-tab" &&
685 echo " foo ();" >x &&
689 test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
690 git config core.whitespace "indent-with-non-tab" &&
691 echo " foo ();" >x &&
692 test_must_fail git diff --check
695 test_expect_success 'ditto, but tabwidth=9' '
696 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
700 test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
701 git config core.whitespace "indent-with-non-tab" &&
702 echo " foo ();" >x &&
703 test_must_fail git diff --check
706 test_expect_success 'ditto, but tabwidth=10' '
707 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
708 test_must_fail git diff --check
711 test_expect_success 'ditto, but tabwidth=20' '
712 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
716 test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
717 git config core.whitespace "-tab-in-indent" &&
718 echo " foo ();" >x &&
722 test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
723 git config core.whitespace "tab-in-indent" &&
724 echo " foo ();" >x &&
725 test_must_fail git diff --check
728 test_expect_success 'check tabs and spaces 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 'ditto, but tabwidth=1 (must be irrelevant)' '
735 git config core.whitespace "tab-in-indent,tabwidth=1" &&
736 test_must_fail git diff --check
739 test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
740 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
742 test_must_fail git diff --check
745 test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
746 git config --unset core.whitespace &&
747 echo "x whitespace" >.gitattributes &&
748 echo " foo ();" >x &&
753 test_expect_success 'line numbers in --check output are correct' '
755 echo "foo(); " >>x &&
756 git diff --check | grep "x:2:"
759 test_expect_success 'checkdiff detects new trailing blank lines (1)' '
762 git diff --check | grep "new blank line"
765 test_expect_success 'checkdiff detects new trailing blank lines (2)' '
766 { echo a; echo b; echo; echo; } >x &&
768 { echo a; echo; echo; echo; echo; } >x &&
769 git diff --check | grep "new blank line"
772 test_expect_success 'checkdiff allows new blank lines' '
776 echo "/* This is new */" &&
783 test_expect_success 'whitespace-only changes not reported' '
785 echo >x "hello world" &&
787 git commit -m "hello 1" &&
788 echo >x "hello world" &&
789 git diff -b >actual &&
790 test_must_be_empty actual
793 test_expect_success 'whitespace-only changes reported across renames' '
795 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
797 before=$(git rev-parse --short $(git hash-object x)) &&
798 git commit -m "base" &&
799 sed -e "5s/^/ /" x >z &&
802 after=$(git rev-parse --short $(git hash-object z)) &&
803 git diff -w -M --cached |
804 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual &&
805 cat <<-EOF >expect &&
807 similarity index NUM%
810 index $before..$after 100644
812 test_cmp expect actual
816 diff --git a/empty b/void
817 similarity index 100%
822 test_expect_success 'rename empty' '
826 git commit -m empty &&
828 git diff -w --cached -M >current &&
829 test_cmp expected current
832 test_expect_success 'combined diff with autocrlf conversion' '
836 git commit -m "one side" x &&
837 git checkout HEAD^ &&
839 git commit -m "the other side" x &&
840 git config core.autocrlf true &&
841 test_must_fail git merge master &&
843 git diff | sed -e "1,/^@@@/d" >actual &&
848 # Start testing the colored format for whitespace checks
850 test_expect_success 'setup diff colors' '
851 git config color.diff.plain normal &&
852 git config color.diff.meta bold &&
853 git config color.diff.frag cyan &&
854 git config color.diff.func normal &&
855 git config color.diff.old red &&
856 git config color.diff.new green &&
857 git config color.diff.commit yellow &&
858 git config color.diff.whitespace blue &&
860 git config core.autocrlf false
863 test_expect_success 'diff that introduces a line with only tabs' '
864 git config core.whitespace blank-at-eol &&
867 before=$(git rev-parse --short $(git hash-object x)) &&
868 git commit -m "initial" x &&
869 echo "{NTN}" | tr "NT" "\n\t" >>x &&
870 after=$(git rev-parse --short $(git hash-object x)) &&
871 git diff --color | test_decode_color >current &&
873 cat >expected <<-EOF &&
874 <BOLD>diff --git a/x b/x<RESET>
875 <BOLD>index $before..$after 100644<RESET>
878 <CYAN>@@ -1 +1,4 @@<RESET>
880 <GREEN>+<RESET><GREEN>{<RESET>
881 <GREEN>+<RESET><BLUE> <RESET>
882 <GREEN>+<RESET><GREEN>}<RESET>
885 test_cmp expected current
888 test_expect_success 'diff that introduces and removes ws breakages' '
891 echo "0. blank-at-eol " &&
892 echo "1. blank-at-eol "
894 before=$(git rev-parse --short $(git hash-object x)) &&
895 git commit -a --allow-empty -m preimage &&
897 echo "0. blank-at-eol " &&
898 echo "1. still-blank-at-eol " &&
899 echo "2. and a new line "
901 after=$(git rev-parse --short $(git hash-object x)) &&
904 test_decode_color >current &&
906 cat >expected <<-EOF &&
907 <BOLD>diff --git a/x b/x<RESET>
908 <BOLD>index $before..$after 100644<RESET>
911 <CYAN>@@ -1,2 +1,3 @@<RESET>
912 0. blank-at-eol <RESET>
913 <RED>-1. blank-at-eol <RESET>
914 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
915 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
918 test_cmp expected current
921 test_expect_success 'ws-error-highlight test setup' '
925 echo "0. blank-at-eol " &&
926 echo "1. blank-at-eol "
928 before=$(git rev-parse --short $(git hash-object x)) &&
929 git commit -a --allow-empty -m preimage &&
931 echo "0. blank-at-eol " &&
932 echo "1. still-blank-at-eol " &&
933 echo "2. and a new line "
935 after=$(git rev-parse --short $(git hash-object x)) &&
937 cat >expect.default-old <<-EOF &&
938 <BOLD>diff --git a/x b/x<RESET>
939 <BOLD>index $before..$after 100644<RESET>
942 <CYAN>@@ -1,2 +1,3 @@<RESET>
943 0. blank-at-eol <RESET>
944 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
945 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
946 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
949 cat >expect.all <<-EOF &&
950 <BOLD>diff --git a/x b/x<RESET>
951 <BOLD>index $before..$after 100644<RESET>
954 <CYAN>@@ -1,2 +1,3 @@<RESET>
955 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
956 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
957 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
958 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
961 cat >expect.none <<-EOF
962 <BOLD>diff --git a/x b/x<RESET>
963 <BOLD>index $before..$after 100644<RESET>
966 <CYAN>@@ -1,2 +1,3 @@<RESET>
967 0. blank-at-eol <RESET>
968 <RED>-1. blank-at-eol <RESET>
969 <GREEN>+1. still-blank-at-eol <RESET>
970 <GREEN>+2. and a new line <RESET>
975 test_expect_success 'test --ws-error-highlight option' '
977 git diff --color --ws-error-highlight=default,old |
978 test_decode_color >current &&
979 test_cmp expect.default-old current &&
981 git diff --color --ws-error-highlight=all |
982 test_decode_color >current &&
983 test_cmp expect.all current &&
985 git diff --color --ws-error-highlight=none |
986 test_decode_color >current &&
987 test_cmp expect.none current
991 test_expect_success 'test diff.wsErrorHighlight config' '
993 git -c diff.wsErrorHighlight=default,old diff --color |
994 test_decode_color >current &&
995 test_cmp expect.default-old current &&
997 git -c diff.wsErrorHighlight=all diff --color |
998 test_decode_color >current &&
999 test_cmp expect.all current &&
1001 git -c diff.wsErrorHighlight=none diff --color |
1002 test_decode_color >current &&
1003 test_cmp expect.none current
1007 test_expect_success 'option overrides diff.wsErrorHighlight' '
1009 git -c diff.wsErrorHighlight=none \
1010 diff --color --ws-error-highlight=default,old |
1011 test_decode_color >current &&
1012 test_cmp expect.default-old current &&
1014 git -c diff.wsErrorHighlight=default \
1015 diff --color --ws-error-highlight=all |
1016 test_decode_color >current &&
1017 test_cmp expect.all current &&
1019 git -c diff.wsErrorHighlight=all \
1020 diff --color --ws-error-highlight=none |
1021 test_decode_color >current &&
1022 test_cmp expect.none current
1026 test_expect_success 'detect moved code, complete file' '
1028 cat <<-\EOF >test.c &&
1032 printf("Hello World");
1036 git commit -m "add main function" &&
1037 file=$(git rev-parse --short HEAD:test.c) &&
1038 git mv test.c main.c &&
1039 test_config color.diff.oldMoved "normal red" &&
1040 test_config color.diff.newMoved "normal green" &&
1041 git diff HEAD --color-moved=zebra --color --no-renames | test_decode_color >actual &&
1042 cat >expected <<-EOF &&
1043 <BOLD>diff --git a/main.c b/main.c<RESET>
1044 <BOLD>new file mode 100644<RESET>
1045 <BOLD>index 0000000..$file<RESET>
1046 <BOLD>--- /dev/null<RESET>
1047 <BOLD>+++ b/main.c<RESET>
1048 <CYAN>@@ -0,0 +1,5 @@<RESET>
1049 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1050 <BGREEN>+<RESET><BGREEN>main()<RESET>
1051 <BGREEN>+<RESET><BGREEN>{<RESET>
1052 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1053 <BGREEN>+<RESET><BGREEN>}<RESET>
1054 <BOLD>diff --git a/test.c b/test.c<RESET>
1055 <BOLD>deleted file mode 100644<RESET>
1056 <BOLD>index $file..0000000<RESET>
1057 <BOLD>--- a/test.c<RESET>
1058 <BOLD>+++ /dev/null<RESET>
1059 <CYAN>@@ -1,5 +0,0 @@<RESET>
1060 <BRED>-#include<stdio.h><RESET>
1061 <BRED>-main()<RESET>
1063 <BRED>-printf("Hello World");<RESET>
1067 test_cmp expected actual
1070 test_expect_success 'detect malicious moved code, inside file' '
1071 test_config color.diff.oldMoved "normal red" &&
1072 test_config color.diff.newMoved "normal green" &&
1073 test_config color.diff.oldMovedAlternative "blue" &&
1074 test_config color.diff.newMovedAlternative "yellow" &&
1076 cat <<-\EOF >main.c &&
1084 int secure_foo(struct user *u)
1086 if (!u->is_allowed_foo)
1096 cat <<-\EOF >test.c &&
1100 printf("Hello World, but different\n");
1103 int another_function()
1108 git add main.c test.c &&
1109 git commit -m "add main and test file" &&
1110 before_main=$(git rev-parse --short HEAD:main.c) &&
1111 before_test=$(git rev-parse --short HEAD:test.c) &&
1112 cat <<-\EOF >main.c &&
1125 cat <<-\EOF >test.c &&
1129 printf("Hello World, but different\n");
1132 int secure_foo(struct user *u)
1135 if (!u->is_allowed_foo)
1139 int another_function()
1144 after_main=$(git rev-parse --short $(git hash-object main.c)) &&
1145 after_test=$(git rev-parse --short $(git hash-object test.c)) &&
1146 git diff HEAD --no-renames --color-moved=zebra --color | test_decode_color >actual &&
1147 cat <<-EOF >expected &&
1148 <BOLD>diff --git a/main.c b/main.c<RESET>
1149 <BOLD>index $before_main..$after_main 100644<RESET>
1150 <BOLD>--- a/main.c<RESET>
1151 <BOLD>+++ b/main.c<RESET>
1152 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1153 printf("World\n");<RESET>
1156 <BRED>-int secure_foo(struct user *u)<RESET>
1158 <BLUE>-if (!u->is_allowed_foo)<RESET>
1159 <BLUE>-return;<RESET>
1160 <RED>-foo(u);<RESET>
1166 <BOLD>diff --git a/test.c b/test.c<RESET>
1167 <BOLD>index $before_test..$after_test 100644<RESET>
1168 <BOLD>--- a/test.c<RESET>
1169 <BOLD>+++ b/test.c<RESET>
1170 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1171 printf("Hello World, but different\n");<RESET>
1174 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1175 <BGREEN>+<RESET><BGREEN>{<RESET>
1176 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1177 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1178 <BGREEN>+<RESET><BGREEN>return;<RESET>
1179 <GREEN>+<RESET><GREEN>}<RESET>
1181 int another_function()<RESET>
1186 test_cmp expected actual
1189 test_expect_success 'plain moved code, inside file' '
1190 test_config color.diff.oldMoved "normal red" &&
1191 test_config color.diff.newMoved "normal green" &&
1192 test_config color.diff.oldMovedAlternative "blue" &&
1193 test_config color.diff.newMovedAlternative "yellow" &&
1194 # needs previous test as setup
1195 git diff HEAD --no-renames --color-moved=plain --color | test_decode_color >actual &&
1196 cat <<-EOF >expected &&
1197 <BOLD>diff --git a/main.c b/main.c<RESET>
1198 <BOLD>index $before_main..$after_main 100644<RESET>
1199 <BOLD>--- a/main.c<RESET>
1200 <BOLD>+++ b/main.c<RESET>
1201 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1202 printf("World\n");<RESET>
1205 <BRED>-int secure_foo(struct user *u)<RESET>
1207 <BRED>-if (!u->is_allowed_foo)<RESET>
1208 <BRED>-return;<RESET>
1209 <BRED>-foo(u);<RESET>
1215 <BOLD>diff --git a/test.c b/test.c<RESET>
1216 <BOLD>index $before_test..$after_test 100644<RESET>
1217 <BOLD>--- a/test.c<RESET>
1218 <BOLD>+++ b/test.c<RESET>
1219 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1220 printf("Hello World, but different\n");<RESET>
1223 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1224 <BGREEN>+<RESET><BGREEN>{<RESET>
1225 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1226 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1227 <BGREEN>+<RESET><BGREEN>return;<RESET>
1228 <BGREEN>+<RESET><BGREEN>}<RESET>
1230 int another_function()<RESET>
1235 test_cmp expected actual
1238 test_expect_success 'detect blocks of moved code' '
1240 cat <<-\EOF >lines.txt &&
1258 git add lines.txt &&
1259 git commit -m "add poetry" &&
1260 cat <<-\EOF >lines.txt &&
1278 test_config color.diff.oldMoved "magenta" &&
1279 test_config color.diff.newMoved "cyan" &&
1280 test_config color.diff.oldMovedAlternative "blue" &&
1281 test_config color.diff.newMovedAlternative "yellow" &&
1282 test_config color.diff.oldMovedDimmed "normal magenta" &&
1283 test_config color.diff.newMovedDimmed "normal cyan" &&
1284 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1285 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1286 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1287 grep -v "index" actual.raw | test_decode_color >actual &&
1288 cat <<-\EOF >expected &&
1289 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1290 <BOLD>--- a/lines.txt<RESET>
1291 <BOLD>+++ b/lines.txt<RESET>
1292 <CYAN>@@ -1,16 +1,16 @@<RESET>
1293 <MAGENTA>-long line 1<RESET>
1294 <MAGENTA>-long line 2<RESET>
1295 <MAGENTA>-long line 3<RESET>
1302 <CYAN>+<RESET><CYAN>long line 1<RESET>
1303 <CYAN>+<RESET><CYAN>long line 2<RESET>
1304 <CYAN>+<RESET><CYAN>long line 3<RESET>
1305 <CYAN>+<RESET><CYAN>long line 14<RESET>
1306 <CYAN>+<RESET><CYAN>long line 15<RESET>
1307 <CYAN>+<RESET><CYAN>long line 16<RESET>
1312 <MAGENTA>-long line 14<RESET>
1313 <MAGENTA>-long line 15<RESET>
1314 <MAGENTA>-long line 16<RESET>
1316 test_cmp expected actual
1320 test_expect_success 'detect permutations inside moved code -- dimmed-zebra' '
1321 # reuse setup from test before!
1322 test_config color.diff.oldMoved "magenta" &&
1323 test_config color.diff.newMoved "cyan" &&
1324 test_config color.diff.oldMovedAlternative "blue" &&
1325 test_config color.diff.newMovedAlternative "yellow" &&
1326 test_config color.diff.oldMovedDimmed "normal magenta" &&
1327 test_config color.diff.newMovedDimmed "normal cyan" &&
1328 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1329 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1330 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1331 grep -v "index" actual.raw | test_decode_color >actual &&
1332 cat <<-\EOF >expected &&
1333 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1334 <BOLD>--- a/lines.txt<RESET>
1335 <BOLD>+++ b/lines.txt<RESET>
1336 <CYAN>@@ -1,16 +1,16 @@<RESET>
1337 <BMAGENTA>-long line 1<RESET>
1338 <BMAGENTA>-long line 2<RESET>
1339 <BMAGENTA>-long line 3<RESET>
1346 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1347 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1348 <CYAN>+<RESET><CYAN>long line 3<RESET>
1349 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1350 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1351 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1356 <BMAGENTA>-long line 14<RESET>
1357 <BMAGENTA>-long line 15<RESET>
1358 <BMAGENTA>-long line 16<RESET>
1360 test_cmp expected actual
1363 test_expect_success 'cmd option assumes configured colored-moved' '
1364 test_config color.diff.oldMoved "magenta" &&
1365 test_config color.diff.newMoved "cyan" &&
1366 test_config color.diff.oldMovedAlternative "blue" &&
1367 test_config color.diff.newMovedAlternative "yellow" &&
1368 test_config color.diff.oldMovedDimmed "normal magenta" &&
1369 test_config color.diff.newMovedDimmed "normal cyan" &&
1370 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1371 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1372 test_config diff.colorMoved zebra &&
1373 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1374 grep -v "index" actual.raw | test_decode_color >actual &&
1375 cat <<-\EOF >expected &&
1376 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1377 <BOLD>--- a/lines.txt<RESET>
1378 <BOLD>+++ b/lines.txt<RESET>
1379 <CYAN>@@ -1,16 +1,16 @@<RESET>
1380 <MAGENTA>-long line 1<RESET>
1381 <MAGENTA>-long line 2<RESET>
1382 <MAGENTA>-long line 3<RESET>
1389 <CYAN>+<RESET><CYAN>long line 1<RESET>
1390 <CYAN>+<RESET><CYAN>long line 2<RESET>
1391 <CYAN>+<RESET><CYAN>long line 3<RESET>
1392 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1393 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1394 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1399 <MAGENTA>-long line 14<RESET>
1400 <MAGENTA>-long line 15<RESET>
1401 <MAGENTA>-long line 16<RESET>
1403 test_cmp expected actual
1406 test_expect_success 'no effect from --color-moved with --word-diff' '
1407 cat <<-\EOF >text.txt &&
1408 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1411 git commit -a -m "clean state" &&
1412 cat <<-\EOF >text.txt &&
1413 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1415 git diff --color-moved --word-diff >actual &&
1416 git diff --word-diff >expect &&
1417 test_cmp expect actual
1420 test_expect_success 'set up whitespace tests' '
1422 # Note that these lines have no leading or trailing whitespace.
1423 cat <<-\EOF >lines.txt &&
1434 git add lines.txt &&
1435 git commit -m "add poetry" &&
1436 git config color.diff.oldMoved "magenta" &&
1437 git config color.diff.newMoved "cyan"
1440 test_expect_success 'move detection ignoring whitespace ' '
1441 q_to_tab <<-\EOF >lines.txt &&
1445 Qchanged long line 9
1452 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1453 grep -v "index" actual.raw | test_decode_color >actual &&
1454 cat <<-\EOF >expected &&
1455 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1456 <BOLD>--- a/lines.txt<RESET>
1457 <BOLD>+++ b/lines.txt<RESET>
1458 <CYAN>@@ -1,9 +1,9 @@<RESET>
1459 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1460 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1461 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1462 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1468 <RED>-long line 6<RESET>
1469 <RED>-long line 7<RESET>
1470 <RED>-long line 8<RESET>
1471 <RED>-long line 9<RESET>
1473 test_cmp expected actual &&
1475 git diff HEAD --no-renames --color-moved --color \
1476 --color-moved-ws=ignore-all-space >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 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1484 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1485 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1486 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1492 <MAGENTA>-long line 6<RESET>
1493 <MAGENTA>-long line 7<RESET>
1494 <MAGENTA>-long line 8<RESET>
1495 <RED>-long line 9<RESET>
1497 test_cmp expected actual
1500 test_expect_success 'move detection ignoring whitespace changes' '
1502 # Lines 6-8 have a space change, but 9 is new whitespace
1503 q_to_tab <<-\EOF >lines.txt &&
1515 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1516 grep -v "index" actual.raw | test_decode_color >actual &&
1517 cat <<-\EOF >expected &&
1518 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1519 <BOLD>--- a/lines.txt<RESET>
1520 <BOLD>+++ b/lines.txt<RESET>
1521 <CYAN>@@ -1,9 +1,9 @@<RESET>
1522 <GREEN>+<RESET><GREEN>long line 6<RESET>
1523 <GREEN>+<RESET><GREEN>long line 7<RESET>
1524 <GREEN>+<RESET><GREEN>long line 8<RESET>
1525 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1531 <RED>-long line 6<RESET>
1532 <RED>-long line 7<RESET>
1533 <RED>-long line 8<RESET>
1534 <RED>-long line 9<RESET>
1536 test_cmp expected actual &&
1538 git diff HEAD --no-renames --color-moved --color \
1539 --color-moved-ws=ignore-space-change >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 <CYAN>+<RESET><CYAN>long line 6<RESET>
1547 <CYAN>+<RESET><CYAN>long line 7<RESET>
1548 <CYAN>+<RESET><CYAN>long line 8<RESET>
1549 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1555 <MAGENTA>-long line 6<RESET>
1556 <MAGENTA>-long line 7<RESET>
1557 <MAGENTA>-long line 8<RESET>
1558 <RED>-long line 9<RESET>
1560 test_cmp expected actual
1563 test_expect_success 'move detection ignoring whitespace at eol' '
1565 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1566 q_to_tab <<-\EOF >lines.txt &&
1578 # avoid cluttering the output with complaints about our eol whitespace
1579 test_config core.whitespace -blank-at-eol &&
1581 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1582 grep -v "index" actual.raw | test_decode_color >actual &&
1583 cat <<-\EOF >expected &&
1584 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1585 <BOLD>--- a/lines.txt<RESET>
1586 <BOLD>+++ b/lines.txt<RESET>
1587 <CYAN>@@ -1,9 +1,9 @@<RESET>
1588 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1589 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1590 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1591 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1597 <RED>-long line 6<RESET>
1598 <RED>-long line 7<RESET>
1599 <RED>-long line 8<RESET>
1600 <RED>-long line 9<RESET>
1602 test_cmp expected actual &&
1604 git diff HEAD --no-renames --color-moved --color \
1605 --color-moved-ws=ignore-space-at-eol >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 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1613 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1614 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1615 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1621 <MAGENTA>-long line 6<RESET>
1622 <MAGENTA>-long line 7<RESET>
1623 <MAGENTA>-long line 8<RESET>
1624 <RED>-long line 9<RESET>
1626 test_cmp expected actual
1629 test_expect_success 'clean up whitespace-test colors' '
1630 git config --unset color.diff.oldMoved &&
1631 git config --unset color.diff.newMoved
1634 test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1651 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1652 grep -v "index" actual.raw | test_decode_color >actual &&
1653 cat >expected <<-\EOF &&
1654 <BOLD>diff --git a/bar b/bar<RESET>
1655 <BOLD>--- a/bar<RESET>
1656 <BOLD>+++ b/bar<RESET>
1657 <CYAN>@@ -0,0 +1 @@<RESET>
1658 <GREEN>+<RESET><GREEN>line1<RESET>
1659 <BOLD>diff --git a/foo b/foo<RESET>
1660 <BOLD>--- a/foo<RESET>
1661 <BOLD>+++ b/foo<RESET>
1662 <CYAN>@@ -1,2 +1 @@<RESET>
1663 irrelevant_line<RESET>
1667 test_cmp expected actual
1670 test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
1673 nineteen chars 456789
1675 twenty chars 234567890
1685 twenty chars 234567890
1686 nineteen chars 456789
1689 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1690 grep -v "index" actual.raw | test_decode_color >actual &&
1691 cat >expected <<-\EOF &&
1692 <BOLD>diff --git a/bar b/bar<RESET>
1693 <BOLD>--- a/bar<RESET>
1694 <BOLD>+++ b/bar<RESET>
1695 <CYAN>@@ -0,0 +1,2 @@<RESET>
1696 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1697 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1698 <BOLD>diff --git a/foo b/foo<RESET>
1699 <BOLD>--- a/foo<RESET>
1700 <BOLD>+++ b/foo<RESET>
1701 <CYAN>@@ -1,3 +1 @@<RESET>
1702 <RED>-nineteen chars 456789<RESET>
1703 irrelevant_line<RESET>
1704 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1707 test_cmp expected actual
1710 test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1731 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1732 grep -v "index" actual.raw | test_decode_color >actual &&
1733 cat >expected <<-\EOF &&
1734 <BOLD>diff --git a/bar b/bar<RESET>
1735 <BOLD>--- a/bar<RESET>
1736 <BOLD>+++ b/bar<RESET>
1737 <CYAN>@@ -0,0 +1,3 @@<RESET>
1738 <GREEN>+<RESET><GREEN>7charsB<RESET>
1739 <GREEN>+<RESET><GREEN>7charsC<RESET>
1740 <GREEN>+<RESET><GREEN>7charsA<RESET>
1741 <BOLD>diff --git a/foo b/foo<RESET>
1742 <BOLD>--- a/foo<RESET>
1743 <BOLD>+++ b/foo<RESET>
1744 <CYAN>@@ -1,4 +1 @@<RESET>
1745 <RED>-7charsA<RESET>
1746 irrelevant_line<RESET>
1747 <RED>-7charsB<RESET>
1748 <RED>-7charsC<RESET>
1751 test_cmp expected actual
1754 test_expect_success 'move detection with submodules' '
1755 test_create_repo bananas &&
1756 echo ripe >bananas/recipe &&
1757 git -C bananas add recipe &&
1758 test_commit fruit &&
1759 test_commit -C bananas recipe &&
1760 git submodule add ./bananas &&
1762 git commit -a -m "bananas are like a heavy library?" &&
1763 echo foul >bananas/recipe &&
1764 echo ripe >fruit.t &&
1766 git diff --submodule=diff --color-moved --color >actual &&
1768 # no move detection as the moved line is across repository boundaries.
1769 test_decode_color <actual >decoded_actual &&
1770 ! grep BGREEN decoded_actual &&
1771 ! grep BRED decoded_actual &&
1773 # nor did we mess with it another way
1774 git diff --submodule=diff --color | test_decode_color >expect &&
1775 test_cmp expect decoded_actual &&
1777 git submodule deinit bananas
1780 test_expect_success 'only move detection ignores white spaces' '
1782 q_to_tab <<-\EOF >text.txt &&
1783 a long line to exceed per-line minimum
1784 another long line to exceed per-line minimum
1788 git commit -m "add text" &&
1789 q_to_tab <<-\EOF >text.txt &&
1790 Qa long line to exceed per-line minimum
1791 Qanother long line to exceed per-line minimum
1795 # Make sure we get a different diff using -w
1796 git diff --color --color-moved -w >actual.raw &&
1797 grep -v "index" actual.raw | test_decode_color >actual &&
1798 q_to_tab <<-\EOF >expected &&
1799 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1800 <BOLD>--- a/text.txt<RESET>
1801 <BOLD>+++ b/text.txt<RESET>
1802 <CYAN>@@ -1,3 +1,3 @@<RESET>
1803 Qa long line to exceed per-line minimum<RESET>
1804 Qanother long line to exceed per-line minimum<RESET>
1805 <RED>-original file<RESET>
1806 <GREEN>+<RESET><GREEN>new file<RESET>
1808 test_cmp expected actual &&
1810 # And now ignoring white space only in the move detection
1811 git diff --color --color-moved \
1812 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
1813 grep -v "index" actual.raw | test_decode_color >actual &&
1814 q_to_tab <<-\EOF >expected &&
1815 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1816 <BOLD>--- a/text.txt<RESET>
1817 <BOLD>+++ b/text.txt<RESET>
1818 <CYAN>@@ -1,3 +1,3 @@<RESET>
1819 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
1820 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
1821 <RED>-original file<RESET>
1822 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>a long line to exceed per-line minimum<RESET>
1823 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>another long line to exceed per-line minimum<RESET>
1824 <GREEN>+<RESET><GREEN>new file<RESET>
1826 test_cmp expected actual
1829 test_expect_success 'compare whitespace delta across moved blocks' '
1832 q_to_tab <<-\EOF >text.txt &&
1836 QBut! <- this stands out
1838 QQdifferent starting
1844 QQQthat has similar lines
1845 QQQto previous blocks, but with different indent
1846 QQQYetQAnotherQoutlierQ
1847 QLine with internal w h i t e s p a c e change
1851 git commit -m "add text.txt" &&
1853 q_to_tab <<-\EOF >text.txt &&
1857 QQQBut! <- this stands out
1865 QQthat has similar lines
1866 QQto previous blocks, but with different indent
1867 QQYetQAnotherQoutlier
1868 QLine with internal whitespace change
1871 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
1872 grep -v "index" actual.raw | test_decode_color >actual &&
1874 q_to_tab <<-\EOF >expected &&
1875 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1876 <BOLD>--- a/text.txt<RESET>
1877 <BOLD>+++ b/text.txt<RESET>
1878 <CYAN>@@ -1,15 +1,15 @@<RESET>
1879 <BOLD;MAGENTA>-QIndented<RESET>
1880 <BOLD;MAGENTA>-QText across<RESET>
1881 <BOLD;MAGENTA>-Qsome lines<RESET>
1882 <RED>-QBut! <- this stands out<RESET>
1883 <BOLD;MAGENTA>-QAdjusting with<RESET>
1884 <BOLD;MAGENTA>-QQdifferent starting<RESET>
1885 <BOLD;MAGENTA>-Qwhite spaces<RESET>
1886 <RED>-QAnother outlier<RESET>
1887 <BOLD;MAGENTA>-QQQIndented<RESET>
1888 <BOLD;MAGENTA>-QQQText across<RESET>
1889 <BOLD;MAGENTA>-QQQfive lines<RESET>
1890 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
1891 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
1892 <RED>-QQQYetQAnotherQoutlierQ<RESET>
1893 <RED>-QLine with internal w h i t e s p a c e change<RESET>
1894 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1895 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1896 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
1897 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
1898 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
1899 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
1900 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
1901 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
1902 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1903 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1904 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
1905 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
1906 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
1907 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
1908 <GREEN>+<RESET>Q<GREEN>Line with internal whitespace change<RESET>
1911 test_cmp expected actual
1914 test_expect_success 'bogus settings in move detection erroring out' '
1915 test_must_fail git diff --color-moved=bogus 2>err &&
1916 test_i18ngrep "must be one of" err &&
1917 test_i18ngrep bogus err &&
1919 test_must_fail git -c diff.colormoved=bogus diff 2>err &&
1920 test_i18ngrep "must be one of" err &&
1921 test_i18ngrep "from command-line config" err &&
1923 test_must_fail git diff --color-moved-ws=bogus 2>err &&
1924 test_i18ngrep "possible values" err &&
1925 test_i18ngrep bogus err &&
1927 test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
1928 test_i18ngrep "possible values" err &&
1929 test_i18ngrep "from command-line config" err
1932 test_expect_success 'compare whitespace delta incompatible with other space options' '
1933 test_must_fail git diff \
1934 --color-moved-ws=allow-indentation-change,ignore-all-space \
1936 test_i18ngrep allow-indentation-change err
1940 test_expect_success 'compare mixed whitespace delta across moved blocks' '
1943 tr Q_ "\t " <<-EOF >text.txt &&
1945 ____too short without
1947 ___being grouped across blank line
1953 ____Indented text to
1954 _Q____be further indented by four spaces across
1956 QQ____These two lines have had their
1957 ____indentation reduced by four spaces
1958 Qdifferent indentation change
1963 git commit -m "add text.txt" &&
1965 tr Q_ "\t " <<-EOF >text.txt &&
1971 QQbe further indented by four spaces across
1976 Q_______being grouped across blank line
1978 Q_QThese two lines have had their
1979 indentation reduced by four spaces
1980 QQdifferent indentation change
1984 git -c color.diff.whitespace="normal red" \
1985 -c core.whitespace=space-before-tab \
1986 diff --color --color-moved --ws-error-highlight=all \
1987 --color-moved-ws=allow-indentation-change >actual.raw &&
1988 grep -v "index" actual.raw | test_decode_color >actual &&
1990 cat <<-\EOF >expected &&
1991 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1992 <BOLD>--- a/text.txt<RESET>
1993 <BOLD>+++ b/text.txt<RESET>
1994 <CYAN>@@ -1,16 +1,16 @@<RESET>
1995 <BOLD;MAGENTA>-<RESET>
1996 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> too short without<RESET>
1997 <BOLD;MAGENTA>-<RESET>
1998 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
1999 <BOLD;MAGENTA>-<RESET>
2000 <RESET>context<RESET>
2003 <RESET>anchor<RESET>
2004 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
2005 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
2006 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
2007 <BOLD;BLUE>-<RESET> <BOLD;BLUE> These two lines have had their<RESET>
2008 <BOLD;BLUE>-<RESET><BOLD;BLUE> indentation reduced by four spaces<RESET>
2009 <BOLD;MAGENTA>-<RESET> <BOLD;MAGENTA>different indentation change<RESET>
2010 <RED>-<RESET><RED> too short<RESET>
2011 <BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
2012 <BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
2013 <BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
2014 <BOLD;YELLOW>+<RESET>
2015 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
2016 <BOLD;YELLOW>+<RESET>
2017 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW> being grouped across blank line<RESET>
2018 <BOLD;YELLOW>+<RESET>
2019 <BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
2020 <BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
2021 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
2022 <GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
2025 test_cmp expected actual
2028 # Note that the "6" in the expected hunk header below is funny, since we only
2029 # show 5 lines (the missing one was blank and thus ignored). This is how
2030 # --ignore-blank-lines behaves even without --function-context, and this test
2031 # is just checking the interaction of the two features. Don't take it as an
2032 # endorsement of that output.
2033 test_expect_success 'combine --ignore-blank-lines with --function-context' '
2034 test_write_lines 1 "" 2 3 4 5 >a &&
2035 test_write_lines 1 2 3 4 >b &&
2036 test_must_fail git diff --no-index \
2037 --ignore-blank-lines --function-context a b >actual.raw &&
2038 sed -n "/@@/,\$p" <actual.raw >actual &&
2039 cat <<-\EOF >expect &&
2047 test_cmp expect actual