3 # Copyright (c) 2006 Johannes E. Schindelin
6 test_description
='Test special whitespace in diff engine.
10 .
"$TEST_DIRECTORY"/lib-diff.sh
12 test_expect_success
"Ray Lehtiniemi's example" '
18 git update-index --add x &&
19 old_hash_x=$(git hash-object x) &&
20 before=$(git rev-parse --short "$old_hash_x") &&
29 new_hash_x=$(git hash-object x) &&
30 after=$(git rev-parse --short "$new_hash_x") &&
34 index $before..$after 100644
48 test_cmp expect out &&
51 test_cmp expect out &&
57 test_expect_success
'another test, without options' '
58 tr Q "\015" <<-\EOF >x &&
59 whitespace at beginning
61 whitespace in the middle
68 old_hash_x=$(git hash-object x) &&
69 before=$(git rev-parse --short "$old_hash_x") &&
71 tr "_" " " <<-\EOF >x &&
72 _ whitespace at beginning
74 white space in the middle
79 new_hash_x=$(git hash-object x) &&
80 after=$(git rev-parse --short "$new_hash_x") &&
82 tr "Q_" "\015 " <<-EOF >expect &&
84 index $before..$after 100644
88 -whitespace at beginning
90 -whitespace in the middle
92 + whitespace at beginning
94 +white space in the middle
102 test_cmp expect out &&
105 test_must_be_empty out &&
107 git diff -w -b >out &&
108 test_must_be_empty out &&
110 git diff -w --ignore-space-at-eol >out &&
111 test_must_be_empty out &&
113 git diff -w -b --ignore-space-at-eol >out &&
114 test_must_be_empty out &&
116 git diff -w --ignore-cr-at-eol >out &&
117 test_must_be_empty out &&
119 tr "Q_" "\015 " <<-EOF >expect &&
121 index $before..$after 100644
125 -whitespace at beginning
126 +_ whitespace at beginning
128 -whitespace in the middle
129 +white space in the middle
135 test_cmp expect out &&
137 git diff -b --ignore-space-at-eol >out &&
138 test_cmp expect out &&
140 git diff -b --ignore-cr-at-eol >out &&
141 test_cmp expect out &&
143 tr "Q_" "\015 " <<-EOF >expect &&
145 index $before..$after 100644
149 -whitespace at beginning
151 -whitespace in the middle
152 +_ whitespace at beginning
154 +white space in the middle
159 git diff --ignore-space-at-eol >out &&
160 test_cmp expect out &&
162 git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
163 test_cmp expect out &&
165 tr "Q_" "\015 " <<-EOF >expect &&
167 index_$before..$after 100644
171 -whitespace at beginning
173 -whitespace in the middle
175 +_ whitespace at beginning
177 +white space in the middle
182 git diff --ignore-cr-at-eol >out &&
186 test_expect_success
'ignore-blank-lines: only new lines' '
188 git update-index x &&
189 test_seq 5 | sed "/3/i\\
191 git diff --ignore-blank-lines >out &&
192 test_must_be_empty out
195 test_expect_success
'ignore-blank-lines: only new lines with space' '
197 git update-index x &&
198 test_seq 5 | sed "/3/i\\
200 git diff -w --ignore-blank-lines >out &&
201 test_must_be_empty out
204 test_expect_success
'ignore-blank-lines: after change' '
216 git update-index x &&
229 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
230 cat <<-\EOF >expected &&
244 compare_diff_patch expected out.tmp
247 test_expect_success
'ignore-blank-lines: before change' '
258 git update-index x &&
271 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
272 cat <<-\EOF >expected &&
285 compare_diff_patch expected out.tmp
288 test_expect_success
'ignore-blank-lines: between changes' '
303 git update-index x &&
320 git diff --ignore-blank-lines >out.tmp &&
321 cat <<-\EOF >expected &&
342 compare_diff_patch expected out.tmp
345 test_expect_success
'ignore-blank-lines: between changes (with interhunkctx)' '
347 git update-index x &&
365 git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
366 cat <<-\EOF >expected &&
387 compare_diff_patch expected out.tmp
390 test_expect_success
'ignore-blank-lines: scattered spaces' '
392 git update-index x &&
413 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
414 cat <<-\EOF >expected &&
429 compare_diff_patch expected out.tmp
432 test_expect_success
'ignore-blank-lines: spaces coalesce' '
434 git update-index x &&
448 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
449 cat <<-\EOF >expected &&
466 compare_diff_patch expected out.tmp
469 test_expect_success
'ignore-blank-lines: mix changes and blank lines' '
471 git update-index x &&
497 git diff --ignore-blank-lines >out.tmp &&
498 cat <<-\EOF >expected &&
527 compare_diff_patch expected out.tmp
530 test_expect_success
'check mixed spaces and tabs in indent' '
531 # This is indented with SP HT SP.
533 test_must_fail git diff --check >check &&
534 grep "space before tab in indent" check
537 test_expect_success
'check mixed tabs and spaces in indent' '
538 # This is indented with HT SP HT.
540 test_must_fail git diff --check >check &&
541 grep "space before tab in indent" check
544 test_expect_success
'check with no whitespace errors' '
545 git commit -m "snapshot" &&
550 test_expect_success
'check with trailing whitespace' '
552 test_must_fail git diff --check
555 test_expect_success
'check with space before tab in indent' '
556 # indent has space followed by hard tab
558 test_must_fail git diff --check
561 test_expect_success
'--check and --exit-code are not exclusive' '
563 git diff --check --exit-code
566 test_expect_success
'--check and --quiet are not exclusive' '
567 git diff --check --quiet
570 test_expect_success
'-w and --exit-code interact sensibly' '
571 test_when_finished "git checkout x" &&
576 test_must_fail git diff --exit-code &&
577 git diff -w >actual &&
578 test_must_be_empty actual &&
579 git diff -w --exit-code
582 test_expect_success
'-I and --exit-code interact sensibly' '
583 test_when_finished "git checkout x" &&
588 test_must_fail git diff --exit-code &&
589 git diff -I. >actual &&
590 test_must_be_empty actual &&
591 git diff -I. --exit-code
594 test_expect_success
'check staged with no whitespace errors' '
597 git diff --cached --check
600 test_expect_success
'check staged with trailing whitespace' '
603 test_must_fail git diff --cached --check
606 test_expect_success
'check staged with space before tab in indent' '
607 # indent has space followed by hard tab
610 test_must_fail git diff --cached --check
613 test_expect_success
'check with no whitespace errors (diff-index)' '
616 git diff-index --check HEAD
619 test_expect_success
'check with trailing whitespace (diff-index)' '
622 test_must_fail git diff-index --check HEAD
625 test_expect_success
'check with space before tab in indent (diff-index)' '
626 # indent has space followed by hard tab
629 test_must_fail git diff-index --check HEAD
632 test_expect_success
'check staged with no whitespace errors (diff-index)' '
635 git diff-index --cached --check HEAD
638 test_expect_success
'check staged with trailing whitespace (diff-index)' '
641 test_must_fail git diff-index --cached --check HEAD
644 test_expect_success
'check staged with space before tab in indent (diff-index)' '
645 # indent has space followed by hard tab
648 test_must_fail git diff-index --cached --check HEAD
651 test_expect_success
'check with no whitespace errors (diff-tree)' '
653 git commit -m "new commit" x &&
654 git diff-tree --check HEAD^ HEAD
657 test_expect_success
'check with trailing whitespace (diff-tree)' '
659 git commit -m "another commit" x &&
660 test_must_fail git diff-tree --check HEAD^ HEAD
663 test_expect_success
'check with space before tab in indent (diff-tree)' '
664 # indent has space followed by hard tab
666 git commit -m "yet another" x &&
667 test_must_fail git diff-tree --check HEAD^ HEAD
670 test_expect_success
'check with ignored trailing whitespace attr (diff-tree)' '
671 test_when_finished "git reset --hard HEAD^" &&
673 # create a whitespace error that should be ignored
674 echo "* -whitespace" >.gitattributes &&
675 git add .gitattributes &&
678 git commit -m "add trailing space" &&
680 # with a worktree diff-tree ignores the whitespace error
681 git diff-tree --root --check HEAD &&
683 # without a worktree diff-tree still ignores the whitespace error
684 git -C .git diff-tree --root --check HEAD
687 test_expect_success
'check trailing whitespace (trailing-space: off)' '
688 git config core.whitespace "-trailing-space" &&
689 echo "foo (); " >x &&
693 test_expect_success
'check trailing whitespace (trailing-space: on)' '
694 git config core.whitespace "trailing-space" &&
695 echo "foo (); " >x &&
696 test_must_fail git diff --check
699 test_expect_success
'check space before tab in indent (space-before-tab: off)' '
700 # indent contains space followed by HT
701 git config core.whitespace "-space-before-tab" &&
702 echo " foo ();" >x &&
706 test_expect_success
'check space before tab in indent (space-before-tab: on)' '
707 # indent contains space followed by HT
708 git config core.whitespace "space-before-tab" &&
709 echo " foo (); " >x &&
710 test_must_fail git diff --check
713 test_expect_success
'check spaces as indentation (indent-with-non-tab: off)' '
714 git config core.whitespace "-indent-with-non-tab" &&
715 echo " foo ();" >x &&
719 test_expect_success
'check spaces as indentation (indent-with-non-tab: on)' '
720 git config core.whitespace "indent-with-non-tab" &&
721 echo " foo ();" >x &&
722 test_must_fail git diff --check
725 test_expect_success
'ditto, but tabwidth=9' '
726 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
730 test_expect_success
'check tabs and spaces as indentation (indent-with-non-tab: on)' '
731 git config core.whitespace "indent-with-non-tab" &&
732 echo " foo ();" >x &&
733 test_must_fail git diff --check
736 test_expect_success
'ditto, but tabwidth=10' '
737 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
738 test_must_fail git diff --check
741 test_expect_success
'ditto, but tabwidth=20' '
742 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
746 test_expect_success
'check tabs as indentation (tab-in-indent: off)' '
747 git config core.whitespace "-tab-in-indent" &&
748 echo " foo ();" >x &&
752 test_expect_success
'check tabs as indentation (tab-in-indent: on)' '
753 git config core.whitespace "tab-in-indent" &&
754 echo " foo ();" >x &&
755 test_must_fail git diff --check
758 test_expect_success
'check tabs and spaces as indentation (tab-in-indent: on)' '
759 git config core.whitespace "tab-in-indent" &&
760 echo " foo ();" >x &&
761 test_must_fail git diff --check
764 test_expect_success
'ditto, but tabwidth=1 (must be irrelevant)' '
765 git config core.whitespace "tab-in-indent,tabwidth=1" &&
766 test_must_fail git diff --check
769 test_expect_success
'check tab-in-indent and indent-with-non-tab conflict' '
770 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
772 test_must_fail git diff --check
775 test_expect_success
'check tab-in-indent excluded from wildcard whitespace attribute' '
776 git config --unset core.whitespace &&
777 echo "x whitespace" >.gitattributes &&
778 echo " foo ();" >x &&
783 test_expect_success
'line numbers in --check output are correct' '
785 echo "foo(); " >>x &&
786 test_must_fail git diff --check >check &&
790 test_expect_success
'checkdiff detects new trailing blank lines (1)' '
793 test_must_fail git diff --check >check &&
794 grep "new blank line" check
797 test_expect_success
'checkdiff detects new trailing blank lines (2)' '
798 test_write_lines a b "" "" >x &&
800 test_write_lines a "" "" "" "" >x &&
801 test_must_fail git diff --check >check &&
802 grep "new blank line" check
805 test_expect_success
'checkdiff allows new blank lines' '
809 echo "/* This is new */" &&
816 test_expect_success
'whitespace-only changes not reported (diff)' '
818 echo >x "hello world" &&
820 git commit -m "hello 1" &&
821 echo >x "hello world" &&
822 git diff -b >actual &&
823 test_must_be_empty actual
826 test_expect_success
'whitespace-only changes not reported (diffstat)' '
827 # reuse state from previous test
828 git diff --stat -b >actual &&
829 test_must_be_empty actual
832 test_expect_success
'whitespace changes with modification reported (diffstat)' '
834 echo >x "hello world" &&
835 git update-index --chmod=+x x &&
836 git diff --stat --cached -b >actual &&
837 cat <<-EOF >expect &&
839 1 file changed, 0 insertions(+), 0 deletions(-)
841 test_cmp expect actual
844 test_expect_success
'whitespace-only changes reported across renames (diffstat)' '
846 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
848 git commit -m "base" &&
849 sed -e "5s/^/ /" x >z &&
852 git diff -w -M --cached --stat >actual &&
853 cat <<-EOF >expect &&
855 1 file changed, 0 insertions(+), 0 deletions(-)
857 test_cmp expect actual
860 test_expect_success
'whitespace-only changes reported across renames' '
861 git reset --hard HEAD~1 &&
862 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
864 hash_x=$(git hash-object x) &&
865 before=$(git rev-parse --short "$hash_x") &&
866 git commit -m "base" &&
867 sed -e "5s/^/ /" x >z &&
870 hash_z=$(git hash-object z) &&
871 after=$(git rev-parse --short "$hash_z") &&
872 git diff -w -M --cached >actual.raw &&
873 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" actual.raw >actual &&
874 cat <<-EOF >expect &&
876 similarity index NUM%
879 index $before..$after 100644
881 test_cmp expect actual
885 diff --git a
/empty b
/void
886 similarity index
100%
891 test_expect_success
'rename empty' '
895 git commit -m empty &&
897 git diff -w --cached -M >current &&
898 test_cmp expected current
901 test_expect_success
'combined diff with autocrlf conversion' '
904 test_commit "one side" x hello one-side &&
905 git checkout HEAD^ &&
907 git commit -m "the other side" x &&
908 git config core.autocrlf true &&
909 test_must_fail git merge one-side >actual &&
910 test_i18ngrep "Automatic merge failed" actual &&
912 git diff >actual.raw &&
913 sed -e "1,/^@@@/d" actual.raw >actual &&
918 # Start testing the colored format for whitespace checks
920 test_expect_success
'setup diff colors' '
921 git config color.diff.plain normal &&
922 git config color.diff.meta bold &&
923 git config color.diff.frag cyan &&
924 git config color.diff.func normal &&
925 git config color.diff.old red &&
926 git config color.diff.new green &&
927 git config color.diff.commit yellow &&
928 git config color.diff.whitespace blue &&
930 git config core.autocrlf false
933 test_expect_success
'diff that introduces a line with only tabs' '
934 git config core.whitespace blank-at-eol &&
937 old_hash_x=$(git hash-object x) &&
938 before=$(git rev-parse --short "$old_hash_x") &&
939 git commit -m "initial" x &&
940 echo "{NTN}" | tr "NT" "\n\t" >>x &&
941 new_hash_x=$(git hash-object x) &&
942 after=$(git rev-parse --short "$new_hash_x") &&
943 git diff --color >current.raw &&
944 test_decode_color <current.raw >current &&
946 cat >expected <<-EOF &&
947 <BOLD>diff --git a/x b/x<RESET>
948 <BOLD>index $before..$after 100644<RESET>
951 <CYAN>@@ -1 +1,4 @@<RESET>
953 <GREEN>+<RESET><GREEN>{<RESET>
954 <GREEN>+<RESET><BLUE> <RESET>
955 <GREEN>+<RESET><GREEN>}<RESET>
958 test_cmp expected current
961 test_expect_success
'diff that introduces and removes ws breakages' '
964 echo "0. blank-at-eol " &&
965 echo "1. blank-at-eol "
967 old_hash_x=$(git hash-object x) &&
968 before=$(git rev-parse --short "$old_hash_x") &&
969 git commit -a --allow-empty -m preimage &&
971 echo "0. blank-at-eol " &&
972 echo "1. still-blank-at-eol " &&
973 echo "2. and a new line "
975 new_hash_x=$(git hash-object x) &&
976 after=$(git rev-parse --short "$new_hash_x") &&
978 git diff --color >current.raw &&
979 test_decode_color <current.raw >current &&
981 cat >expected <<-EOF &&
982 <BOLD>diff --git a/x b/x<RESET>
983 <BOLD>index $before..$after 100644<RESET>
986 <CYAN>@@ -1,2 +1,3 @@<RESET>
987 0. blank-at-eol <RESET>
988 <RED>-1. blank-at-eol <RESET>
989 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
990 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
993 test_cmp expected current
996 test_expect_success
'ws-error-highlight test setup' '
1000 echo "0. blank-at-eol " &&
1001 echo "1. blank-at-eol "
1003 old_hash_x=$(git hash-object x) &&
1004 before=$(git rev-parse --short "$old_hash_x") &&
1005 git commit -a --allow-empty -m preimage &&
1007 echo "0. blank-at-eol " &&
1008 echo "1. still-blank-at-eol " &&
1009 echo "2. and a new line "
1011 new_hash_x=$(git hash-object x) &&
1012 after=$(git rev-parse --short "$new_hash_x") &&
1014 cat >expect.default-old <<-EOF &&
1015 <BOLD>diff --git a/x b/x<RESET>
1016 <BOLD>index $before..$after 100644<RESET>
1017 <BOLD>--- a/x<RESET>
1018 <BOLD>+++ b/x<RESET>
1019 <CYAN>@@ -1,2 +1,3 @@<RESET>
1020 0. blank-at-eol <RESET>
1021 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1022 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1023 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1026 cat >expect.all <<-EOF &&
1027 <BOLD>diff --git a/x b/x<RESET>
1028 <BOLD>index $before..$after 100644<RESET>
1029 <BOLD>--- a/x<RESET>
1030 <BOLD>+++ b/x<RESET>
1031 <CYAN>@@ -1,2 +1,3 @@<RESET>
1032 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
1033 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1034 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1035 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1038 cat >expect.none <<-EOF
1039 <BOLD>diff --git a/x b/x<RESET>
1040 <BOLD>index $before..$after 100644<RESET>
1041 <BOLD>--- a/x<RESET>
1042 <BOLD>+++ b/x<RESET>
1043 <CYAN>@@ -1,2 +1,3 @@<RESET>
1044 0. blank-at-eol <RESET>
1045 <RED>-1. blank-at-eol <RESET>
1046 <GREEN>+1. still-blank-at-eol <RESET>
1047 <GREEN>+2. and a new line <RESET>
1052 test_expect_success
'test --ws-error-highlight option' '
1054 git diff --color --ws-error-highlight=default,old >current.raw &&
1055 test_decode_color <current.raw >current &&
1056 test_cmp expect.default-old current &&
1058 git diff --color --ws-error-highlight=all >current.raw &&
1059 test_decode_color <current.raw >current &&
1060 test_cmp expect.all current &&
1062 git diff --color --ws-error-highlight=none >current.raw &&
1063 test_decode_color <current.raw >current &&
1064 test_cmp expect.none current
1068 test_expect_success
'test diff.wsErrorHighlight config' '
1070 git -c diff.wsErrorHighlight=default,old diff --color >current.raw &&
1071 test_decode_color <current.raw >current &&
1072 test_cmp expect.default-old current &&
1074 git -c diff.wsErrorHighlight=all diff --color >current.raw &&
1075 test_decode_color <current.raw >current &&
1076 test_cmp expect.all current &&
1078 git -c diff.wsErrorHighlight=none diff --color >current.raw &&
1079 test_decode_color <current.raw >current &&
1080 test_cmp expect.none current
1084 test_expect_success
'option overrides diff.wsErrorHighlight' '
1086 git -c diff.wsErrorHighlight=none \
1087 diff --color --ws-error-highlight=default,old >current.raw &&
1088 test_decode_color <current.raw >current &&
1089 test_cmp expect.default-old current &&
1091 git -c diff.wsErrorHighlight=default \
1092 diff --color --ws-error-highlight=all >current.raw &&
1093 test_decode_color <current.raw >current &&
1094 test_cmp expect.all current &&
1096 git -c diff.wsErrorHighlight=all \
1097 diff --color --ws-error-highlight=none >current.raw &&
1098 test_decode_color <current.raw >current &&
1099 test_cmp expect.none current
1103 test_expect_success
'detect moved code, complete file' '
1105 cat <<-\EOF >test.c &&
1109 printf("Hello World");
1113 git commit -m "add main function" &&
1114 file=$(git rev-parse --short HEAD:test.c) &&
1115 git mv test.c main.c &&
1116 test_config color.diff.oldMoved "normal red" &&
1117 test_config color.diff.newMoved "normal green" &&
1118 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1119 test_decode_color <actual.raw >actual &&
1120 cat >expected <<-EOF &&
1121 <BOLD>diff --git a/main.c b/main.c<RESET>
1122 <BOLD>new file mode 100644<RESET>
1123 <BOLD>index 0000000..$file<RESET>
1124 <BOLD>--- /dev/null<RESET>
1125 <BOLD>+++ b/main.c<RESET>
1126 <CYAN>@@ -0,0 +1,5 @@<RESET>
1127 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1128 <BGREEN>+<RESET><BGREEN>main()<RESET>
1129 <BGREEN>+<RESET><BGREEN>{<RESET>
1130 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1131 <BGREEN>+<RESET><BGREEN>}<RESET>
1132 <BOLD>diff --git a/test.c b/test.c<RESET>
1133 <BOLD>deleted file mode 100644<RESET>
1134 <BOLD>index $file..0000000<RESET>
1135 <BOLD>--- a/test.c<RESET>
1136 <BOLD>+++ /dev/null<RESET>
1137 <CYAN>@@ -1,5 +0,0 @@<RESET>
1138 <BRED>-#include<stdio.h><RESET>
1139 <BRED>-main()<RESET>
1141 <BRED>-printf("Hello World");<RESET>
1145 test_cmp expected actual
1148 test_expect_success
'detect malicious moved code, inside file' '
1149 test_config color.diff.oldMoved "normal red" &&
1150 test_config color.diff.newMoved "normal green" &&
1151 test_config color.diff.oldMovedAlternative "blue" &&
1152 test_config color.diff.newMovedAlternative "yellow" &&
1154 cat <<-\EOF >main.c &&
1162 int secure_foo(struct user *u)
1164 if (!u->is_allowed_foo)
1174 cat <<-\EOF >test.c &&
1178 printf("Hello World, but different\n");
1181 int another_function()
1186 git add main.c test.c &&
1187 git commit -m "add main and test file" &&
1188 before_main=$(git rev-parse --short HEAD:main.c) &&
1189 before_test=$(git rev-parse --short HEAD:test.c) &&
1190 cat <<-\EOF >main.c &&
1203 cat <<-\EOF >test.c &&
1207 printf("Hello World, but different\n");
1210 int secure_foo(struct user *u)
1213 if (!u->is_allowed_foo)
1217 int another_function()
1222 hash_main=$(git hash-object main.c) &&
1223 after_main=$(git rev-parse --short "$hash_main") &&
1224 hash_test=$(git hash-object test.c) &&
1225 after_test=$(git rev-parse --short "$hash_test") &&
1226 git diff HEAD --no-renames --color-moved=zebra --color >actual.raw &&
1227 test_decode_color <actual.raw >actual &&
1228 cat <<-EOF >expected &&
1229 <BOLD>diff --git a/main.c b/main.c<RESET>
1230 <BOLD>index $before_main..$after_main 100644<RESET>
1231 <BOLD>--- a/main.c<RESET>
1232 <BOLD>+++ b/main.c<RESET>
1233 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1234 printf("World\n");<RESET>
1237 <BRED>-int secure_foo(struct user *u)<RESET>
1239 <BLUE>-if (!u->is_allowed_foo)<RESET>
1240 <BLUE>-return;<RESET>
1241 <RED>-foo(u);<RESET>
1247 <BOLD>diff --git a/test.c b/test.c<RESET>
1248 <BOLD>index $before_test..$after_test 100644<RESET>
1249 <BOLD>--- a/test.c<RESET>
1250 <BOLD>+++ b/test.c<RESET>
1251 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1252 printf("Hello World, but different\n");<RESET>
1255 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1256 <BGREEN>+<RESET><BGREEN>{<RESET>
1257 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1258 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1259 <BGREEN>+<RESET><BGREEN>return;<RESET>
1260 <GREEN>+<RESET><GREEN>}<RESET>
1262 int another_function()<RESET>
1267 test_cmp expected actual
1270 test_expect_success
'plain moved code, inside file' '
1271 test_config color.diff.oldMoved "normal red" &&
1272 test_config color.diff.newMoved "normal green" &&
1273 test_config color.diff.oldMovedAlternative "blue" &&
1274 test_config color.diff.newMovedAlternative "yellow" &&
1275 # needs previous test as setup
1276 git diff HEAD --no-renames --color-moved=plain --color >actual.raw &&
1277 test_decode_color <actual.raw >actual &&
1278 cat <<-EOF >expected &&
1279 <BOLD>diff --git a/main.c b/main.c<RESET>
1280 <BOLD>index $before_main..$after_main 100644<RESET>
1281 <BOLD>--- a/main.c<RESET>
1282 <BOLD>+++ b/main.c<RESET>
1283 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1284 printf("World\n");<RESET>
1287 <BRED>-int secure_foo(struct user *u)<RESET>
1289 <BRED>-if (!u->is_allowed_foo)<RESET>
1290 <BRED>-return;<RESET>
1291 <BRED>-foo(u);<RESET>
1297 <BOLD>diff --git a/test.c b/test.c<RESET>
1298 <BOLD>index $before_test..$after_test 100644<RESET>
1299 <BOLD>--- a/test.c<RESET>
1300 <BOLD>+++ b/test.c<RESET>
1301 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1302 printf("Hello World, but different\n");<RESET>
1305 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1306 <BGREEN>+<RESET><BGREEN>{<RESET>
1307 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1308 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1309 <BGREEN>+<RESET><BGREEN>return;<RESET>
1310 <BGREEN>+<RESET><BGREEN>}<RESET>
1312 int another_function()<RESET>
1317 test_cmp expected actual
1320 test_expect_success
'detect blocks of moved code' '
1322 cat <<-\EOF >lines.txt &&
1340 git add lines.txt &&
1341 git commit -m "add poetry" &&
1342 cat <<-\EOF >lines.txt &&
1360 test_config color.diff.oldMoved "magenta" &&
1361 test_config color.diff.newMoved "cyan" &&
1362 test_config color.diff.oldMovedAlternative "blue" &&
1363 test_config color.diff.newMovedAlternative "yellow" &&
1364 test_config color.diff.oldMovedDimmed "normal magenta" &&
1365 test_config color.diff.newMovedDimmed "normal cyan" &&
1366 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1367 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1368 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1369 grep -v "index" actual.raw | test_decode_color >actual &&
1370 cat <<-\EOF >expected &&
1371 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1372 <BOLD>--- a/lines.txt<RESET>
1373 <BOLD>+++ b/lines.txt<RESET>
1374 <CYAN>@@ -1,16 +1,16 @@<RESET>
1375 <MAGENTA>-long line 1<RESET>
1376 <MAGENTA>-long line 2<RESET>
1377 <MAGENTA>-long line 3<RESET>
1384 <CYAN>+<RESET><CYAN>long line 1<RESET>
1385 <CYAN>+<RESET><CYAN>long line 2<RESET>
1386 <CYAN>+<RESET><CYAN>long line 3<RESET>
1387 <CYAN>+<RESET><CYAN>long line 14<RESET>
1388 <CYAN>+<RESET><CYAN>long line 15<RESET>
1389 <CYAN>+<RESET><CYAN>long line 16<RESET>
1394 <MAGENTA>-long line 14<RESET>
1395 <MAGENTA>-long line 15<RESET>
1396 <MAGENTA>-long line 16<RESET>
1398 test_cmp expected actual
1402 test_expect_success
'detect permutations inside moved code -- dimmed-zebra' '
1403 # reuse setup from test before!
1404 test_config color.diff.oldMoved "magenta" &&
1405 test_config color.diff.newMoved "cyan" &&
1406 test_config color.diff.oldMovedAlternative "blue" &&
1407 test_config color.diff.newMovedAlternative "yellow" &&
1408 test_config color.diff.oldMovedDimmed "normal magenta" &&
1409 test_config color.diff.newMovedDimmed "normal cyan" &&
1410 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1411 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1412 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1413 grep -v "index" actual.raw | test_decode_color >actual &&
1414 cat <<-\EOF >expected &&
1415 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1416 <BOLD>--- a/lines.txt<RESET>
1417 <BOLD>+++ b/lines.txt<RESET>
1418 <CYAN>@@ -1,16 +1,16 @@<RESET>
1419 <BMAGENTA>-long line 1<RESET>
1420 <BMAGENTA>-long line 2<RESET>
1421 <BMAGENTA>-long line 3<RESET>
1428 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1429 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1430 <CYAN>+<RESET><CYAN>long line 3<RESET>
1431 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1432 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1433 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1438 <BMAGENTA>-long line 14<RESET>
1439 <BMAGENTA>-long line 15<RESET>
1440 <BMAGENTA>-long line 16<RESET>
1442 test_cmp expected actual
1445 test_expect_success
'cmd option assumes configured colored-moved' '
1446 test_config color.diff.oldMoved "magenta" &&
1447 test_config color.diff.newMoved "cyan" &&
1448 test_config color.diff.oldMovedAlternative "blue" &&
1449 test_config color.diff.newMovedAlternative "yellow" &&
1450 test_config color.diff.oldMovedDimmed "normal magenta" &&
1451 test_config color.diff.newMovedDimmed "normal cyan" &&
1452 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1453 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1454 test_config diff.colorMoved zebra &&
1455 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1456 grep -v "index" actual.raw | test_decode_color >actual &&
1457 cat <<-\EOF >expected &&
1458 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1459 <BOLD>--- a/lines.txt<RESET>
1460 <BOLD>+++ b/lines.txt<RESET>
1461 <CYAN>@@ -1,16 +1,16 @@<RESET>
1462 <MAGENTA>-long line 1<RESET>
1463 <MAGENTA>-long line 2<RESET>
1464 <MAGENTA>-long line 3<RESET>
1471 <CYAN>+<RESET><CYAN>long line 1<RESET>
1472 <CYAN>+<RESET><CYAN>long line 2<RESET>
1473 <CYAN>+<RESET><CYAN>long line 3<RESET>
1474 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1475 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1476 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1481 <MAGENTA>-long line 14<RESET>
1482 <MAGENTA>-long line 15<RESET>
1483 <MAGENTA>-long line 16<RESET>
1485 test_cmp expected actual
1488 test_expect_success
'no effect from --color-moved with --word-diff' '
1489 cat <<-\EOF >text.txt &&
1490 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1493 git commit -a -m "clean state" &&
1494 cat <<-\EOF >text.txt &&
1495 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1497 git diff --color-moved --word-diff >actual &&
1498 git diff --word-diff >expect &&
1499 test_cmp expect actual
1502 test_expect_success
'set up whitespace tests' '
1504 # Note that these lines have no leading or trailing whitespace.
1505 cat <<-\EOF >lines.txt &&
1516 git add lines.txt &&
1517 git commit -m "add poetry" &&
1518 git config color.diff.oldMoved "magenta" &&
1519 git config color.diff.newMoved "cyan"
1522 test_expect_success
'move detection ignoring whitespace ' '
1523 q_to_tab <<-\EOF >lines.txt &&
1527 Qchanged long line 9
1534 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1535 grep -v "index" actual.raw | test_decode_color >actual &&
1536 cat <<-\EOF >expected &&
1537 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1538 <BOLD>--- a/lines.txt<RESET>
1539 <BOLD>+++ b/lines.txt<RESET>
1540 <CYAN>@@ -1,9 +1,9 @@<RESET>
1541 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1542 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1543 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1544 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1550 <RED>-long line 6<RESET>
1551 <RED>-long line 7<RESET>
1552 <RED>-long line 8<RESET>
1553 <RED>-long line 9<RESET>
1555 test_cmp expected actual &&
1557 git diff HEAD --no-renames --color-moved --color \
1558 --color-moved-ws=ignore-all-space >actual.raw &&
1559 grep -v "index" actual.raw | test_decode_color >actual &&
1560 cat <<-\EOF >expected &&
1561 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1562 <BOLD>--- a/lines.txt<RESET>
1563 <BOLD>+++ b/lines.txt<RESET>
1564 <CYAN>@@ -1,9 +1,9 @@<RESET>
1565 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1566 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1567 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1568 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1574 <MAGENTA>-long line 6<RESET>
1575 <MAGENTA>-long line 7<RESET>
1576 <MAGENTA>-long line 8<RESET>
1577 <RED>-long line 9<RESET>
1579 test_cmp expected actual
1582 test_expect_success
'move detection ignoring whitespace changes' '
1584 # Lines 6-8 have a space change, but 9 is new whitespace
1585 q_to_tab <<-\EOF >lines.txt &&
1597 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1598 grep -v "index" actual.raw | test_decode_color >actual &&
1599 cat <<-\EOF >expected &&
1600 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1601 <BOLD>--- a/lines.txt<RESET>
1602 <BOLD>+++ b/lines.txt<RESET>
1603 <CYAN>@@ -1,9 +1,9 @@<RESET>
1604 <GREEN>+<RESET><GREEN>long line 6<RESET>
1605 <GREEN>+<RESET><GREEN>long line 7<RESET>
1606 <GREEN>+<RESET><GREEN>long line 8<RESET>
1607 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1613 <RED>-long line 6<RESET>
1614 <RED>-long line 7<RESET>
1615 <RED>-long line 8<RESET>
1616 <RED>-long line 9<RESET>
1618 test_cmp expected actual &&
1620 git diff HEAD --no-renames --color-moved --color \
1621 --color-moved-ws=ignore-space-change >actual.raw &&
1622 grep -v "index" actual.raw | test_decode_color >actual &&
1623 cat <<-\EOF >expected &&
1624 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1625 <BOLD>--- a/lines.txt<RESET>
1626 <BOLD>+++ b/lines.txt<RESET>
1627 <CYAN>@@ -1,9 +1,9 @@<RESET>
1628 <CYAN>+<RESET><CYAN>long line 6<RESET>
1629 <CYAN>+<RESET><CYAN>long line 7<RESET>
1630 <CYAN>+<RESET><CYAN>long line 8<RESET>
1631 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1637 <MAGENTA>-long line 6<RESET>
1638 <MAGENTA>-long line 7<RESET>
1639 <MAGENTA>-long line 8<RESET>
1640 <RED>-long line 9<RESET>
1642 test_cmp expected actual
1645 test_expect_success
'move detection ignoring whitespace at eol' '
1647 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1648 q_to_tab <<-\EOF >lines.txt &&
1660 # avoid cluttering the output with complaints about our eol whitespace
1661 test_config core.whitespace -blank-at-eol &&
1663 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1664 grep -v "index" actual.raw | test_decode_color >actual &&
1665 cat <<-\EOF >expected &&
1666 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1667 <BOLD>--- a/lines.txt<RESET>
1668 <BOLD>+++ b/lines.txt<RESET>
1669 <CYAN>@@ -1,9 +1,9 @@<RESET>
1670 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1671 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1672 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1673 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1679 <RED>-long line 6<RESET>
1680 <RED>-long line 7<RESET>
1681 <RED>-long line 8<RESET>
1682 <RED>-long line 9<RESET>
1684 test_cmp expected actual &&
1686 git diff HEAD --no-renames --color-moved --color \
1687 --color-moved-ws=ignore-space-at-eol >actual.raw &&
1688 grep -v "index" actual.raw | test_decode_color >actual &&
1689 cat <<-\EOF >expected &&
1690 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1691 <BOLD>--- a/lines.txt<RESET>
1692 <BOLD>+++ b/lines.txt<RESET>
1693 <CYAN>@@ -1,9 +1,9 @@<RESET>
1694 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1695 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1696 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1697 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1703 <MAGENTA>-long line 6<RESET>
1704 <MAGENTA>-long line 7<RESET>
1705 <MAGENTA>-long line 8<RESET>
1706 <RED>-long line 9<RESET>
1708 test_cmp expected actual
1711 test_expect_success
'clean up whitespace-test colors' '
1712 git config --unset color.diff.oldMoved &&
1713 git config --unset color.diff.newMoved
1716 test_expect_success
'--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1733 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1734 grep -v "index" actual.raw | test_decode_color >actual &&
1735 cat >expected <<-\EOF &&
1736 <BOLD>diff --git a/bar b/bar<RESET>
1737 <BOLD>--- a/bar<RESET>
1738 <BOLD>+++ b/bar<RESET>
1739 <CYAN>@@ -0,0 +1 @@<RESET>
1740 <GREEN>+<RESET><GREEN>line1<RESET>
1741 <BOLD>diff --git a/foo b/foo<RESET>
1742 <BOLD>--- a/foo<RESET>
1743 <BOLD>+++ b/foo<RESET>
1744 <CYAN>@@ -1,2 +1 @@<RESET>
1745 irrelevant_line<RESET>
1749 test_cmp expected actual
1752 test_expect_success
'--color-moved respects MIN_ALNUM_COUNT' '
1755 nineteen chars 456789
1757 twenty chars 234567890
1767 twenty chars 234567890
1768 nineteen chars 456789
1771 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1772 grep -v "index" actual.raw | test_decode_color >actual &&
1773 cat >expected <<-\EOF &&
1774 <BOLD>diff --git a/bar b/bar<RESET>
1775 <BOLD>--- a/bar<RESET>
1776 <BOLD>+++ b/bar<RESET>
1777 <CYAN>@@ -0,0 +1,2 @@<RESET>
1778 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1779 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1780 <BOLD>diff --git a/foo b/foo<RESET>
1781 <BOLD>--- a/foo<RESET>
1782 <BOLD>+++ b/foo<RESET>
1783 <CYAN>@@ -1,3 +1 @@<RESET>
1784 <RED>-nineteen chars 456789<RESET>
1785 irrelevant_line<RESET>
1786 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1789 test_cmp expected actual
1792 test_expect_success
'--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1813 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1814 grep -v "index" actual.raw | test_decode_color >actual &&
1815 cat >expected <<-\EOF &&
1816 <BOLD>diff --git a/bar b/bar<RESET>
1817 <BOLD>--- a/bar<RESET>
1818 <BOLD>+++ b/bar<RESET>
1819 <CYAN>@@ -0,0 +1,3 @@<RESET>
1820 <GREEN>+<RESET><GREEN>7charsB<RESET>
1821 <GREEN>+<RESET><GREEN>7charsC<RESET>
1822 <GREEN>+<RESET><GREEN>7charsA<RESET>
1823 <BOLD>diff --git a/foo b/foo<RESET>
1824 <BOLD>--- a/foo<RESET>
1825 <BOLD>+++ b/foo<RESET>
1826 <CYAN>@@ -1,4 +1 @@<RESET>
1827 <RED>-7charsA<RESET>
1828 irrelevant_line<RESET>
1829 <RED>-7charsB<RESET>
1830 <RED>-7charsC<RESET>
1833 test_cmp expected actual
1836 test_expect_success
'move detection with submodules' '
1837 test_create_repo bananas &&
1838 echo ripe >bananas/recipe &&
1839 git -C bananas add recipe &&
1840 test_commit fruit &&
1841 test_commit -C bananas recipe &&
1842 git submodule add ./bananas &&
1844 git commit -a -m "bananas are like a heavy library?" &&
1845 echo foul >bananas/recipe &&
1846 echo ripe >fruit.t &&
1848 git diff --submodule=diff --color-moved --color >actual &&
1850 # no move detection as the moved line is across repository boundaries.
1851 test_decode_color <actual >decoded_actual &&
1852 ! grep BGREEN decoded_actual &&
1853 ! grep BRED decoded_actual &&
1855 # nor did we mess with it another way
1856 git diff --submodule=diff --color >expect.raw &&
1857 test_decode_color <expect.raw >expect &&
1858 test_cmp expect decoded_actual &&
1860 git submodule deinit bananas
1863 test_expect_success
'only move detection ignores white spaces' '
1865 q_to_tab <<-\EOF >text.txt &&
1866 a long line to exceed per-line minimum
1867 another long line to exceed per-line minimum
1871 git commit -m "add text" &&
1872 q_to_tab <<-\EOF >text.txt &&
1873 Qa long line to exceed per-line minimum
1874 Qanother long line to exceed per-line minimum
1878 # Make sure we get a different diff using -w
1879 git diff --color --color-moved -w >actual.raw &&
1880 grep -v "index" actual.raw | test_decode_color >actual &&
1881 q_to_tab <<-\EOF >expected &&
1882 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1883 <BOLD>--- a/text.txt<RESET>
1884 <BOLD>+++ b/text.txt<RESET>
1885 <CYAN>@@ -1,3 +1,3 @@<RESET>
1886 Qa long line to exceed per-line minimum<RESET>
1887 Qanother long line to exceed per-line minimum<RESET>
1888 <RED>-original file<RESET>
1889 <GREEN>+<RESET><GREEN>new file<RESET>
1891 test_cmp expected actual &&
1893 # And now ignoring white space only in the move detection
1894 git diff --color --color-moved \
1895 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
1896 grep -v "index" actual.raw | test_decode_color >actual &&
1897 q_to_tab <<-\EOF >expected &&
1898 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1899 <BOLD>--- a/text.txt<RESET>
1900 <BOLD>+++ b/text.txt<RESET>
1901 <CYAN>@@ -1,3 +1,3 @@<RESET>
1902 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
1903 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
1904 <RED>-original file<RESET>
1905 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>a long line to exceed per-line minimum<RESET>
1906 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>another long line to exceed per-line minimum<RESET>
1907 <GREEN>+<RESET><GREEN>new file<RESET>
1909 test_cmp expected actual
1912 test_expect_success
'compare whitespace delta across moved blocks' '
1915 q_to_tab <<-\EOF >text.txt &&
1919 QBut! <- this stands out
1921 QQdifferent starting
1927 QQQthat has similar lines
1928 QQQto previous blocks, but with different indent
1929 QQQYetQAnotherQoutlierQ
1930 QLine with internal w h i t e s p a c e change
1934 git commit -m "add text.txt" &&
1936 q_to_tab <<-\EOF >text.txt &&
1940 QQQBut! <- this stands out
1948 QQthat has similar lines
1949 QQto previous blocks, but with different indent
1950 QQYetQAnotherQoutlier
1951 QLine with internal whitespace change
1954 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
1955 grep -v "index" actual.raw | test_decode_color >actual &&
1957 q_to_tab <<-\EOF >expected &&
1958 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1959 <BOLD>--- a/text.txt<RESET>
1960 <BOLD>+++ b/text.txt<RESET>
1961 <CYAN>@@ -1,15 +1,15 @@<RESET>
1962 <BOLD;MAGENTA>-QIndented<RESET>
1963 <BOLD;MAGENTA>-QText across<RESET>
1964 <BOLD;MAGENTA>-Qsome lines<RESET>
1965 <RED>-QBut! <- this stands out<RESET>
1966 <BOLD;MAGENTA>-QAdjusting with<RESET>
1967 <BOLD;MAGENTA>-QQdifferent starting<RESET>
1968 <BOLD;MAGENTA>-Qwhite spaces<RESET>
1969 <RED>-QAnother outlier<RESET>
1970 <BOLD;MAGENTA>-QQQIndented<RESET>
1971 <BOLD;MAGENTA>-QQQText across<RESET>
1972 <BOLD;MAGENTA>-QQQfive lines<RESET>
1973 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
1974 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
1975 <RED>-QQQYetQAnotherQoutlierQ<RESET>
1976 <RED>-QLine with internal w h i t e s p a c e change<RESET>
1977 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1978 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1979 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
1980 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
1981 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
1982 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
1983 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
1984 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
1985 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1986 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1987 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
1988 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
1989 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
1990 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
1991 <GREEN>+<RESET>Q<GREEN>Line with internal whitespace change<RESET>
1994 test_cmp expected actual
1997 test_expect_success
'bogus settings in move detection erroring out' '
1998 test_must_fail git diff --color-moved=bogus 2>err &&
1999 test_i18ngrep "must be one of" err &&
2000 test_i18ngrep bogus err &&
2002 test_must_fail git -c diff.colormoved=bogus diff 2>err &&
2003 test_i18ngrep "must be one of" err &&
2004 test_i18ngrep "from command-line config" err &&
2006 test_must_fail git diff --color-moved-ws=bogus 2>err &&
2007 test_i18ngrep "possible values" err &&
2008 test_i18ngrep bogus err &&
2010 test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
2011 test_i18ngrep "possible values" err &&
2012 test_i18ngrep "from command-line config" err
2015 test_expect_success
'compare whitespace delta incompatible with other space options' '
2016 test_must_fail git diff \
2017 --color-moved-ws=allow-indentation-change,ignore-all-space \
2019 test_i18ngrep allow-indentation-change err
2023 test_expect_success
'compare mixed whitespace delta across moved blocks' '
2026 tr Q_ "\t " <<-EOF >text.txt &&
2028 ____too short without
2030 ___being grouped across blank line
2036 ____Indented text to
2037 _Q____be further indented by four spaces across
2039 QQ____These two lines have had their
2040 ____indentation reduced by four spaces
2041 Qdifferent indentation change
2046 git commit -m "add text.txt" &&
2048 tr Q_ "\t " <<-EOF >text.txt &&
2054 QQbe further indented by four spaces across
2059 Q_______being grouped across blank line
2061 Q_QThese two lines have had their
2062 indentation reduced by four spaces
2063 QQdifferent indentation change
2067 git -c color.diff.whitespace="normal red" \
2068 -c core.whitespace=space-before-tab \
2069 diff --color --color-moved --ws-error-highlight=all \
2070 --color-moved-ws=allow-indentation-change >actual.raw &&
2071 grep -v "index" actual.raw | test_decode_color >actual &&
2073 cat <<-\EOF >expected &&
2074 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2075 <BOLD>--- a/text.txt<RESET>
2076 <BOLD>+++ b/text.txt<RESET>
2077 <CYAN>@@ -1,16 +1,16 @@<RESET>
2078 <BOLD;MAGENTA>-<RESET>
2079 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> too short without<RESET>
2080 <BOLD;MAGENTA>-<RESET>
2081 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
2082 <BOLD;MAGENTA>-<RESET>
2083 <RESET>context<RESET>
2086 <RESET>anchor<RESET>
2087 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
2088 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
2089 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
2090 <BOLD;BLUE>-<RESET> <BOLD;BLUE> These two lines have had their<RESET>
2091 <BOLD;BLUE>-<RESET><BOLD;BLUE> indentation reduced by four spaces<RESET>
2092 <BOLD;MAGENTA>-<RESET> <BOLD;MAGENTA>different indentation change<RESET>
2093 <RED>-<RESET><RED> too short<RESET>
2094 <BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
2095 <BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
2096 <BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
2097 <BOLD;YELLOW>+<RESET>
2098 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
2099 <BOLD;YELLOW>+<RESET>
2100 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW> being grouped across blank line<RESET>
2101 <BOLD;YELLOW>+<RESET>
2102 <BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
2103 <BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
2104 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
2105 <GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
2108 test_cmp expected actual
2111 test_expect_success
'combine --ignore-blank-lines with --function-context' '
2112 test_write_lines 1 "" 2 3 4 5 >a &&
2113 test_write_lines 1 2 3 4 >b &&
2114 test_must_fail git diff --no-index \
2115 --ignore-blank-lines --function-context a b >actual.raw &&
2116 sed -n "/@@/,\$p" <actual.raw >actual &&
2117 cat <<-\EOF >expect &&
2126 test_cmp expect actual
2129 test_expect_success
'combine --ignore-blank-lines with --function-context 2' '
2130 test_write_lines a b c "" function 1 2 3 4 5 "" 6 7 8 9 >a &&
2131 test_write_lines "" a b c "" function 1 2 3 4 5 6 7 8 >b &&
2132 test_must_fail git diff --no-index \
2133 --ignore-blank-lines --function-context a b >actual.raw &&
2134 sed -n "/@@/,\$p" <actual.raw >actual &&
2135 cat <<-\EOF >expect &&
2149 test_cmp expect actual