Merge branch 'jc/tree-walk-drop-base-offset'
[git/debian.git] / t / t4015-diff-whitespace.sh
blobb298f220e01fe6de17a5dfe608550a5a57dcf9c6
1 #!/bin/sh
3 # Copyright (c) 2006 Johannes E. Schindelin
6 test_description='Test special whitespace in diff engine.
10 TEST_PASSES_SANITIZE_LEAK=true
11 . ./test-lib.sh
12 . "$TEST_DIRECTORY"/lib-diff.sh
14 test_expect_success "Ray Lehtiniemi's example" '
15 cat <<-\EOF >x &&
16 do {
17 nothing;
18 } while (0);
19 EOF
20 git update-index --add x &&
21 old_hash_x=$(git hash-object x) &&
22 before=$(git rev-parse --short "$old_hash_x") &&
24 cat <<-\EOF >x &&
27 nothing;
29 while (0);
30 EOF
31 new_hash_x=$(git hash-object x) &&
32 after=$(git rev-parse --short "$new_hash_x") &&
34 cat <<-EOF >expect &&
35 diff --git a/x b/x
36 index $before..$after 100644
37 --- a/x
38 +++ b/x
39 @@ -1,3 +1,5 @@
40 -do {
41 +do
43 nothing;
44 -} while (0);
46 +while (0);
47 EOF
49 git diff >out &&
50 test_cmp expect out &&
52 git diff -w >out &&
53 test_cmp expect out &&
55 git diff -b >out &&
56 test_cmp expect out
59 test_expect_success 'another test, without options' '
60 tr Q "\015" <<-\EOF >x &&
61 whitespace at beginning
62 whitespace change
63 whitespace in the middle
64 whitespace at end
65 unchanged line
66 CR at endQ
67 EOF
69 git update-index x &&
70 old_hash_x=$(git hash-object x) &&
71 before=$(git rev-parse --short "$old_hash_x") &&
73 tr "_" " " <<-\EOF >x &&
74 _ whitespace at beginning
75 whitespace change
76 white space in the middle
77 whitespace at end__
78 unchanged line
79 CR at end
80 EOF
81 new_hash_x=$(git hash-object x) &&
82 after=$(git rev-parse --short "$new_hash_x") &&
84 tr "Q_" "\015 " <<-EOF >expect &&
85 diff --git a/x b/x
86 index $before..$after 100644
87 --- a/x
88 +++ b/x
89 @@ -1,6 +1,6 @@
90 -whitespace at beginning
91 -whitespace change
92 -whitespace in the middle
93 -whitespace at end
94 + whitespace at beginning
95 +whitespace change
96 +white space in the middle
97 +whitespace at end__
98 unchanged line
99 -CR at endQ
100 +CR at end
103 git diff >out &&
104 test_cmp expect out &&
106 git diff -w >out &&
107 test_must_be_empty out &&
109 git diff -w -b >out &&
110 test_must_be_empty out &&
112 git diff -w --ignore-space-at-eol >out &&
113 test_must_be_empty out &&
115 git diff -w -b --ignore-space-at-eol >out &&
116 test_must_be_empty out &&
118 git diff -w --ignore-cr-at-eol >out &&
119 test_must_be_empty out &&
121 tr "Q_" "\015 " <<-EOF >expect &&
122 diff --git a/x b/x
123 index $before..$after 100644
124 --- a/x
125 +++ b/x
126 @@ -1,6 +1,6 @@
127 -whitespace at beginning
128 +_ whitespace at beginning
129 whitespace change
130 -whitespace in the middle
131 +white space in the middle
132 whitespace at end__
133 unchanged line
134 CR at end
136 git diff -b >out &&
137 test_cmp expect out &&
139 git diff -b --ignore-space-at-eol >out &&
140 test_cmp expect out &&
142 git diff -b --ignore-cr-at-eol >out &&
143 test_cmp expect out &&
145 tr "Q_" "\015 " <<-EOF >expect &&
146 diff --git a/x b/x
147 index $before..$after 100644
148 --- a/x
149 +++ b/x
150 @@ -1,6 +1,6 @@
151 -whitespace at beginning
152 -whitespace change
153 -whitespace in the middle
154 +_ whitespace at beginning
155 +whitespace change
156 +white space in the middle
157 whitespace at end__
158 unchanged line
159 CR at end
161 git diff --ignore-space-at-eol >out &&
162 test_cmp expect out &&
164 git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
165 test_cmp expect out &&
167 tr "Q_" "\015 " <<-EOF >expect &&
168 diff --git a/x b/x
169 index_$before..$after 100644
170 --- a/x
171 +++ b/x
172 @@ -1,6 +1,6 @@
173 -whitespace at beginning
174 -whitespace change
175 -whitespace in the middle
176 -whitespace at end
177 +_ whitespace at beginning
178 +whitespace_ _change
179 +white space in the middle
180 +whitespace at end__
181 unchanged line
182 CR at end
184 git diff --ignore-cr-at-eol >out &&
185 test_cmp expect out
188 test_expect_success 'ignore-blank-lines: only new lines' '
189 test_seq 5 >x &&
190 git update-index x &&
191 test_seq 5 | sed "/3/i\\
192 " >x &&
193 git diff --ignore-blank-lines >out &&
194 test_must_be_empty out
197 test_expect_success 'ignore-blank-lines: only new lines with space' '
198 test_seq 5 >x &&
199 git update-index x &&
200 test_seq 5 | sed "/3/i\\
201 " >x &&
202 git diff -w --ignore-blank-lines >out &&
203 test_must_be_empty out
206 test_expect_success 'ignore-blank-lines: after change' '
207 cat <<-\EOF >x &&
218 git update-index x &&
219 cat <<-\EOF >x &&
220 change
231 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
232 cat <<-\EOF >expected &&
233 diff --git a/x b/x
234 --- a/x
235 +++ b/x
236 @@ -1,6 +1,7 @@
237 +change
246 compare_diff_patch expected out.tmp
249 test_expect_success 'ignore-blank-lines: before change' '
250 cat <<-\EOF >x &&
260 git update-index x &&
261 cat <<-\EOF >x &&
271 change
273 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
274 cat <<-\EOF >expected &&
275 diff --git a/x b/x
276 --- a/x
277 +++ b/x
278 @@ -4,5 +4,7 @@
285 +change
287 compare_diff_patch expected out.tmp
290 test_expect_success 'ignore-blank-lines: between changes' '
291 cat <<-\EOF >x &&
305 git update-index x &&
306 cat <<-\EOF >x &&
307 change
320 change
322 git diff --ignore-blank-lines >out.tmp &&
323 cat <<-\EOF >expected &&
324 diff --git a/x b/x
325 --- a/x
326 +++ b/x
327 @@ -1,5 +1,7 @@
328 +change
335 @@ -8,5 +8,7 @@
342 +change
344 compare_diff_patch expected out.tmp
347 test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
348 test_seq 10 >x &&
349 git update-index x &&
350 cat <<-\EOF >x &&
351 change
365 change
367 git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
368 cat <<-\EOF >expected &&
369 diff --git a/x b/x
370 --- a/x
371 +++ b/x
372 @@ -1,10 +1,15 @@
373 +change
387 +change
389 compare_diff_patch expected out.tmp
392 test_expect_success 'ignore-blank-lines: scattered spaces' '
393 test_seq 10 >x &&
394 git update-index x &&
395 cat <<-\EOF >x &&
396 change
413 change
415 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
416 cat <<-\EOF >expected &&
417 diff --git a/x b/x
418 --- a/x
419 +++ b/x
420 @@ -1,3 +1,4 @@
421 +change
425 @@ -8,3 +15,4 @@
429 +change
431 compare_diff_patch expected out.tmp
434 test_expect_success 'ignore-blank-lines: spaces coalesce' '
435 test_seq 6 >x &&
436 git update-index x &&
437 cat <<-\EOF >x &&
438 change
448 change
450 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
451 cat <<-\EOF >expected &&
452 diff --git a/x b/x
453 --- a/x
454 +++ b/x
455 @@ -1,6 +1,11 @@
456 +change
466 +change
468 compare_diff_patch expected out.tmp
471 test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
472 test_seq 16 >x &&
473 git update-index x &&
474 cat <<-\EOF >x &&
475 change
482 change
490 change
497 change
499 git diff --ignore-blank-lines >out.tmp &&
500 cat <<-\EOF >expected &&
501 diff --git a/x b/x
502 --- a/x
503 +++ b/x
504 @@ -1,8 +1,11 @@
505 +change
512 +change
516 @@ -9,8 +13,11 @@
520 +change
527 +change
529 compare_diff_patch expected out.tmp
532 test_expect_success 'check mixed spaces and tabs in indent' '
533 # This is indented with SP HT SP.
534 echo " foo();" >x &&
535 test_must_fail git diff --check >check &&
536 grep "space before tab in indent" check
539 test_expect_success 'check mixed tabs and spaces in indent' '
540 # This is indented with HT SP HT.
541 echo " foo();" >x &&
542 test_must_fail git diff --check >check &&
543 grep "space before tab in indent" check
546 test_expect_success 'check with no whitespace errors' '
547 git commit -m "snapshot" &&
548 echo "foo();" >x &&
549 git diff --check
552 test_expect_success 'check with trailing whitespace' '
553 echo "foo(); " >x &&
554 test_must_fail git diff --check
557 test_expect_success 'check with space before tab in indent' '
558 # indent has space followed by hard tab
559 echo " foo();" >x &&
560 test_must_fail git diff --check
563 test_expect_success '--check and --exit-code are not exclusive' '
564 git checkout x &&
565 git diff --check --exit-code
568 test_expect_success '--check and --quiet are not exclusive' '
569 git diff --check --quiet
572 test_expect_success '-w and --exit-code interact sensibly' '
573 test_when_finished "git checkout x" &&
575 test_seq 15 &&
576 echo " 16"
577 } >x &&
578 test_must_fail git diff --exit-code &&
579 git diff -w >actual &&
580 test_must_be_empty actual &&
581 git diff -w --exit-code
584 test_expect_success '-I and --exit-code interact sensibly' '
585 test_when_finished "git checkout x" &&
587 test_seq 15 &&
588 echo " 16"
589 } >x &&
590 test_must_fail git diff --exit-code &&
591 git diff -I. >actual &&
592 test_must_be_empty actual &&
593 git diff -I. --exit-code
596 test_expect_success 'check staged with no whitespace errors' '
597 echo "foo();" >x &&
598 git add x &&
599 git diff --cached --check
602 test_expect_success 'check staged with trailing whitespace' '
603 echo "foo(); " >x &&
604 git add x &&
605 test_must_fail git diff --cached --check
608 test_expect_success 'check staged with space before tab in indent' '
609 # indent has space followed by hard tab
610 echo " foo();" >x &&
611 git add x &&
612 test_must_fail git diff --cached --check
615 test_expect_success 'check with no whitespace errors (diff-index)' '
616 echo "foo();" >x &&
617 git add x &&
618 git diff-index --check HEAD
621 test_expect_success 'check with trailing whitespace (diff-index)' '
622 echo "foo(); " >x &&
623 git add x &&
624 test_must_fail git diff-index --check HEAD
627 test_expect_success 'check with space before tab in indent (diff-index)' '
628 # indent has space followed by hard tab
629 echo " foo();" >x &&
630 git add x &&
631 test_must_fail git diff-index --check HEAD
634 test_expect_success 'check staged with no whitespace errors (diff-index)' '
635 echo "foo();" >x &&
636 git add x &&
637 git diff-index --cached --check HEAD
640 test_expect_success 'check staged with trailing whitespace (diff-index)' '
641 echo "foo(); " >x &&
642 git add x &&
643 test_must_fail git diff-index --cached --check HEAD
646 test_expect_success 'check staged with space before tab in indent (diff-index)' '
647 # indent has space followed by hard tab
648 echo " foo();" >x &&
649 git add x &&
650 test_must_fail git diff-index --cached --check HEAD
653 test_expect_success 'check with no whitespace errors (diff-tree)' '
654 echo "foo();" >x &&
655 git commit -m "new commit" x &&
656 git diff-tree --check HEAD^ HEAD
659 test_expect_success 'check with trailing whitespace (diff-tree)' '
660 echo "foo(); " >x &&
661 git commit -m "another commit" x &&
662 test_must_fail git diff-tree --check HEAD^ HEAD
665 test_expect_success 'check with space before tab in indent (diff-tree)' '
666 # indent has space followed by hard tab
667 echo " foo();" >x &&
668 git commit -m "yet another" x &&
669 test_must_fail git diff-tree --check HEAD^ HEAD
672 test_expect_success 'check with ignored trailing whitespace attr (diff-tree)' '
673 test_when_finished "git reset --hard HEAD^" &&
675 # create a whitespace error that should be ignored
676 echo "* -whitespace" >.gitattributes &&
677 git add .gitattributes &&
678 echo "foo(); " >x &&
679 git add x &&
680 git commit -m "add trailing space" &&
682 # with a worktree diff-tree ignores the whitespace error
683 git diff-tree --root --check HEAD &&
685 # without a worktree diff-tree still ignores the whitespace error
686 git -C .git diff-tree --root --check HEAD
689 test_expect_success 'check trailing whitespace (trailing-space: off)' '
690 git config core.whitespace "-trailing-space" &&
691 echo "foo (); " >x &&
692 git diff --check
695 test_expect_success 'check trailing whitespace (trailing-space: on)' '
696 git config core.whitespace "trailing-space" &&
697 echo "foo (); " >x &&
698 test_must_fail git diff --check
701 test_expect_success 'check space before tab in indent (space-before-tab: off)' '
702 # indent contains space followed by HT
703 git config core.whitespace "-space-before-tab" &&
704 echo " foo ();" >x &&
705 git diff --check
708 test_expect_success 'check space before tab in indent (space-before-tab: on)' '
709 # indent contains space followed by HT
710 git config core.whitespace "space-before-tab" &&
711 echo " foo (); " >x &&
712 test_must_fail git diff --check
715 test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
716 git config core.whitespace "-indent-with-non-tab" &&
717 echo " foo ();" >x &&
718 git diff --check
721 test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
722 git config core.whitespace "indent-with-non-tab" &&
723 echo " foo ();" >x &&
724 test_must_fail git diff --check
727 test_expect_success 'ditto, but tabwidth=9' '
728 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
729 git diff --check
732 test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
733 git config core.whitespace "indent-with-non-tab" &&
734 echo " foo ();" >x &&
735 test_must_fail git diff --check
738 test_expect_success 'ditto, but tabwidth=10' '
739 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
740 test_must_fail git diff --check
743 test_expect_success 'ditto, but tabwidth=20' '
744 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
745 git diff --check
748 test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
749 git config core.whitespace "-tab-in-indent" &&
750 echo " foo ();" >x &&
751 git diff --check
754 test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
755 git config core.whitespace "tab-in-indent" &&
756 echo " foo ();" >x &&
757 test_must_fail git diff --check
760 test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
761 git config core.whitespace "tab-in-indent" &&
762 echo " foo ();" >x &&
763 test_must_fail git diff --check
766 test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
767 git config core.whitespace "tab-in-indent,tabwidth=1" &&
768 test_must_fail git diff --check
771 test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
772 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
773 echo "foo ();" >x &&
774 test_must_fail git diff --check
777 test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
778 git config --unset core.whitespace &&
779 echo "x whitespace" >.gitattributes &&
780 echo " foo ();" >x &&
781 git diff --check &&
782 rm -f .gitattributes
785 test_expect_success 'line numbers in --check output are correct' '
786 echo "" >x &&
787 echo "foo(); " >>x &&
788 test_must_fail git diff --check >check &&
789 grep "x:2:" check
792 test_expect_success 'checkdiff detects new trailing blank lines (1)' '
793 echo "foo();" >x &&
794 echo "" >>x &&
795 test_must_fail git diff --check >check &&
796 grep "new blank line" check
799 test_expect_success 'checkdiff detects new trailing blank lines (2)' '
800 test_write_lines a b "" "" >x &&
801 git add x &&
802 test_write_lines a "" "" "" "" >x &&
803 test_must_fail git diff --check >check &&
804 grep "new blank line" check
807 test_expect_success 'checkdiff allows new blank lines' '
808 git checkout x &&
809 mv x y &&
811 echo "/* This is new */" &&
812 echo "" &&
813 cat y
814 ) >x &&
815 git diff --check
818 test_expect_success 'whitespace-only changes not reported (diff)' '
819 git reset --hard &&
820 echo >x "hello world" &&
821 git add x &&
822 git commit -m "hello 1" &&
823 echo >x "hello world" &&
824 git diff -b >actual &&
825 test_must_be_empty actual
828 test_expect_success 'whitespace-only changes not reported (diffstat)' '
829 # reuse state from previous test
830 git diff --stat -b >actual &&
831 test_must_be_empty actual
834 test_expect_success 'whitespace changes with modification reported (diffstat)' '
835 git reset --hard &&
836 echo >x "hello world" &&
837 git update-index --chmod=+x x &&
838 git diff --stat --cached -b >actual &&
839 cat <<-EOF >expect &&
840 x | 0
841 1 file changed, 0 insertions(+), 0 deletions(-)
843 test_cmp expect actual
846 test_expect_success 'whitespace-only changes reported across renames (diffstat)' '
847 git reset --hard &&
848 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i" || return 1; done >x &&
849 git add x &&
850 git commit -m "base" &&
851 sed -e "5s/^/ /" x >z &&
852 git rm x &&
853 git add z &&
854 git diff -w -M --cached --stat >actual &&
855 cat <<-EOF >expect &&
856 x => z | 0
857 1 file changed, 0 insertions(+), 0 deletions(-)
859 test_cmp expect actual
862 test_expect_success 'whitespace-only changes reported across renames' '
863 git reset --hard HEAD~1 &&
864 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i" || return 1; done >x &&
865 git add x &&
866 hash_x=$(git hash-object x) &&
867 before=$(git rev-parse --short "$hash_x") &&
868 git commit -m "base" &&
869 sed -e "5s/^/ /" x >z &&
870 git rm x &&
871 git add z &&
872 hash_z=$(git hash-object z) &&
873 after=$(git rev-parse --short "$hash_z") &&
874 git diff -w -M --cached >actual.raw &&
875 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" actual.raw >actual &&
876 cat <<-EOF >expect &&
877 diff --git a/x b/z
878 similarity index NUM%
879 rename from x
880 rename to z
881 index $before..$after 100644
883 test_cmp expect actual
886 cat >expected <<\EOF
887 diff --git a/empty b/void
888 similarity index 100%
889 rename from empty
890 rename to void
893 test_expect_success 'rename empty' '
894 git reset --hard &&
895 >empty &&
896 git add empty &&
897 git commit -m empty &&
898 git mv empty void &&
899 git diff -w --cached -M >current &&
900 test_cmp expected current
903 test_expect_success 'combined diff with autocrlf conversion' '
905 git reset --hard &&
906 test_commit "one side" x hello one-side &&
907 git checkout HEAD^ &&
908 echo >x goodbye &&
909 git commit -m "the other side" x &&
910 git config core.autocrlf true &&
911 test_must_fail git merge one-side >actual &&
912 test_i18ngrep "Automatic merge failed" actual &&
914 git diff >actual.raw &&
915 sed -e "1,/^@@@/d" actual.raw >actual &&
916 ! grep "^-" actual
920 # Start testing the colored format for whitespace checks
922 test_expect_success 'setup diff colors' '
923 git config color.diff.plain normal &&
924 git config color.diff.meta bold &&
925 git config color.diff.frag cyan &&
926 git config color.diff.func normal &&
927 git config color.diff.old red &&
928 git config color.diff.new green &&
929 git config color.diff.commit yellow &&
930 git config color.diff.whitespace blue &&
932 git config core.autocrlf false
935 test_expect_success 'diff that introduces a line with only tabs' '
936 git config core.whitespace blank-at-eol &&
937 git reset --hard &&
938 echo "test" >x &&
939 old_hash_x=$(git hash-object x) &&
940 before=$(git rev-parse --short "$old_hash_x") &&
941 git commit -m "initial" x &&
942 echo "{NTN}" | tr "NT" "\n\t" >>x &&
943 new_hash_x=$(git hash-object x) &&
944 after=$(git rev-parse --short "$new_hash_x") &&
945 git diff --color >current.raw &&
946 test_decode_color <current.raw >current &&
948 cat >expected <<-EOF &&
949 <BOLD>diff --git a/x b/x<RESET>
950 <BOLD>index $before..$after 100644<RESET>
951 <BOLD>--- a/x<RESET>
952 <BOLD>+++ b/x<RESET>
953 <CYAN>@@ -1 +1,4 @@<RESET>
954 test<RESET>
955 <GREEN>+<RESET><GREEN>{<RESET>
956 <GREEN>+<RESET><BLUE> <RESET>
957 <GREEN>+<RESET><GREEN>}<RESET>
960 test_cmp expected current
963 test_expect_success 'diff that introduces and removes ws breakages' '
964 git reset --hard &&
966 echo "0. blank-at-eol " &&
967 echo "1. blank-at-eol "
968 } >x &&
969 old_hash_x=$(git hash-object x) &&
970 before=$(git rev-parse --short "$old_hash_x") &&
971 git commit -a --allow-empty -m preimage &&
973 echo "0. blank-at-eol " &&
974 echo "1. still-blank-at-eol " &&
975 echo "2. and a new line "
976 } >x &&
977 new_hash_x=$(git hash-object x) &&
978 after=$(git rev-parse --short "$new_hash_x") &&
980 git diff --color >current.raw &&
981 test_decode_color <current.raw >current &&
983 cat >expected <<-EOF &&
984 <BOLD>diff --git a/x b/x<RESET>
985 <BOLD>index $before..$after 100644<RESET>
986 <BOLD>--- a/x<RESET>
987 <BOLD>+++ b/x<RESET>
988 <CYAN>@@ -1,2 +1,3 @@<RESET>
989 0. blank-at-eol <RESET>
990 <RED>-1. blank-at-eol <RESET>
991 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
992 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
995 test_cmp expected current
998 test_expect_success 'ws-error-highlight test setup' '
1000 git reset --hard &&
1002 echo "0. blank-at-eol " &&
1003 echo "1. blank-at-eol "
1004 } >x &&
1005 old_hash_x=$(git hash-object x) &&
1006 before=$(git rev-parse --short "$old_hash_x") &&
1007 git commit -a --allow-empty -m preimage &&
1009 echo "0. blank-at-eol " &&
1010 echo "1. still-blank-at-eol " &&
1011 echo "2. and a new line "
1012 } >x &&
1013 new_hash_x=$(git hash-object x) &&
1014 after=$(git rev-parse --short "$new_hash_x") &&
1016 cat >expect.default-old <<-EOF &&
1017 <BOLD>diff --git a/x b/x<RESET>
1018 <BOLD>index $before..$after 100644<RESET>
1019 <BOLD>--- a/x<RESET>
1020 <BOLD>+++ b/x<RESET>
1021 <CYAN>@@ -1,2 +1,3 @@<RESET>
1022 0. blank-at-eol <RESET>
1023 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1024 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1025 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1028 cat >expect.all <<-EOF &&
1029 <BOLD>diff --git a/x b/x<RESET>
1030 <BOLD>index $before..$after 100644<RESET>
1031 <BOLD>--- a/x<RESET>
1032 <BOLD>+++ b/x<RESET>
1033 <CYAN>@@ -1,2 +1,3 @@<RESET>
1034 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
1035 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1036 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1037 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1040 cat >expect.none <<-EOF
1041 <BOLD>diff --git a/x b/x<RESET>
1042 <BOLD>index $before..$after 100644<RESET>
1043 <BOLD>--- a/x<RESET>
1044 <BOLD>+++ b/x<RESET>
1045 <CYAN>@@ -1,2 +1,3 @@<RESET>
1046 0. blank-at-eol <RESET>
1047 <RED>-1. blank-at-eol <RESET>
1048 <GREEN>+1. still-blank-at-eol <RESET>
1049 <GREEN>+2. and a new line <RESET>
1054 test_expect_success 'test --ws-error-highlight option' '
1056 git diff --color --ws-error-highlight=default,old >current.raw &&
1057 test_decode_color <current.raw >current &&
1058 test_cmp expect.default-old current &&
1060 git diff --color --ws-error-highlight=all >current.raw &&
1061 test_decode_color <current.raw >current &&
1062 test_cmp expect.all current &&
1064 git diff --color --ws-error-highlight=none >current.raw &&
1065 test_decode_color <current.raw >current &&
1066 test_cmp expect.none current
1070 test_expect_success 'test diff.wsErrorHighlight config' '
1072 git -c diff.wsErrorHighlight=default,old diff --color >current.raw &&
1073 test_decode_color <current.raw >current &&
1074 test_cmp expect.default-old current &&
1076 git -c diff.wsErrorHighlight=all diff --color >current.raw &&
1077 test_decode_color <current.raw >current &&
1078 test_cmp expect.all current &&
1080 git -c diff.wsErrorHighlight=none diff --color >current.raw &&
1081 test_decode_color <current.raw >current &&
1082 test_cmp expect.none current
1086 test_expect_success 'option overrides diff.wsErrorHighlight' '
1088 git -c diff.wsErrorHighlight=none \
1089 diff --color --ws-error-highlight=default,old >current.raw &&
1090 test_decode_color <current.raw >current &&
1091 test_cmp expect.default-old current &&
1093 git -c diff.wsErrorHighlight=default \
1094 diff --color --ws-error-highlight=all >current.raw &&
1095 test_decode_color <current.raw >current &&
1096 test_cmp expect.all current &&
1098 git -c diff.wsErrorHighlight=all \
1099 diff --color --ws-error-highlight=none >current.raw &&
1100 test_decode_color <current.raw >current &&
1101 test_cmp expect.none current
1105 test_expect_success 'detect moved code, complete file' '
1106 git reset --hard &&
1107 cat <<-\EOF >test.c &&
1108 #include<stdio.h>
1109 main()
1111 printf("Hello World");
1114 git add test.c &&
1115 git commit -m "add main function" &&
1116 file=$(git rev-parse --short HEAD:test.c) &&
1117 git mv test.c main.c &&
1118 test_config color.diff.oldMoved "normal red" &&
1119 test_config color.diff.newMoved "normal green" &&
1120 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1121 test_decode_color <actual.raw >actual &&
1122 cat >expected <<-EOF &&
1123 <BOLD>diff --git a/main.c b/main.c<RESET>
1124 <BOLD>new file mode 100644<RESET>
1125 <BOLD>index 0000000..$file<RESET>
1126 <BOLD>--- /dev/null<RESET>
1127 <BOLD>+++ b/main.c<RESET>
1128 <CYAN>@@ -0,0 +1,5 @@<RESET>
1129 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1130 <BGREEN>+<RESET><BGREEN>main()<RESET>
1131 <BGREEN>+<RESET><BGREEN>{<RESET>
1132 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1133 <BGREEN>+<RESET><BGREEN>}<RESET>
1134 <BOLD>diff --git a/test.c b/test.c<RESET>
1135 <BOLD>deleted file mode 100644<RESET>
1136 <BOLD>index $file..0000000<RESET>
1137 <BOLD>--- a/test.c<RESET>
1138 <BOLD>+++ /dev/null<RESET>
1139 <CYAN>@@ -1,5 +0,0 @@<RESET>
1140 <BRED>-#include<stdio.h><RESET>
1141 <BRED>-main()<RESET>
1142 <BRED>-{<RESET>
1143 <BRED>-printf("Hello World");<RESET>
1144 <BRED>-}<RESET>
1147 test_cmp expected actual
1150 test_expect_success 'detect malicious moved code, inside file' '
1151 test_config color.diff.oldMoved "normal red" &&
1152 test_config color.diff.newMoved "normal green" &&
1153 test_config color.diff.oldMovedAlternative "blue" &&
1154 test_config color.diff.newMovedAlternative "yellow" &&
1155 git reset --hard &&
1156 cat <<-\EOF >main.c &&
1157 #include<stdio.h>
1158 int stuff()
1160 printf("Hello ");
1161 printf("World\n");
1164 int secure_foo(struct user *u)
1166 if (!u->is_allowed_foo)
1167 return;
1168 foo(u);
1171 int main()
1173 foo();
1176 cat <<-\EOF >test.c &&
1177 #include<stdio.h>
1178 int bar()
1180 printf("Hello World, but different\n");
1183 int another_function()
1185 bar();
1188 git add main.c test.c &&
1189 git commit -m "add main and test file" &&
1190 before_main=$(git rev-parse --short HEAD:main.c) &&
1191 before_test=$(git rev-parse --short HEAD:test.c) &&
1192 cat <<-\EOF >main.c &&
1193 #include<stdio.h>
1194 int stuff()
1196 printf("Hello ");
1197 printf("World\n");
1200 int main()
1202 foo();
1205 cat <<-\EOF >test.c &&
1206 #include<stdio.h>
1207 int bar()
1209 printf("Hello World, but different\n");
1212 int secure_foo(struct user *u)
1214 foo(u);
1215 if (!u->is_allowed_foo)
1216 return;
1219 int another_function()
1221 bar();
1224 hash_main=$(git hash-object main.c) &&
1225 after_main=$(git rev-parse --short "$hash_main") &&
1226 hash_test=$(git hash-object test.c) &&
1227 after_test=$(git rev-parse --short "$hash_test") &&
1228 git diff HEAD --no-renames --color-moved=zebra --color >actual.raw &&
1229 test_decode_color <actual.raw >actual &&
1230 cat <<-EOF >expected &&
1231 <BOLD>diff --git a/main.c b/main.c<RESET>
1232 <BOLD>index $before_main..$after_main 100644<RESET>
1233 <BOLD>--- a/main.c<RESET>
1234 <BOLD>+++ b/main.c<RESET>
1235 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1236 printf("World\n");<RESET>
1237 }<RESET>
1238 <RESET>
1239 <BRED>-int secure_foo(struct user *u)<RESET>
1240 <BRED>-{<RESET>
1241 <BLUE>-if (!u->is_allowed_foo)<RESET>
1242 <BLUE>-return;<RESET>
1243 <RED>-foo(u);<RESET>
1244 <RED>-}<RESET>
1245 <RED>-<RESET>
1246 int main()<RESET>
1247 {<RESET>
1248 foo();<RESET>
1249 <BOLD>diff --git a/test.c b/test.c<RESET>
1250 <BOLD>index $before_test..$after_test 100644<RESET>
1251 <BOLD>--- a/test.c<RESET>
1252 <BOLD>+++ b/test.c<RESET>
1253 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1254 printf("Hello World, but different\n");<RESET>
1255 }<RESET>
1256 <RESET>
1257 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1258 <BGREEN>+<RESET><BGREEN>{<RESET>
1259 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1260 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1261 <BGREEN>+<RESET><BGREEN>return;<RESET>
1262 <GREEN>+<RESET><GREEN>}<RESET>
1263 <GREEN>+<RESET>
1264 int another_function()<RESET>
1265 {<RESET>
1266 bar();<RESET>
1269 test_cmp expected actual
1272 test_expect_success 'plain moved code, inside file' '
1273 test_config color.diff.oldMoved "normal red" &&
1274 test_config color.diff.newMoved "normal green" &&
1275 test_config color.diff.oldMovedAlternative "blue" &&
1276 test_config color.diff.newMovedAlternative "yellow" &&
1277 # needs previous test as setup
1278 git diff HEAD --no-renames --color-moved=plain --color >actual.raw &&
1279 test_decode_color <actual.raw >actual &&
1280 cat <<-EOF >expected &&
1281 <BOLD>diff --git a/main.c b/main.c<RESET>
1282 <BOLD>index $before_main..$after_main 100644<RESET>
1283 <BOLD>--- a/main.c<RESET>
1284 <BOLD>+++ b/main.c<RESET>
1285 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1286 printf("World\n");<RESET>
1287 }<RESET>
1288 <RESET>
1289 <BRED>-int secure_foo(struct user *u)<RESET>
1290 <BRED>-{<RESET>
1291 <BRED>-if (!u->is_allowed_foo)<RESET>
1292 <BRED>-return;<RESET>
1293 <BRED>-foo(u);<RESET>
1294 <BRED>-}<RESET>
1295 <BRED>-<RESET>
1296 int main()<RESET>
1297 {<RESET>
1298 foo();<RESET>
1299 <BOLD>diff --git a/test.c b/test.c<RESET>
1300 <BOLD>index $before_test..$after_test 100644<RESET>
1301 <BOLD>--- a/test.c<RESET>
1302 <BOLD>+++ b/test.c<RESET>
1303 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1304 printf("Hello World, but different\n");<RESET>
1305 }<RESET>
1306 <RESET>
1307 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1308 <BGREEN>+<RESET><BGREEN>{<RESET>
1309 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1310 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1311 <BGREEN>+<RESET><BGREEN>return;<RESET>
1312 <BGREEN>+<RESET><BGREEN>}<RESET>
1313 <BGREEN>+<RESET>
1314 int another_function()<RESET>
1315 {<RESET>
1316 bar();<RESET>
1319 test_cmp expected actual
1322 test_expect_success 'detect blocks of moved code' '
1323 git reset --hard &&
1324 cat <<-\EOF >lines.txt &&
1325 long line 1
1326 long line 2
1327 long line 3
1328 line 4
1329 line 5
1330 line 6
1331 line 7
1332 line 8
1333 line 9
1334 line 10
1335 line 11
1336 line 12
1337 line 13
1338 long line 14
1339 long line 15
1340 long line 16
1342 git add lines.txt &&
1343 git commit -m "add poetry" &&
1344 cat <<-\EOF >lines.txt &&
1345 line 4
1346 line 5
1347 line 6
1348 line 7
1349 line 8
1350 line 9
1351 long line 1
1352 long line 2
1353 long line 3
1354 long line 14
1355 long line 15
1356 long line 16
1357 line 10
1358 line 11
1359 line 12
1360 line 13
1362 test_config color.diff.oldMoved "magenta" &&
1363 test_config color.diff.newMoved "cyan" &&
1364 test_config color.diff.oldMovedAlternative "blue" &&
1365 test_config color.diff.newMovedAlternative "yellow" &&
1366 test_config color.diff.oldMovedDimmed "normal magenta" &&
1367 test_config color.diff.newMovedDimmed "normal cyan" &&
1368 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1369 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1370 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1371 grep -v "index" actual.raw | test_decode_color >actual &&
1372 cat <<-\EOF >expected &&
1373 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1374 <BOLD>--- a/lines.txt<RESET>
1375 <BOLD>+++ b/lines.txt<RESET>
1376 <CYAN>@@ -1,16 +1,16 @@<RESET>
1377 <MAGENTA>-long line 1<RESET>
1378 <MAGENTA>-long line 2<RESET>
1379 <MAGENTA>-long line 3<RESET>
1380 line 4<RESET>
1381 line 5<RESET>
1382 line 6<RESET>
1383 line 7<RESET>
1384 line 8<RESET>
1385 line 9<RESET>
1386 <CYAN>+<RESET><CYAN>long line 1<RESET>
1387 <CYAN>+<RESET><CYAN>long line 2<RESET>
1388 <CYAN>+<RESET><CYAN>long line 3<RESET>
1389 <CYAN>+<RESET><CYAN>long line 14<RESET>
1390 <CYAN>+<RESET><CYAN>long line 15<RESET>
1391 <CYAN>+<RESET><CYAN>long line 16<RESET>
1392 line 10<RESET>
1393 line 11<RESET>
1394 line 12<RESET>
1395 line 13<RESET>
1396 <MAGENTA>-long line 14<RESET>
1397 <MAGENTA>-long line 15<RESET>
1398 <MAGENTA>-long line 16<RESET>
1400 test_cmp expected actual
1404 test_expect_success 'detect permutations inside moved code -- dimmed-zebra' '
1405 # reuse setup from test before!
1406 test_config color.diff.oldMoved "magenta" &&
1407 test_config color.diff.newMoved "cyan" &&
1408 test_config color.diff.oldMovedAlternative "blue" &&
1409 test_config color.diff.newMovedAlternative "yellow" &&
1410 test_config color.diff.oldMovedDimmed "normal magenta" &&
1411 test_config color.diff.newMovedDimmed "normal cyan" &&
1412 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1413 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1414 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1415 grep -v "index" actual.raw | test_decode_color >actual &&
1416 cat <<-\EOF >expected &&
1417 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1418 <BOLD>--- a/lines.txt<RESET>
1419 <BOLD>+++ b/lines.txt<RESET>
1420 <CYAN>@@ -1,16 +1,16 @@<RESET>
1421 <BMAGENTA>-long line 1<RESET>
1422 <BMAGENTA>-long line 2<RESET>
1423 <BMAGENTA>-long line 3<RESET>
1424 line 4<RESET>
1425 line 5<RESET>
1426 line 6<RESET>
1427 line 7<RESET>
1428 line 8<RESET>
1429 line 9<RESET>
1430 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1431 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1432 <CYAN>+<RESET><CYAN>long line 3<RESET>
1433 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1434 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1435 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1436 line 10<RESET>
1437 line 11<RESET>
1438 line 12<RESET>
1439 line 13<RESET>
1440 <BMAGENTA>-long line 14<RESET>
1441 <BMAGENTA>-long line 15<RESET>
1442 <BMAGENTA>-long line 16<RESET>
1444 test_cmp expected actual
1447 test_expect_success 'zebra alternate color is only used when necessary' '
1448 cat >old.txt <<-\EOF &&
1449 line 1A should be marked as oldMoved newMovedAlternate
1450 line 1B should be marked as oldMoved newMovedAlternate
1451 unchanged
1452 line 2A should be marked as oldMoved newMovedAlternate
1453 line 2B should be marked as oldMoved newMovedAlternate
1454 line 3A should be marked as oldMovedAlternate newMoved
1455 line 3B should be marked as oldMovedAlternate newMoved
1456 unchanged
1457 line 4A should be marked as oldMoved newMovedAlternate
1458 line 4B should be marked as oldMoved newMovedAlternate
1459 line 5A should be marked as oldMovedAlternate newMoved
1460 line 5B should be marked as oldMovedAlternate newMoved
1461 line 6A should be marked as oldMoved newMoved
1462 line 6B should be marked as oldMoved newMoved
1464 cat >new.txt <<-\EOF &&
1465 line 1A should be marked as oldMoved newMovedAlternate
1466 line 1B should be marked as oldMoved newMovedAlternate
1467 unchanged
1468 line 3A should be marked as oldMovedAlternate newMoved
1469 line 3B should be marked as oldMovedAlternate newMoved
1470 line 2A should be marked as oldMoved newMovedAlternate
1471 line 2B should be marked as oldMoved newMovedAlternate
1472 unchanged
1473 line 6A should be marked as oldMoved newMoved
1474 line 6B should be marked as oldMoved newMoved
1475 line 4A should be marked as oldMoved newMovedAlternate
1476 line 4B should be marked as oldMoved newMovedAlternate
1477 line 5A should be marked as oldMovedAlternate newMoved
1478 line 5B should be marked as oldMovedAlternate newMoved
1480 test_expect_code 1 git diff --no-index --color --color-moved=zebra \
1481 --color-moved-ws=allow-indentation-change \
1482 old.txt new.txt >output &&
1483 grep -v index output | test_decode_color >actual &&
1484 cat >expected <<-\EOF &&
1485 <BOLD>diff --git a/old.txt b/new.txt<RESET>
1486 <BOLD>--- a/old.txt<RESET>
1487 <BOLD>+++ b/new.txt<RESET>
1488 <CYAN>@@ -1,14 +1,14 @@<RESET>
1489 <BOLD;MAGENTA>-line 1A should be marked as oldMoved newMovedAlternate<RESET>
1490 <BOLD;MAGENTA>-line 1B should be marked as oldMoved newMovedAlternate<RESET>
1491 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 1A should be marked as oldMoved newMovedAlternate<RESET>
1492 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 1B should be marked as oldMoved newMovedAlternate<RESET>
1493 unchanged<RESET>
1494 <BOLD;MAGENTA>-line 2A should be marked as oldMoved newMovedAlternate<RESET>
1495 <BOLD;MAGENTA>-line 2B should be marked as oldMoved newMovedAlternate<RESET>
1496 <BOLD;BLUE>-line 3A should be marked as oldMovedAlternate newMoved<RESET>
1497 <BOLD;BLUE>-line 3B should be marked as oldMovedAlternate newMoved<RESET>
1498 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 3A should be marked as oldMovedAlternate newMoved<RESET>
1499 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 3B should be marked as oldMovedAlternate newMoved<RESET>
1500 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 2A should be marked as oldMoved newMovedAlternate<RESET>
1501 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 2B should be marked as oldMoved newMovedAlternate<RESET>
1502 unchanged<RESET>
1503 <BOLD;MAGENTA>-line 4A should be marked as oldMoved newMovedAlternate<RESET>
1504 <BOLD;MAGENTA>-line 4B should be marked as oldMoved newMovedAlternate<RESET>
1505 <BOLD;BLUE>-line 5A should be marked as oldMovedAlternate newMoved<RESET>
1506 <BOLD;BLUE>-line 5B should be marked as oldMovedAlternate newMoved<RESET>
1507 <BOLD;MAGENTA>-line 6A should be marked as oldMoved newMoved<RESET>
1508 <BOLD;MAGENTA>-line 6B should be marked as oldMoved newMoved<RESET>
1509 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 6A should be marked as oldMoved newMoved<RESET>
1510 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 6B should be marked as oldMoved newMoved<RESET>
1511 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 4A should be marked as oldMoved newMovedAlternate<RESET>
1512 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 4B should be marked as oldMoved newMovedAlternate<RESET>
1513 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 5A should be marked as oldMovedAlternate newMoved<RESET>
1514 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 5B should be marked as oldMovedAlternate newMoved<RESET>
1516 test_cmp expected actual
1519 test_expect_success 'short lines of opposite sign do not get marked as moved' '
1520 cat >old.txt <<-\EOF &&
1521 this line should be marked as moved
1522 unchanged
1523 unchanged
1524 unchanged
1525 unchanged
1526 too short
1527 this line should be marked as oldMoved newMoved
1528 this line should be marked as oldMovedAlternate newMoved
1529 unchanged 1
1530 unchanged 2
1531 unchanged 3
1532 unchanged 4
1533 this line should be marked as oldMoved newMoved/newMovedAlternate
1535 cat >new.txt <<-\EOF &&
1536 too short
1537 unchanged
1538 unchanged
1539 this line should be marked as moved
1540 too short
1541 unchanged
1542 unchanged
1543 this line should be marked as oldMoved newMoved/newMovedAlternate
1544 unchanged 1
1545 unchanged 2
1546 this line should be marked as oldMovedAlternate newMoved
1547 this line should be marked as oldMoved newMoved/newMovedAlternate
1548 unchanged 3
1549 this line should be marked as oldMoved newMoved
1550 unchanged 4
1552 test_expect_code 1 git diff --no-index --color --color-moved=zebra \
1553 old.txt new.txt >output && cat output &&
1554 grep -v index output | test_decode_color >actual &&
1555 cat >expect <<-\EOF &&
1556 <BOLD>diff --git a/old.txt b/new.txt<RESET>
1557 <BOLD>--- a/old.txt<RESET>
1558 <BOLD>+++ b/new.txt<RESET>
1559 <CYAN>@@ -1,13 +1,15 @@<RESET>
1560 <BOLD;MAGENTA>-this line should be marked as moved<RESET>
1561 <GREEN>+<RESET><GREEN>too short<RESET>
1562 unchanged<RESET>
1563 unchanged<RESET>
1564 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as moved<RESET>
1565 <GREEN>+<RESET><GREEN>too short<RESET>
1566 unchanged<RESET>
1567 unchanged<RESET>
1568 <RED>-too short<RESET>
1569 <BOLD;MAGENTA>-this line should be marked as oldMoved newMoved<RESET>
1570 <BOLD;BLUE>-this line should be marked as oldMovedAlternate newMoved<RESET>
1571 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as oldMoved newMoved/newMovedAlternate<RESET>
1572 unchanged 1<RESET>
1573 unchanged 2<RESET>
1574 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as oldMovedAlternate newMoved<RESET>
1575 <BOLD;YELLOW>+<RESET><BOLD;YELLOW>this line should be marked as oldMoved newMoved/newMovedAlternate<RESET>
1576 unchanged 3<RESET>
1577 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as oldMoved newMoved<RESET>
1578 unchanged 4<RESET>
1579 <BOLD;MAGENTA>-this line should be marked as oldMoved newMoved/newMovedAlternate<RESET>
1581 test_cmp expect actual
1584 test_expect_success 'cmd option assumes configured colored-moved' '
1585 test_config color.diff.oldMoved "magenta" &&
1586 test_config color.diff.newMoved "cyan" &&
1587 test_config color.diff.oldMovedAlternative "blue" &&
1588 test_config color.diff.newMovedAlternative "yellow" &&
1589 test_config color.diff.oldMovedDimmed "normal magenta" &&
1590 test_config color.diff.newMovedDimmed "normal cyan" &&
1591 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1592 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1593 test_config diff.colorMoved zebra &&
1594 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1595 grep -v "index" actual.raw | test_decode_color >actual &&
1596 cat <<-\EOF >expected &&
1597 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1598 <BOLD>--- a/lines.txt<RESET>
1599 <BOLD>+++ b/lines.txt<RESET>
1600 <CYAN>@@ -1,16 +1,16 @@<RESET>
1601 <MAGENTA>-long line 1<RESET>
1602 <MAGENTA>-long line 2<RESET>
1603 <MAGENTA>-long line 3<RESET>
1604 line 4<RESET>
1605 line 5<RESET>
1606 line 6<RESET>
1607 line 7<RESET>
1608 line 8<RESET>
1609 line 9<RESET>
1610 <CYAN>+<RESET><CYAN>long line 1<RESET>
1611 <CYAN>+<RESET><CYAN>long line 2<RESET>
1612 <CYAN>+<RESET><CYAN>long line 3<RESET>
1613 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1614 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1615 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1616 line 10<RESET>
1617 line 11<RESET>
1618 line 12<RESET>
1619 line 13<RESET>
1620 <MAGENTA>-long line 14<RESET>
1621 <MAGENTA>-long line 15<RESET>
1622 <MAGENTA>-long line 16<RESET>
1624 test_cmp expected actual
1627 test_expect_success 'no effect on diff from --color-moved with --word-diff' '
1628 cat <<-\EOF >text.txt &&
1629 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1631 git add text.txt &&
1632 git commit -a -m "clean state" &&
1633 cat <<-\EOF >text.txt &&
1634 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1636 git diff --color-moved --word-diff >actual &&
1637 git diff --word-diff >expect &&
1638 test_cmp expect actual
1641 test_expect_success 'no effect on show from --color-moved with --word-diff' '
1642 git show --color-moved --word-diff >actual &&
1643 git show --word-diff >expect &&
1644 test_cmp expect actual
1647 test_expect_success 'set up whitespace tests' '
1648 git reset --hard &&
1649 # Note that these lines have no leading or trailing whitespace.
1650 cat <<-\EOF >lines.txt &&
1651 line 1
1652 line 2
1653 line 3
1654 line 4
1655 line 5
1656 long line 6
1657 long line 7
1658 long line 8
1659 long line 9
1661 git add lines.txt &&
1662 git commit -m "add poetry" &&
1663 git config color.diff.oldMoved "magenta" &&
1664 git config color.diff.newMoved "cyan"
1667 test_expect_success 'move detection ignoring whitespace ' '
1668 q_to_tab <<-\EOF >lines.txt &&
1669 Qlong line 6
1670 Qlong line 7
1671 Qlong line 8
1672 Qchanged long line 9
1673 line 1
1674 line 2
1675 line 3
1676 line 4
1677 line 5
1679 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1680 grep -v "index" actual.raw | test_decode_color >actual &&
1681 cat <<-\EOF >expected &&
1682 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1683 <BOLD>--- a/lines.txt<RESET>
1684 <BOLD>+++ b/lines.txt<RESET>
1685 <CYAN>@@ -1,9 +1,9 @@<RESET>
1686 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1687 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1688 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1689 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1690 line 1<RESET>
1691 line 2<RESET>
1692 line 3<RESET>
1693 line 4<RESET>
1694 line 5<RESET>
1695 <RED>-long line 6<RESET>
1696 <RED>-long line 7<RESET>
1697 <RED>-long line 8<RESET>
1698 <RED>-long line 9<RESET>
1700 test_cmp expected actual &&
1702 git diff HEAD --no-renames --color-moved --color \
1703 --color-moved-ws=ignore-all-space >actual.raw &&
1704 grep -v "index" actual.raw | test_decode_color >actual &&
1705 cat <<-\EOF >expected &&
1706 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1707 <BOLD>--- a/lines.txt<RESET>
1708 <BOLD>+++ b/lines.txt<RESET>
1709 <CYAN>@@ -1,9 +1,9 @@<RESET>
1710 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1711 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1712 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1713 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1714 line 1<RESET>
1715 line 2<RESET>
1716 line 3<RESET>
1717 line 4<RESET>
1718 line 5<RESET>
1719 <MAGENTA>-long line 6<RESET>
1720 <MAGENTA>-long line 7<RESET>
1721 <MAGENTA>-long line 8<RESET>
1722 <RED>-long line 9<RESET>
1724 test_cmp expected actual
1727 test_expect_success 'move detection ignoring whitespace changes' '
1728 git reset --hard &&
1729 # Lines 6-8 have a space change, but 9 is new whitespace
1730 q_to_tab <<-\EOF >lines.txt &&
1731 longQline 6
1732 longQline 7
1733 longQline 8
1734 long liQne 9
1735 line 1
1736 line 2
1737 line 3
1738 line 4
1739 line 5
1742 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1743 grep -v "index" actual.raw | test_decode_color >actual &&
1744 cat <<-\EOF >expected &&
1745 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1746 <BOLD>--- a/lines.txt<RESET>
1747 <BOLD>+++ b/lines.txt<RESET>
1748 <CYAN>@@ -1,9 +1,9 @@<RESET>
1749 <GREEN>+<RESET><GREEN>long line 6<RESET>
1750 <GREEN>+<RESET><GREEN>long line 7<RESET>
1751 <GREEN>+<RESET><GREEN>long line 8<RESET>
1752 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1753 line 1<RESET>
1754 line 2<RESET>
1755 line 3<RESET>
1756 line 4<RESET>
1757 line 5<RESET>
1758 <RED>-long line 6<RESET>
1759 <RED>-long line 7<RESET>
1760 <RED>-long line 8<RESET>
1761 <RED>-long line 9<RESET>
1763 test_cmp expected actual &&
1765 git diff HEAD --no-renames --color-moved --color \
1766 --color-moved-ws=ignore-space-change >actual.raw &&
1767 grep -v "index" actual.raw | test_decode_color >actual &&
1768 cat <<-\EOF >expected &&
1769 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1770 <BOLD>--- a/lines.txt<RESET>
1771 <BOLD>+++ b/lines.txt<RESET>
1772 <CYAN>@@ -1,9 +1,9 @@<RESET>
1773 <CYAN>+<RESET><CYAN>long line 6<RESET>
1774 <CYAN>+<RESET><CYAN>long line 7<RESET>
1775 <CYAN>+<RESET><CYAN>long line 8<RESET>
1776 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1777 line 1<RESET>
1778 line 2<RESET>
1779 line 3<RESET>
1780 line 4<RESET>
1781 line 5<RESET>
1782 <MAGENTA>-long line 6<RESET>
1783 <MAGENTA>-long line 7<RESET>
1784 <MAGENTA>-long line 8<RESET>
1785 <RED>-long line 9<RESET>
1787 test_cmp expected actual
1790 test_expect_success 'move detection ignoring whitespace at eol' '
1791 git reset --hard &&
1792 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1793 q_to_tab <<-\EOF >lines.txt &&
1794 long line 6Q
1795 long line 7Q
1796 long line 8Q
1797 longQline 9Q
1798 line 1
1799 line 2
1800 line 3
1801 line 4
1802 line 5
1805 # avoid cluttering the output with complaints about our eol whitespace
1806 test_config core.whitespace -blank-at-eol &&
1808 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1809 grep -v "index" actual.raw | test_decode_color >actual &&
1810 cat <<-\EOF >expected &&
1811 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1812 <BOLD>--- a/lines.txt<RESET>
1813 <BOLD>+++ b/lines.txt<RESET>
1814 <CYAN>@@ -1,9 +1,9 @@<RESET>
1815 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1816 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1817 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1818 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1819 line 1<RESET>
1820 line 2<RESET>
1821 line 3<RESET>
1822 line 4<RESET>
1823 line 5<RESET>
1824 <RED>-long line 6<RESET>
1825 <RED>-long line 7<RESET>
1826 <RED>-long line 8<RESET>
1827 <RED>-long line 9<RESET>
1829 test_cmp expected actual &&
1831 git diff HEAD --no-renames --color-moved --color \
1832 --color-moved-ws=ignore-space-at-eol >actual.raw &&
1833 grep -v "index" actual.raw | test_decode_color >actual &&
1834 cat <<-\EOF >expected &&
1835 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1836 <BOLD>--- a/lines.txt<RESET>
1837 <BOLD>+++ b/lines.txt<RESET>
1838 <CYAN>@@ -1,9 +1,9 @@<RESET>
1839 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1840 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1841 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1842 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1843 line 1<RESET>
1844 line 2<RESET>
1845 line 3<RESET>
1846 line 4<RESET>
1847 line 5<RESET>
1848 <MAGENTA>-long line 6<RESET>
1849 <MAGENTA>-long line 7<RESET>
1850 <MAGENTA>-long line 8<RESET>
1851 <RED>-long line 9<RESET>
1853 test_cmp expected actual
1856 test_expect_success 'clean up whitespace-test colors' '
1857 git config --unset color.diff.oldMoved &&
1858 git config --unset color.diff.newMoved
1861 test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1862 git reset --hard &&
1863 >bar &&
1864 cat <<-\EOF >foo &&
1865 irrelevant_line
1866 line1
1868 git add foo bar &&
1869 git commit -m x &&
1871 cat <<-\EOF >bar &&
1872 line1
1874 cat <<-\EOF >foo &&
1875 irrelevant_line
1878 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1879 grep -v "index" actual.raw | test_decode_color >actual &&
1880 cat >expected <<-\EOF &&
1881 <BOLD>diff --git a/bar b/bar<RESET>
1882 <BOLD>--- a/bar<RESET>
1883 <BOLD>+++ b/bar<RESET>
1884 <CYAN>@@ -0,0 +1 @@<RESET>
1885 <GREEN>+<RESET><GREEN>line1<RESET>
1886 <BOLD>diff --git a/foo b/foo<RESET>
1887 <BOLD>--- a/foo<RESET>
1888 <BOLD>+++ b/foo<RESET>
1889 <CYAN>@@ -1,2 +1 @@<RESET>
1890 irrelevant_line<RESET>
1891 <RED>-line1<RESET>
1894 test_cmp expected actual
1897 test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
1898 git reset --hard &&
1899 cat <<-\EOF >foo &&
1900 nineteen chars 456789
1901 irrelevant_line
1902 twenty chars 234567890
1904 >bar &&
1905 git add foo bar &&
1906 git commit -m x &&
1908 cat <<-\EOF >foo &&
1909 irrelevant_line
1911 cat <<-\EOF >bar &&
1912 twenty chars 234567890
1913 nineteen chars 456789
1916 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1917 grep -v "index" actual.raw | test_decode_color >actual &&
1918 cat >expected <<-\EOF &&
1919 <BOLD>diff --git a/bar b/bar<RESET>
1920 <BOLD>--- a/bar<RESET>
1921 <BOLD>+++ b/bar<RESET>
1922 <CYAN>@@ -0,0 +1,2 @@<RESET>
1923 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1924 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1925 <BOLD>diff --git a/foo b/foo<RESET>
1926 <BOLD>--- a/foo<RESET>
1927 <BOLD>+++ b/foo<RESET>
1928 <CYAN>@@ -1,3 +1 @@<RESET>
1929 <RED>-nineteen chars 456789<RESET>
1930 irrelevant_line<RESET>
1931 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1934 test_cmp expected actual
1937 test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1938 git reset --hard &&
1939 cat <<-\EOF >foo &&
1940 7charsA
1941 irrelevant_line
1942 7charsB
1943 7charsC
1945 >bar &&
1946 git add foo bar &&
1947 git commit -m x &&
1949 cat <<-\EOF >foo &&
1950 irrelevant_line
1952 cat <<-\EOF >bar &&
1953 7charsB
1954 7charsC
1955 7charsA
1958 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1959 grep -v "index" actual.raw | test_decode_color >actual &&
1960 cat >expected <<-\EOF &&
1961 <BOLD>diff --git a/bar b/bar<RESET>
1962 <BOLD>--- a/bar<RESET>
1963 <BOLD>+++ b/bar<RESET>
1964 <CYAN>@@ -0,0 +1,3 @@<RESET>
1965 <GREEN>+<RESET><GREEN>7charsB<RESET>
1966 <GREEN>+<RESET><GREEN>7charsC<RESET>
1967 <GREEN>+<RESET><GREEN>7charsA<RESET>
1968 <BOLD>diff --git a/foo b/foo<RESET>
1969 <BOLD>--- a/foo<RESET>
1970 <BOLD>+++ b/foo<RESET>
1971 <CYAN>@@ -1,4 +1 @@<RESET>
1972 <RED>-7charsA<RESET>
1973 irrelevant_line<RESET>
1974 <RED>-7charsB<RESET>
1975 <RED>-7charsC<RESET>
1978 test_cmp expected actual
1981 test_expect_success '--color-moved rewinds for MIN_ALNUM_COUNT' '
1982 git reset --hard &&
1983 test_write_lines >file \
1984 A B C one two three four five six seven D E F G H I J &&
1985 git add file &&
1986 test_write_lines >file \
1987 one two A B C D E F G H I J two three four five six seven &&
1988 git diff --color-moved=zebra -- file &&
1990 git diff --color-moved=zebra --color -- file >actual.raw &&
1991 grep -v "index" actual.raw | test_decode_color >actual &&
1992 cat >expected <<-\EOF &&
1993 <BOLD>diff --git a/file b/file<RESET>
1994 <BOLD>--- a/file<RESET>
1995 <BOLD>+++ b/file<RESET>
1996 <CYAN>@@ -1,13 +1,8 @@<RESET>
1997 <GREEN>+<RESET><GREEN>one<RESET>
1998 <GREEN>+<RESET><GREEN>two<RESET>
1999 A<RESET>
2000 B<RESET>
2001 C<RESET>
2002 <RED>-one<RESET>
2003 <BOLD;MAGENTA>-two<RESET>
2004 <BOLD;MAGENTA>-three<RESET>
2005 <BOLD;MAGENTA>-four<RESET>
2006 <BOLD;MAGENTA>-five<RESET>
2007 <BOLD;MAGENTA>-six<RESET>
2008 <BOLD;MAGENTA>-seven<RESET>
2009 D<RESET>
2010 E<RESET>
2011 F<RESET>
2012 <CYAN>@@ -15,3 +10,9 @@<RESET> <RESET>G<RESET>
2013 H<RESET>
2014 I<RESET>
2015 J<RESET>
2016 <BOLD;CYAN>+<RESET><BOLD;CYAN>two<RESET>
2017 <BOLD;CYAN>+<RESET><BOLD;CYAN>three<RESET>
2018 <BOLD;CYAN>+<RESET><BOLD;CYAN>four<RESET>
2019 <BOLD;CYAN>+<RESET><BOLD;CYAN>five<RESET>
2020 <BOLD;CYAN>+<RESET><BOLD;CYAN>six<RESET>
2021 <BOLD;CYAN>+<RESET><BOLD;CYAN>seven<RESET>
2024 test_cmp expected actual
2027 test_expect_success 'move detection with submodules' '
2028 test_create_repo bananas &&
2029 echo ripe >bananas/recipe &&
2030 git -C bananas add recipe &&
2031 test_commit fruit &&
2032 test_commit -C bananas recipe &&
2033 git submodule add ./bananas &&
2034 git add bananas &&
2035 git commit -a -m "bananas are like a heavy library?" &&
2036 echo foul >bananas/recipe &&
2037 echo ripe >fruit.t &&
2039 git diff --submodule=diff --color-moved --color >actual &&
2041 # no move detection as the moved line is across repository boundaries.
2042 test_decode_color <actual >decoded_actual &&
2043 ! grep BGREEN decoded_actual &&
2044 ! grep BRED decoded_actual &&
2046 # nor did we mess with it another way
2047 git diff --submodule=diff --color >expect.raw &&
2048 test_decode_color <expect.raw >expect &&
2049 test_cmp expect decoded_actual &&
2050 rm -rf bananas &&
2051 git submodule deinit bananas
2054 test_expect_success 'only move detection ignores white spaces' '
2055 git reset --hard &&
2056 q_to_tab <<-\EOF >text.txt &&
2057 a long line to exceed per-line minimum
2058 another long line to exceed per-line minimum
2059 original file
2061 git add text.txt &&
2062 git commit -m "add text" &&
2063 q_to_tab <<-\EOF >text.txt &&
2064 Qa long line to exceed per-line minimum
2065 Qanother long line to exceed per-line minimum
2066 new file
2069 # Make sure we get a different diff using -w
2070 git diff --color --color-moved -w >actual.raw &&
2071 grep -v "index" actual.raw | test_decode_color >actual &&
2072 q_to_tab <<-\EOF >expected &&
2073 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2074 <BOLD>--- a/text.txt<RESET>
2075 <BOLD>+++ b/text.txt<RESET>
2076 <CYAN>@@ -1,3 +1,3 @@<RESET>
2077 Qa long line to exceed per-line minimum<RESET>
2078 Qanother long line to exceed per-line minimum<RESET>
2079 <RED>-original file<RESET>
2080 <GREEN>+<RESET><GREEN>new file<RESET>
2082 test_cmp expected actual &&
2084 # And now ignoring white space only in the move detection
2085 git diff --color --color-moved \
2086 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
2087 grep -v "index" actual.raw | test_decode_color >actual &&
2088 q_to_tab <<-\EOF >expected &&
2089 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2090 <BOLD>--- a/text.txt<RESET>
2091 <BOLD>+++ b/text.txt<RESET>
2092 <CYAN>@@ -1,3 +1,3 @@<RESET>
2093 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
2094 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
2095 <RED>-original file<RESET>
2096 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>a long line to exceed per-line minimum<RESET>
2097 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>another long line to exceed per-line minimum<RESET>
2098 <GREEN>+<RESET><GREEN>new file<RESET>
2100 test_cmp expected actual
2103 test_expect_success 'compare whitespace delta across moved blocks' '
2105 git reset --hard &&
2106 q_to_tab <<-\EOF >text.txt &&
2107 QIndented
2108 QText across
2109 Qsome lines
2110 QBut! <- this stands out
2111 QAdjusting with
2112 QQdifferent starting
2113 Qwhite spaces
2114 QAnother outlier
2115 QQQIndented
2116 QQQText across
2117 QQQfive lines
2118 QQQthat has similar lines
2119 QQQto previous blocks, but with different indent
2120 QQQYetQAnotherQoutlierQ
2121 QLine with internal w h i t e s p a c e change
2124 git add text.txt &&
2125 git commit -m "add text.txt" &&
2127 q_to_tab <<-\EOF >text.txt &&
2128 QQIndented
2129 QQText across
2130 QQsome lines
2131 QQQBut! <- this stands out
2132 Adjusting with
2133 Qdifferent starting
2134 white spaces
2135 AnotherQoutlier
2136 QQIndented
2137 QQText across
2138 QQfive lines
2139 QQthat has similar lines
2140 QQto previous blocks, but with different indent
2141 QQYetQAnotherQoutlier
2142 QLine with internal whitespace change
2145 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
2146 grep -v "index" actual.raw | test_decode_color >actual &&
2148 q_to_tab <<-\EOF >expected &&
2149 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2150 <BOLD>--- a/text.txt<RESET>
2151 <BOLD>+++ b/text.txt<RESET>
2152 <CYAN>@@ -1,15 +1,15 @@<RESET>
2153 <BOLD;MAGENTA>-QIndented<RESET>
2154 <BOLD;MAGENTA>-QText across<RESET>
2155 <BOLD;MAGENTA>-Qsome lines<RESET>
2156 <RED>-QBut! <- this stands out<RESET>
2157 <BOLD;MAGENTA>-QAdjusting with<RESET>
2158 <BOLD;MAGENTA>-QQdifferent starting<RESET>
2159 <BOLD;MAGENTA>-Qwhite spaces<RESET>
2160 <RED>-QAnother outlier<RESET>
2161 <BOLD;MAGENTA>-QQQIndented<RESET>
2162 <BOLD;MAGENTA>-QQQText across<RESET>
2163 <BOLD;MAGENTA>-QQQfive lines<RESET>
2164 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
2165 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
2166 <RED>-QQQYetQAnotherQoutlierQ<RESET>
2167 <RED>-QLine with internal w h i t e s p a c e change<RESET>
2168 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
2169 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
2170 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
2171 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
2172 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
2173 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
2174 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
2175 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
2176 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
2177 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
2178 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
2179 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
2180 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
2181 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
2182 <GREEN>+<RESET>Q<GREEN>Line with internal whitespace change<RESET>
2185 test_cmp expected actual
2188 test_expect_success 'bogus settings in move detection erroring out' '
2189 test_must_fail git diff --color-moved=bogus 2>err &&
2190 test_i18ngrep "must be one of" err &&
2191 test_i18ngrep bogus err &&
2193 test_must_fail git -c diff.colormoved=bogus diff 2>err &&
2194 test_i18ngrep "must be one of" err &&
2195 test_i18ngrep "from command-line config" err &&
2197 test_must_fail git diff --color-moved-ws=bogus 2>err &&
2198 test_i18ngrep "possible values" err &&
2199 test_i18ngrep bogus err &&
2201 test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
2202 test_i18ngrep "possible values" err &&
2203 test_i18ngrep "from command-line config" err
2206 test_expect_success 'compare whitespace delta incompatible with other space options' '
2207 test_must_fail git diff \
2208 --color-moved-ws=allow-indentation-change,ignore-all-space \
2209 2>err &&
2210 test_i18ngrep allow-indentation-change err
2213 EMPTY=''
2214 test_expect_success 'compare mixed whitespace delta across moved blocks' '
2216 git reset --hard &&
2217 tr "^|Q_" "\f\v\t " <<-EOF >text.txt &&
2219 |____too short without
2221 ___being grouped across blank line
2222 ${EMPTY}
2223 context
2224 lines
2226 anchor
2227 ____Indented text to
2228 _Q____be further indented by four spaces across
2229 ____Qseveral lines
2230 QQ____These two lines have had their
2231 ____indentation reduced by four spaces
2232 Qdifferent indentation change
2233 ____too short
2236 git add text.txt &&
2237 git commit -m "add text.txt" &&
2239 tr "^|Q_" "\f\v\t " <<-EOF >text.txt &&
2240 context
2241 lines
2243 anchor
2244 QIndented text to
2245 QQbe further indented by four spaces across
2246 Q____several lines
2247 ${EMPTY}
2248 QQtoo short without
2249 ${EMPTY}
2250 ^Q_______being grouped across blank line
2251 ${EMPTY}
2252 Q_QThese two lines have had their
2253 indentation reduced by four spaces
2254 QQdifferent indentation change
2255 __Qtoo short
2258 git -c color.diff.whitespace="normal red" \
2259 -c core.whitespace=space-before-tab \
2260 diff --color --color-moved --ws-error-highlight=all \
2261 --color-moved-ws=allow-indentation-change >actual.raw &&
2262 grep -v "index" actual.raw | tr "\f\v" "^|" | test_decode_color >actual &&
2264 cat <<-\EOF >expected &&
2265 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2266 <BOLD>--- a/text.txt<RESET>
2267 <BOLD>+++ b/text.txt<RESET>
2268 <CYAN>@@ -1,16 +1,16 @@<RESET>
2269 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA>^<RESET><BRED> <RESET>
2270 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA>| too short without<RESET>
2271 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA>^<RESET>
2272 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
2273 <BOLD;MAGENTA>-<RESET>
2274 <RESET>context<RESET>
2275 <RESET>lines<RESET>
2276 <RESET>to<RESET>
2277 <RESET>anchor<RESET>
2278 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
2279 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
2280 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
2281 <BOLD;BLUE>-<RESET> <BOLD;BLUE> These two lines have had their<RESET>
2282 <BOLD;BLUE>-<RESET><BOLD;BLUE> indentation reduced by four spaces<RESET>
2283 <BOLD;MAGENTA>-<RESET> <BOLD;MAGENTA>different indentation change<RESET>
2284 <RED>-<RESET><RED> too short<RESET>
2285 <BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
2286 <BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
2287 <BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
2288 <BOLD;YELLOW>+<RESET>
2289 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
2290 <BOLD;YELLOW>+<RESET>
2291 <BOLD;YELLOW>+<RESET><BOLD;YELLOW>^ being grouped across blank line<RESET>
2292 <BOLD;YELLOW>+<RESET>
2293 <BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
2294 <BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
2295 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
2296 <GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
2299 test_cmp expected actual
2302 test_expect_success 'combine --ignore-blank-lines with --function-context' '
2303 test_write_lines 1 "" 2 3 4 5 >a &&
2304 test_write_lines 1 2 3 4 >b &&
2305 test_must_fail git diff --no-index \
2306 --ignore-blank-lines --function-context a b >actual.raw &&
2307 sed -n "/@@/,\$p" <actual.raw >actual &&
2308 cat <<-\EOF >expect &&
2309 @@ -1,6 +1,4 @@
2317 test_cmp expect actual
2320 test_expect_success 'combine --ignore-blank-lines with --function-context 2' '
2321 test_write_lines a b c "" function 1 2 3 4 5 "" 6 7 8 9 >a &&
2322 test_write_lines "" a b c "" function 1 2 3 4 5 6 7 8 >b &&
2323 test_must_fail git diff --no-index \
2324 --ignore-blank-lines --function-context a b >actual.raw &&
2325 sed -n "/@@/,\$p" <actual.raw >actual &&
2326 cat <<-\EOF >expect &&
2327 @@ -5,11 +6,9 @@ c
2328 function
2340 test_cmp expect actual
2343 test_done