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 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 'check staged with no whitespace errors' '
573 git diff --cached --check
576 test_expect_success 'check staged with trailing whitespace' '
579 test_must_fail git diff --cached --check
582 test_expect_success 'check staged with space before tab in indent' '
583 # indent has space followed by hard tab
586 test_must_fail git diff --cached --check
589 test_expect_success 'check with no whitespace errors (diff-index)' '
592 git diff-index --check HEAD
595 test_expect_success 'check with trailing whitespace (diff-index)' '
598 test_must_fail git diff-index --check HEAD
601 test_expect_success 'check with space before tab in indent (diff-index)' '
602 # indent has space followed by hard tab
605 test_must_fail git diff-index --check HEAD
608 test_expect_success 'check staged with no whitespace errors (diff-index)' '
611 git diff-index --cached --check HEAD
614 test_expect_success 'check staged with trailing whitespace (diff-index)' '
617 test_must_fail git diff-index --cached --check HEAD
620 test_expect_success 'check staged with space before tab in indent (diff-index)' '
621 # indent has space followed by hard tab
624 test_must_fail git diff-index --cached --check HEAD
627 test_expect_success 'check with no whitespace errors (diff-tree)' '
629 git commit -m "new commit" x &&
630 git diff-tree --check HEAD^ HEAD
633 test_expect_success 'check with trailing whitespace (diff-tree)' '
635 git commit -m "another commit" x &&
636 test_must_fail git diff-tree --check HEAD^ HEAD
639 test_expect_success 'check with space before tab in indent (diff-tree)' '
640 # indent has space followed by hard tab
642 git commit -m "yet another" x &&
643 test_must_fail git diff-tree --check HEAD^ HEAD
646 test_expect_success 'check with ignored trailing whitespace attr (diff-tree)' '
647 test_when_finished "git reset --hard HEAD^" &&
649 # create a whitespace error that should be ignored
650 echo "* -whitespace" >.gitattributes &&
651 git add .gitattributes &&
654 git commit -m "add trailing space" &&
656 # with a worktree diff-tree ignores the whitespace error
657 git diff-tree --root --check HEAD &&
659 # without a worktree diff-tree still ignores the whitespace error
660 git -C .git diff-tree --root --check HEAD
663 test_expect_success 'check trailing whitespace (trailing-space: off)' '
664 git config core.whitespace "-trailing-space" &&
665 echo "foo (); " >x &&
669 test_expect_success 'check trailing whitespace (trailing-space: on)' '
670 git config core.whitespace "trailing-space" &&
671 echo "foo (); " >x &&
672 test_must_fail git diff --check
675 test_expect_success 'check space before tab in indent (space-before-tab: off)' '
676 # indent contains space followed by HT
677 git config core.whitespace "-space-before-tab" &&
678 echo " foo ();" >x &&
682 test_expect_success 'check space before tab in indent (space-before-tab: on)' '
683 # indent contains space followed by HT
684 git config core.whitespace "space-before-tab" &&
685 echo " foo (); " >x &&
686 test_must_fail git diff --check
689 test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
690 git config core.whitespace "-indent-with-non-tab" &&
691 echo " foo ();" >x &&
695 test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
696 git config core.whitespace "indent-with-non-tab" &&
697 echo " foo ();" >x &&
698 test_must_fail git diff --check
701 test_expect_success 'ditto, but tabwidth=9' '
702 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
706 test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
707 git config core.whitespace "indent-with-non-tab" &&
708 echo " foo ();" >x &&
709 test_must_fail git diff --check
712 test_expect_success 'ditto, but tabwidth=10' '
713 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
714 test_must_fail git diff --check
717 test_expect_success 'ditto, but tabwidth=20' '
718 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
722 test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
723 git config core.whitespace "-tab-in-indent" &&
724 echo " foo ();" >x &&
728 test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
729 git config core.whitespace "tab-in-indent" &&
730 echo " foo ();" >x &&
731 test_must_fail git diff --check
734 test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
735 git config core.whitespace "tab-in-indent" &&
736 echo " foo ();" >x &&
737 test_must_fail git diff --check
740 test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
741 git config core.whitespace "tab-in-indent,tabwidth=1" &&
742 test_must_fail git diff --check
745 test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
746 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
748 test_must_fail git diff --check
751 test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
752 git config --unset core.whitespace &&
753 echo "x whitespace" >.gitattributes &&
754 echo " foo ();" >x &&
759 test_expect_success 'line numbers in --check output are correct' '
761 echo "foo(); " >>x &&
762 test_must_fail git diff --check >check &&
766 test_expect_success 'checkdiff detects new trailing blank lines (1)' '
769 test_must_fail git diff --check >check &&
770 grep "new blank line" check
773 test_expect_success 'checkdiff detects new trailing blank lines (2)' '
774 test_write_lines a b "" "" >x &&
776 test_write_lines a "" "" "" "" >x &&
777 test_must_fail git diff --check >check &&
778 grep "new blank line" check
781 test_expect_success 'checkdiff allows new blank lines' '
785 echo "/* This is new */" &&
792 test_expect_success 'whitespace-only changes not reported (diff)' '
794 echo >x "hello world" &&
796 git commit -m "hello 1" &&
797 echo >x "hello world" &&
798 git diff -b >actual &&
799 test_must_be_empty actual
802 test_expect_success 'whitespace-only changes not reported (diffstat)' '
803 # reuse state from previous test
804 git diff --stat -b >actual &&
805 test_must_be_empty actual
808 test_expect_success 'whitespace changes with modification reported (diffstat)' '
810 echo >x "hello world" &&
811 git update-index --chmod=+x x &&
812 git diff --stat --cached -b >actual &&
813 cat <<-EOF >expect &&
815 1 file changed, 0 insertions(+), 0 deletions(-)
817 test_cmp expect actual
820 test_expect_success 'whitespace-only changes reported across renames (diffstat)' '
822 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
824 git commit -m "base" &&
825 sed -e "5s/^/ /" x >z &&
828 git diff -w -M --cached --stat >actual &&
829 cat <<-EOF >expect &&
831 1 file changed, 0 insertions(+), 0 deletions(-)
833 test_cmp expect actual
836 test_expect_success 'whitespace-only changes reported across renames' '
837 git reset --hard HEAD~1 &&
838 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
840 hash_x=$(git hash-object x) &&
841 before=$(git rev-parse --short "$hash_x") &&
842 git commit -m "base" &&
843 sed -e "5s/^/ /" x >z &&
846 hash_z=$(git hash-object z) &&
847 after=$(git rev-parse --short "$hash_z") &&
848 git diff -w -M --cached >actual.raw &&
849 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" actual.raw >actual &&
850 cat <<-EOF >expect &&
852 similarity index NUM%
855 index $before..$after 100644
857 test_cmp expect actual
861 diff --git a/empty b/void
862 similarity index 100%
867 test_expect_success 'rename empty' '
871 git commit -m empty &&
873 git diff -w --cached -M >current &&
874 test_cmp expected current
877 test_expect_success 'combined diff with autocrlf conversion' '
880 test_commit "one side" x hello one-side &&
881 git checkout HEAD^ &&
883 git commit -m "the other side" x &&
884 git config core.autocrlf true &&
885 test_must_fail git merge one-side >actual &&
886 test_i18ngrep "Automatic merge failed" actual &&
888 git diff >actual.raw &&
889 sed -e "1,/^@@@/d" actual.raw >actual &&
894 # Start testing the colored format for whitespace checks
896 test_expect_success 'setup diff colors' '
897 git config color.diff.plain normal &&
898 git config color.diff.meta bold &&
899 git config color.diff.frag cyan &&
900 git config color.diff.func normal &&
901 git config color.diff.old red &&
902 git config color.diff.new green &&
903 git config color.diff.commit yellow &&
904 git config color.diff.whitespace blue &&
906 git config core.autocrlf false
909 test_expect_success 'diff that introduces a line with only tabs' '
910 git config core.whitespace blank-at-eol &&
913 old_hash_x=$(git hash-object x) &&
914 before=$(git rev-parse --short "$old_hash_x") &&
915 git commit -m "initial" x &&
916 echo "{NTN}" | tr "NT" "\n\t" >>x &&
917 new_hash_x=$(git hash-object x) &&
918 after=$(git rev-parse --short "$new_hash_x") &&
919 git diff --color >current.raw &&
920 test_decode_color <current.raw >current &&
922 cat >expected <<-EOF &&
923 <BOLD>diff --git a/x b/x<RESET>
924 <BOLD>index $before..$after 100644<RESET>
927 <CYAN>@@ -1 +1,4 @@<RESET>
929 <GREEN>+<RESET><GREEN>{<RESET>
930 <GREEN>+<RESET><BLUE> <RESET>
931 <GREEN>+<RESET><GREEN>}<RESET>
934 test_cmp expected current
937 test_expect_success 'diff that introduces and removes ws breakages' '
940 echo "0. blank-at-eol " &&
941 echo "1. blank-at-eol "
943 old_hash_x=$(git hash-object x) &&
944 before=$(git rev-parse --short "$old_hash_x") &&
945 git commit -a --allow-empty -m preimage &&
947 echo "0. blank-at-eol " &&
948 echo "1. still-blank-at-eol " &&
949 echo "2. and a new line "
951 new_hash_x=$(git hash-object x) &&
952 after=$(git rev-parse --short "$new_hash_x") &&
954 git diff --color >current.raw &&
955 test_decode_color <current.raw >current &&
957 cat >expected <<-EOF &&
958 <BOLD>diff --git a/x b/x<RESET>
959 <BOLD>index $before..$after 100644<RESET>
962 <CYAN>@@ -1,2 +1,3 @@<RESET>
963 0. blank-at-eol <RESET>
964 <RED>-1. blank-at-eol <RESET>
965 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
966 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
969 test_cmp expected current
972 test_expect_success 'ws-error-highlight test setup' '
976 echo "0. blank-at-eol " &&
977 echo "1. blank-at-eol "
979 old_hash_x=$(git hash-object x) &&
980 before=$(git rev-parse --short "$old_hash_x") &&
981 git commit -a --allow-empty -m preimage &&
983 echo "0. blank-at-eol " &&
984 echo "1. still-blank-at-eol " &&
985 echo "2. and a new line "
987 new_hash_x=$(git hash-object x) &&
988 after=$(git rev-parse --short "$new_hash_x") &&
990 cat >expect.default-old <<-EOF &&
991 <BOLD>diff --git a/x b/x<RESET>
992 <BOLD>index $before..$after 100644<RESET>
995 <CYAN>@@ -1,2 +1,3 @@<RESET>
996 0. blank-at-eol <RESET>
997 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
998 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
999 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1002 cat >expect.all <<-EOF &&
1003 <BOLD>diff --git a/x b/x<RESET>
1004 <BOLD>index $before..$after 100644<RESET>
1005 <BOLD>--- a/x<RESET>
1006 <BOLD>+++ b/x<RESET>
1007 <CYAN>@@ -1,2 +1,3 @@<RESET>
1008 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
1009 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1010 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1011 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1014 cat >expect.none <<-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>-1. blank-at-eol <RESET>
1022 <GREEN>+1. still-blank-at-eol <RESET>
1023 <GREEN>+2. and a new line <RESET>
1028 test_expect_success 'test --ws-error-highlight option' '
1030 git diff --color --ws-error-highlight=default,old >current.raw &&
1031 test_decode_color <current.raw >current &&
1032 test_cmp expect.default-old current &&
1034 git diff --color --ws-error-highlight=all >current.raw &&
1035 test_decode_color <current.raw >current &&
1036 test_cmp expect.all current &&
1038 git diff --color --ws-error-highlight=none >current.raw &&
1039 test_decode_color <current.raw >current &&
1040 test_cmp expect.none current
1044 test_expect_success 'test diff.wsErrorHighlight config' '
1046 git -c diff.wsErrorHighlight=default,old diff --color >current.raw &&
1047 test_decode_color <current.raw >current &&
1048 test_cmp expect.default-old current &&
1050 git -c diff.wsErrorHighlight=all diff --color >current.raw &&
1051 test_decode_color <current.raw >current &&
1052 test_cmp expect.all current &&
1054 git -c diff.wsErrorHighlight=none diff --color >current.raw &&
1055 test_decode_color <current.raw >current &&
1056 test_cmp expect.none current
1060 test_expect_success 'option overrides diff.wsErrorHighlight' '
1062 git -c diff.wsErrorHighlight=none \
1063 diff --color --ws-error-highlight=default,old >current.raw &&
1064 test_decode_color <current.raw >current &&
1065 test_cmp expect.default-old current &&
1067 git -c diff.wsErrorHighlight=default \
1068 diff --color --ws-error-highlight=all >current.raw &&
1069 test_decode_color <current.raw >current &&
1070 test_cmp expect.all current &&
1072 git -c diff.wsErrorHighlight=all \
1073 diff --color --ws-error-highlight=none >current.raw &&
1074 test_decode_color <current.raw >current &&
1075 test_cmp expect.none current
1079 test_expect_success 'detect moved code, complete file' '
1081 cat <<-\EOF >test.c &&
1085 printf("Hello World");
1089 git commit -m "add main function" &&
1090 file=$(git rev-parse --short HEAD:test.c) &&
1091 git mv test.c main.c &&
1092 test_config color.diff.oldMoved "normal red" &&
1093 test_config color.diff.newMoved "normal green" &&
1094 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1095 test_decode_color <actual.raw >actual &&
1096 cat >expected <<-EOF &&
1097 <BOLD>diff --git a/main.c b/main.c<RESET>
1098 <BOLD>new file mode 100644<RESET>
1099 <BOLD>index 0000000..$file<RESET>
1100 <BOLD>--- /dev/null<RESET>
1101 <BOLD>+++ b/main.c<RESET>
1102 <CYAN>@@ -0,0 +1,5 @@<RESET>
1103 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1104 <BGREEN>+<RESET><BGREEN>main()<RESET>
1105 <BGREEN>+<RESET><BGREEN>{<RESET>
1106 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1107 <BGREEN>+<RESET><BGREEN>}<RESET>
1108 <BOLD>diff --git a/test.c b/test.c<RESET>
1109 <BOLD>deleted file mode 100644<RESET>
1110 <BOLD>index $file..0000000<RESET>
1111 <BOLD>--- a/test.c<RESET>
1112 <BOLD>+++ /dev/null<RESET>
1113 <CYAN>@@ -1,5 +0,0 @@<RESET>
1114 <BRED>-#include<stdio.h><RESET>
1115 <BRED>-main()<RESET>
1117 <BRED>-printf("Hello World");<RESET>
1121 test_cmp expected actual
1124 test_expect_success 'detect malicious moved code, inside file' '
1125 test_config color.diff.oldMoved "normal red" &&
1126 test_config color.diff.newMoved "normal green" &&
1127 test_config color.diff.oldMovedAlternative "blue" &&
1128 test_config color.diff.newMovedAlternative "yellow" &&
1130 cat <<-\EOF >main.c &&
1138 int secure_foo(struct user *u)
1140 if (!u->is_allowed_foo)
1150 cat <<-\EOF >test.c &&
1154 printf("Hello World, but different\n");
1157 int another_function()
1162 git add main.c test.c &&
1163 git commit -m "add main and test file" &&
1164 before_main=$(git rev-parse --short HEAD:main.c) &&
1165 before_test=$(git rev-parse --short HEAD:test.c) &&
1166 cat <<-\EOF >main.c &&
1179 cat <<-\EOF >test.c &&
1183 printf("Hello World, but different\n");
1186 int secure_foo(struct user *u)
1189 if (!u->is_allowed_foo)
1193 int another_function()
1198 hash_main=$(git hash-object main.c) &&
1199 after_main=$(git rev-parse --short "$hash_main") &&
1200 hash_test=$(git hash-object test.c) &&
1201 after_test=$(git rev-parse --short "$hash_test") &&
1202 git diff HEAD --no-renames --color-moved=zebra --color >actual.raw &&
1203 test_decode_color <actual.raw >actual &&
1204 cat <<-EOF >expected &&
1205 <BOLD>diff --git a/main.c b/main.c<RESET>
1206 <BOLD>index $before_main..$after_main 100644<RESET>
1207 <BOLD>--- a/main.c<RESET>
1208 <BOLD>+++ b/main.c<RESET>
1209 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1210 printf("World\n");<RESET>
1213 <BRED>-int secure_foo(struct user *u)<RESET>
1215 <BLUE>-if (!u->is_allowed_foo)<RESET>
1216 <BLUE>-return;<RESET>
1217 <RED>-foo(u);<RESET>
1223 <BOLD>diff --git a/test.c b/test.c<RESET>
1224 <BOLD>index $before_test..$after_test 100644<RESET>
1225 <BOLD>--- a/test.c<RESET>
1226 <BOLD>+++ b/test.c<RESET>
1227 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1228 printf("Hello World, but different\n");<RESET>
1231 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1232 <BGREEN>+<RESET><BGREEN>{<RESET>
1233 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1234 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1235 <BGREEN>+<RESET><BGREEN>return;<RESET>
1236 <GREEN>+<RESET><GREEN>}<RESET>
1238 int another_function()<RESET>
1243 test_cmp expected actual
1246 test_expect_success 'plain moved code, inside file' '
1247 test_config color.diff.oldMoved "normal red" &&
1248 test_config color.diff.newMoved "normal green" &&
1249 test_config color.diff.oldMovedAlternative "blue" &&
1250 test_config color.diff.newMovedAlternative "yellow" &&
1251 # needs previous test as setup
1252 git diff HEAD --no-renames --color-moved=plain --color >actual.raw &&
1253 test_decode_color <actual.raw >actual &&
1254 cat <<-EOF >expected &&
1255 <BOLD>diff --git a/main.c b/main.c<RESET>
1256 <BOLD>index $before_main..$after_main 100644<RESET>
1257 <BOLD>--- a/main.c<RESET>
1258 <BOLD>+++ b/main.c<RESET>
1259 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1260 printf("World\n");<RESET>
1263 <BRED>-int secure_foo(struct user *u)<RESET>
1265 <BRED>-if (!u->is_allowed_foo)<RESET>
1266 <BRED>-return;<RESET>
1267 <BRED>-foo(u);<RESET>
1273 <BOLD>diff --git a/test.c b/test.c<RESET>
1274 <BOLD>index $before_test..$after_test 100644<RESET>
1275 <BOLD>--- a/test.c<RESET>
1276 <BOLD>+++ b/test.c<RESET>
1277 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1278 printf("Hello World, but different\n");<RESET>
1281 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1282 <BGREEN>+<RESET><BGREEN>{<RESET>
1283 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1284 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1285 <BGREEN>+<RESET><BGREEN>return;<RESET>
1286 <BGREEN>+<RESET><BGREEN>}<RESET>
1288 int another_function()<RESET>
1293 test_cmp expected actual
1296 test_expect_success 'detect blocks of moved code' '
1298 cat <<-\EOF >lines.txt &&
1316 git add lines.txt &&
1317 git commit -m "add poetry" &&
1318 cat <<-\EOF >lines.txt &&
1336 test_config color.diff.oldMoved "magenta" &&
1337 test_config color.diff.newMoved "cyan" &&
1338 test_config color.diff.oldMovedAlternative "blue" &&
1339 test_config color.diff.newMovedAlternative "yellow" &&
1340 test_config color.diff.oldMovedDimmed "normal magenta" &&
1341 test_config color.diff.newMovedDimmed "normal cyan" &&
1342 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1343 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1344 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1345 grep -v "index" actual.raw | test_decode_color >actual &&
1346 cat <<-\EOF >expected &&
1347 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1348 <BOLD>--- a/lines.txt<RESET>
1349 <BOLD>+++ b/lines.txt<RESET>
1350 <CYAN>@@ -1,16 +1,16 @@<RESET>
1351 <MAGENTA>-long line 1<RESET>
1352 <MAGENTA>-long line 2<RESET>
1353 <MAGENTA>-long line 3<RESET>
1360 <CYAN>+<RESET><CYAN>long line 1<RESET>
1361 <CYAN>+<RESET><CYAN>long line 2<RESET>
1362 <CYAN>+<RESET><CYAN>long line 3<RESET>
1363 <CYAN>+<RESET><CYAN>long line 14<RESET>
1364 <CYAN>+<RESET><CYAN>long line 15<RESET>
1365 <CYAN>+<RESET><CYAN>long line 16<RESET>
1370 <MAGENTA>-long line 14<RESET>
1371 <MAGENTA>-long line 15<RESET>
1372 <MAGENTA>-long line 16<RESET>
1374 test_cmp expected actual
1378 test_expect_success 'detect permutations inside moved code -- dimmed-zebra' '
1379 # reuse setup from test before!
1380 test_config color.diff.oldMoved "magenta" &&
1381 test_config color.diff.newMoved "cyan" &&
1382 test_config color.diff.oldMovedAlternative "blue" &&
1383 test_config color.diff.newMovedAlternative "yellow" &&
1384 test_config color.diff.oldMovedDimmed "normal magenta" &&
1385 test_config color.diff.newMovedDimmed "normal cyan" &&
1386 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1387 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1388 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1389 grep -v "index" actual.raw | test_decode_color >actual &&
1390 cat <<-\EOF >expected &&
1391 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1392 <BOLD>--- a/lines.txt<RESET>
1393 <BOLD>+++ b/lines.txt<RESET>
1394 <CYAN>@@ -1,16 +1,16 @@<RESET>
1395 <BMAGENTA>-long line 1<RESET>
1396 <BMAGENTA>-long line 2<RESET>
1397 <BMAGENTA>-long line 3<RESET>
1404 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1405 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1406 <CYAN>+<RESET><CYAN>long line 3<RESET>
1407 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1408 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1409 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1414 <BMAGENTA>-long line 14<RESET>
1415 <BMAGENTA>-long line 15<RESET>
1416 <BMAGENTA>-long line 16<RESET>
1418 test_cmp expected actual
1421 test_expect_success 'cmd option assumes configured colored-moved' '
1422 test_config color.diff.oldMoved "magenta" &&
1423 test_config color.diff.newMoved "cyan" &&
1424 test_config color.diff.oldMovedAlternative "blue" &&
1425 test_config color.diff.newMovedAlternative "yellow" &&
1426 test_config color.diff.oldMovedDimmed "normal magenta" &&
1427 test_config color.diff.newMovedDimmed "normal cyan" &&
1428 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1429 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1430 test_config diff.colorMoved zebra &&
1431 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1432 grep -v "index" actual.raw | test_decode_color >actual &&
1433 cat <<-\EOF >expected &&
1434 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1435 <BOLD>--- a/lines.txt<RESET>
1436 <BOLD>+++ b/lines.txt<RESET>
1437 <CYAN>@@ -1,16 +1,16 @@<RESET>
1438 <MAGENTA>-long line 1<RESET>
1439 <MAGENTA>-long line 2<RESET>
1440 <MAGENTA>-long line 3<RESET>
1447 <CYAN>+<RESET><CYAN>long line 1<RESET>
1448 <CYAN>+<RESET><CYAN>long line 2<RESET>
1449 <CYAN>+<RESET><CYAN>long line 3<RESET>
1450 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1451 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1452 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1457 <MAGENTA>-long line 14<RESET>
1458 <MAGENTA>-long line 15<RESET>
1459 <MAGENTA>-long line 16<RESET>
1461 test_cmp expected actual
1464 test_expect_success 'no effect from --color-moved with --word-diff' '
1465 cat <<-\EOF >text.txt &&
1466 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1469 git commit -a -m "clean state" &&
1470 cat <<-\EOF >text.txt &&
1471 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1473 git diff --color-moved --word-diff >actual &&
1474 git diff --word-diff >expect &&
1475 test_cmp expect actual
1478 test_expect_success 'set up whitespace tests' '
1480 # Note that these lines have no leading or trailing whitespace.
1481 cat <<-\EOF >lines.txt &&
1492 git add lines.txt &&
1493 git commit -m "add poetry" &&
1494 git config color.diff.oldMoved "magenta" &&
1495 git config color.diff.newMoved "cyan"
1498 test_expect_success 'move detection ignoring whitespace ' '
1499 q_to_tab <<-\EOF >lines.txt &&
1503 Qchanged long line 9
1510 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1511 grep -v "index" actual.raw | test_decode_color >actual &&
1512 cat <<-\EOF >expected &&
1513 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1514 <BOLD>--- a/lines.txt<RESET>
1515 <BOLD>+++ b/lines.txt<RESET>
1516 <CYAN>@@ -1,9 +1,9 @@<RESET>
1517 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1518 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1519 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1520 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1526 <RED>-long line 6<RESET>
1527 <RED>-long line 7<RESET>
1528 <RED>-long line 8<RESET>
1529 <RED>-long line 9<RESET>
1531 test_cmp expected actual &&
1533 git diff HEAD --no-renames --color-moved --color \
1534 --color-moved-ws=ignore-all-space >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 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1542 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1543 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1544 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1550 <MAGENTA>-long line 6<RESET>
1551 <MAGENTA>-long line 7<RESET>
1552 <MAGENTA>-long line 8<RESET>
1553 <RED>-long line 9<RESET>
1555 test_cmp expected actual
1558 test_expect_success 'move detection ignoring whitespace changes' '
1560 # Lines 6-8 have a space change, but 9 is new whitespace
1561 q_to_tab <<-\EOF >lines.txt &&
1573 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1574 grep -v "index" actual.raw | test_decode_color >actual &&
1575 cat <<-\EOF >expected &&
1576 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1577 <BOLD>--- a/lines.txt<RESET>
1578 <BOLD>+++ b/lines.txt<RESET>
1579 <CYAN>@@ -1,9 +1,9 @@<RESET>
1580 <GREEN>+<RESET><GREEN>long line 6<RESET>
1581 <GREEN>+<RESET><GREEN>long line 7<RESET>
1582 <GREEN>+<RESET><GREEN>long line 8<RESET>
1583 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1589 <RED>-long line 6<RESET>
1590 <RED>-long line 7<RESET>
1591 <RED>-long line 8<RESET>
1592 <RED>-long line 9<RESET>
1594 test_cmp expected actual &&
1596 git diff HEAD --no-renames --color-moved --color \
1597 --color-moved-ws=ignore-space-change >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 <CYAN>+<RESET><CYAN>long line 6<RESET>
1605 <CYAN>+<RESET><CYAN>long line 7<RESET>
1606 <CYAN>+<RESET><CYAN>long line 8<RESET>
1607 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1613 <MAGENTA>-long line 6<RESET>
1614 <MAGENTA>-long line 7<RESET>
1615 <MAGENTA>-long line 8<RESET>
1616 <RED>-long line 9<RESET>
1618 test_cmp expected actual
1621 test_expect_success 'move detection ignoring whitespace at eol' '
1623 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1624 q_to_tab <<-\EOF >lines.txt &&
1636 # avoid cluttering the output with complaints about our eol whitespace
1637 test_config core.whitespace -blank-at-eol &&
1639 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1640 grep -v "index" actual.raw | test_decode_color >actual &&
1641 cat <<-\EOF >expected &&
1642 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1643 <BOLD>--- a/lines.txt<RESET>
1644 <BOLD>+++ b/lines.txt<RESET>
1645 <CYAN>@@ -1,9 +1,9 @@<RESET>
1646 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1647 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1648 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1649 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1655 <RED>-long line 6<RESET>
1656 <RED>-long line 7<RESET>
1657 <RED>-long line 8<RESET>
1658 <RED>-long line 9<RESET>
1660 test_cmp expected actual &&
1662 git diff HEAD --no-renames --color-moved --color \
1663 --color-moved-ws=ignore-space-at-eol >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 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1671 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1672 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1673 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1679 <MAGENTA>-long line 6<RESET>
1680 <MAGENTA>-long line 7<RESET>
1681 <MAGENTA>-long line 8<RESET>
1682 <RED>-long line 9<RESET>
1684 test_cmp expected actual
1687 test_expect_success 'clean up whitespace-test colors' '
1688 git config --unset color.diff.oldMoved &&
1689 git config --unset color.diff.newMoved
1692 test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1709 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1710 grep -v "index" actual.raw | test_decode_color >actual &&
1711 cat >expected <<-\EOF &&
1712 <BOLD>diff --git a/bar b/bar<RESET>
1713 <BOLD>--- a/bar<RESET>
1714 <BOLD>+++ b/bar<RESET>
1715 <CYAN>@@ -0,0 +1 @@<RESET>
1716 <GREEN>+<RESET><GREEN>line1<RESET>
1717 <BOLD>diff --git a/foo b/foo<RESET>
1718 <BOLD>--- a/foo<RESET>
1719 <BOLD>+++ b/foo<RESET>
1720 <CYAN>@@ -1,2 +1 @@<RESET>
1721 irrelevant_line<RESET>
1725 test_cmp expected actual
1728 test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
1731 nineteen chars 456789
1733 twenty chars 234567890
1743 twenty chars 234567890
1744 nineteen chars 456789
1747 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1748 grep -v "index" actual.raw | test_decode_color >actual &&
1749 cat >expected <<-\EOF &&
1750 <BOLD>diff --git a/bar b/bar<RESET>
1751 <BOLD>--- a/bar<RESET>
1752 <BOLD>+++ b/bar<RESET>
1753 <CYAN>@@ -0,0 +1,2 @@<RESET>
1754 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1755 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1756 <BOLD>diff --git a/foo b/foo<RESET>
1757 <BOLD>--- a/foo<RESET>
1758 <BOLD>+++ b/foo<RESET>
1759 <CYAN>@@ -1,3 +1 @@<RESET>
1760 <RED>-nineteen chars 456789<RESET>
1761 irrelevant_line<RESET>
1762 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1765 test_cmp expected actual
1768 test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1789 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1790 grep -v "index" actual.raw | test_decode_color >actual &&
1791 cat >expected <<-\EOF &&
1792 <BOLD>diff --git a/bar b/bar<RESET>
1793 <BOLD>--- a/bar<RESET>
1794 <BOLD>+++ b/bar<RESET>
1795 <CYAN>@@ -0,0 +1,3 @@<RESET>
1796 <GREEN>+<RESET><GREEN>7charsB<RESET>
1797 <GREEN>+<RESET><GREEN>7charsC<RESET>
1798 <GREEN>+<RESET><GREEN>7charsA<RESET>
1799 <BOLD>diff --git a/foo b/foo<RESET>
1800 <BOLD>--- a/foo<RESET>
1801 <BOLD>+++ b/foo<RESET>
1802 <CYAN>@@ -1,4 +1 @@<RESET>
1803 <RED>-7charsA<RESET>
1804 irrelevant_line<RESET>
1805 <RED>-7charsB<RESET>
1806 <RED>-7charsC<RESET>
1809 test_cmp expected actual
1812 test_expect_success 'move detection with submodules' '
1813 test_create_repo bananas &&
1814 echo ripe >bananas/recipe &&
1815 git -C bananas add recipe &&
1816 test_commit fruit &&
1817 test_commit -C bananas recipe &&
1818 git submodule add ./bananas &&
1820 git commit -a -m "bananas are like a heavy library?" &&
1821 echo foul >bananas/recipe &&
1822 echo ripe >fruit.t &&
1824 git diff --submodule=diff --color-moved --color >actual &&
1826 # no move detection as the moved line is across repository boundaries.
1827 test_decode_color <actual >decoded_actual &&
1828 ! grep BGREEN decoded_actual &&
1829 ! grep BRED decoded_actual &&
1831 # nor did we mess with it another way
1832 git diff --submodule=diff --color >expect.raw &&
1833 test_decode_color <expect.raw >expect &&
1834 test_cmp expect decoded_actual &&
1836 git submodule deinit bananas
1839 test_expect_success 'only move detection ignores white spaces' '
1841 q_to_tab <<-\EOF >text.txt &&
1842 a long line to exceed per-line minimum
1843 another long line to exceed per-line minimum
1847 git commit -m "add text" &&
1848 q_to_tab <<-\EOF >text.txt &&
1849 Qa long line to exceed per-line minimum
1850 Qanother long line to exceed per-line minimum
1854 # Make sure we get a different diff using -w
1855 git diff --color --color-moved -w >actual.raw &&
1856 grep -v "index" actual.raw | test_decode_color >actual &&
1857 q_to_tab <<-\EOF >expected &&
1858 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1859 <BOLD>--- a/text.txt<RESET>
1860 <BOLD>+++ b/text.txt<RESET>
1861 <CYAN>@@ -1,3 +1,3 @@<RESET>
1862 Qa long line to exceed per-line minimum<RESET>
1863 Qanother long line to exceed per-line minimum<RESET>
1864 <RED>-original file<RESET>
1865 <GREEN>+<RESET><GREEN>new file<RESET>
1867 test_cmp expected actual &&
1869 # And now ignoring white space only in the move detection
1870 git diff --color --color-moved \
1871 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
1872 grep -v "index" actual.raw | test_decode_color >actual &&
1873 q_to_tab <<-\EOF >expected &&
1874 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1875 <BOLD>--- a/text.txt<RESET>
1876 <BOLD>+++ b/text.txt<RESET>
1877 <CYAN>@@ -1,3 +1,3 @@<RESET>
1878 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
1879 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
1880 <RED>-original file<RESET>
1881 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>a long line to exceed per-line minimum<RESET>
1882 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>another long line to exceed per-line minimum<RESET>
1883 <GREEN>+<RESET><GREEN>new file<RESET>
1885 test_cmp expected actual
1888 test_expect_success 'compare whitespace delta across moved blocks' '
1891 q_to_tab <<-\EOF >text.txt &&
1895 QBut! <- this stands out
1897 QQdifferent starting
1903 QQQthat has similar lines
1904 QQQto previous blocks, but with different indent
1905 QQQYetQAnotherQoutlierQ
1906 QLine with internal w h i t e s p a c e change
1910 git commit -m "add text.txt" &&
1912 q_to_tab <<-\EOF >text.txt &&
1916 QQQBut! <- this stands out
1924 QQthat has similar lines
1925 QQto previous blocks, but with different indent
1926 QQYetQAnotherQoutlier
1927 QLine with internal whitespace change
1930 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
1931 grep -v "index" actual.raw | test_decode_color >actual &&
1933 q_to_tab <<-\EOF >expected &&
1934 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1935 <BOLD>--- a/text.txt<RESET>
1936 <BOLD>+++ b/text.txt<RESET>
1937 <CYAN>@@ -1,15 +1,15 @@<RESET>
1938 <BOLD;MAGENTA>-QIndented<RESET>
1939 <BOLD;MAGENTA>-QText across<RESET>
1940 <BOLD;MAGENTA>-Qsome lines<RESET>
1941 <RED>-QBut! <- this stands out<RESET>
1942 <BOLD;MAGENTA>-QAdjusting with<RESET>
1943 <BOLD;MAGENTA>-QQdifferent starting<RESET>
1944 <BOLD;MAGENTA>-Qwhite spaces<RESET>
1945 <RED>-QAnother outlier<RESET>
1946 <BOLD;MAGENTA>-QQQIndented<RESET>
1947 <BOLD;MAGENTA>-QQQText across<RESET>
1948 <BOLD;MAGENTA>-QQQfive lines<RESET>
1949 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
1950 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
1951 <RED>-QQQYetQAnotherQoutlierQ<RESET>
1952 <RED>-QLine with internal w h i t e s p a c e change<RESET>
1953 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1954 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1955 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
1956 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
1957 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
1958 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
1959 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
1960 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
1961 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1962 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1963 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
1964 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
1965 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
1966 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
1967 <GREEN>+<RESET>Q<GREEN>Line with internal whitespace change<RESET>
1970 test_cmp expected actual
1973 test_expect_success 'bogus settings in move detection erroring out' '
1974 test_must_fail git diff --color-moved=bogus 2>err &&
1975 test_i18ngrep "must be one of" err &&
1976 test_i18ngrep bogus err &&
1978 test_must_fail git -c diff.colormoved=bogus diff 2>err &&
1979 test_i18ngrep "must be one of" err &&
1980 test_i18ngrep "from command-line config" err &&
1982 test_must_fail git diff --color-moved-ws=bogus 2>err &&
1983 test_i18ngrep "possible values" err &&
1984 test_i18ngrep bogus err &&
1986 test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
1987 test_i18ngrep "possible values" err &&
1988 test_i18ngrep "from command-line config" err
1991 test_expect_success 'compare whitespace delta incompatible with other space options' '
1992 test_must_fail git diff \
1993 --color-moved-ws=allow-indentation-change,ignore-all-space \
1995 test_i18ngrep allow-indentation-change err
1999 test_expect_success 'compare mixed whitespace delta across moved blocks' '
2002 tr Q_ "\t " <<-EOF >text.txt &&
2004 ____too short without
2006 ___being grouped across blank line
2012 ____Indented text to
2013 _Q____be further indented by four spaces across
2015 QQ____These two lines have had their
2016 ____indentation reduced by four spaces
2017 Qdifferent indentation change
2022 git commit -m "add text.txt" &&
2024 tr Q_ "\t " <<-EOF >text.txt &&
2030 QQbe further indented by four spaces across
2035 Q_______being grouped across blank line
2037 Q_QThese two lines have had their
2038 indentation reduced by four spaces
2039 QQdifferent indentation change
2043 git -c color.diff.whitespace="normal red" \
2044 -c core.whitespace=space-before-tab \
2045 diff --color --color-moved --ws-error-highlight=all \
2046 --color-moved-ws=allow-indentation-change >actual.raw &&
2047 grep -v "index" actual.raw | test_decode_color >actual &&
2049 cat <<-\EOF >expected &&
2050 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2051 <BOLD>--- a/text.txt<RESET>
2052 <BOLD>+++ b/text.txt<RESET>
2053 <CYAN>@@ -1,16 +1,16 @@<RESET>
2054 <BOLD;MAGENTA>-<RESET>
2055 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> too short without<RESET>
2056 <BOLD;MAGENTA>-<RESET>
2057 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
2058 <BOLD;MAGENTA>-<RESET>
2059 <RESET>context<RESET>
2062 <RESET>anchor<RESET>
2063 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
2064 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
2065 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
2066 <BOLD;BLUE>-<RESET> <BOLD;BLUE> These two lines have had their<RESET>
2067 <BOLD;BLUE>-<RESET><BOLD;BLUE> indentation reduced by four spaces<RESET>
2068 <BOLD;MAGENTA>-<RESET> <BOLD;MAGENTA>different indentation change<RESET>
2069 <RED>-<RESET><RED> too short<RESET>
2070 <BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
2071 <BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
2072 <BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
2073 <BOLD;YELLOW>+<RESET>
2074 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
2075 <BOLD;YELLOW>+<RESET>
2076 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW> being grouped across blank line<RESET>
2077 <BOLD;YELLOW>+<RESET>
2078 <BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
2079 <BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
2080 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
2081 <GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
2084 test_cmp expected actual
2087 test_expect_success 'combine --ignore-blank-lines with --function-context' '
2088 test_write_lines 1 "" 2 3 4 5 >a &&
2089 test_write_lines 1 2 3 4 >b &&
2090 test_must_fail git diff --no-index \
2091 --ignore-blank-lines --function-context a b >actual.raw &&
2092 sed -n "/@@/,\$p" <actual.raw >actual &&
2093 cat <<-\EOF >expect &&
2102 test_cmp expect actual
2105 test_expect_success 'combine --ignore-blank-lines with --function-context 2' '
2106 test_write_lines a b c "" function 1 2 3 4 5 "" 6 7 8 9 >a &&
2107 test_write_lines "" a b c "" function 1 2 3 4 5 6 7 8 >b &&
2108 test_must_fail git diff --no-index \
2109 --ignore-blank-lines --function-context a b >actual.raw &&
2110 sed -n "/@@/,\$p" <actual.raw >actual &&
2111 cat <<-\EOF >expect &&
2125 test_cmp expect actual