hex: drop sha1_to_hex_r()
[git/raj.git] / t / t4015-diff-whitespace.sh
blobeadaf57262637297029040bea4370cc0c407514d
1 #!/bin/sh
3 # Copyright (c) 2006 Johannes E. Schindelin
6 test_description='Test special whitespace in diff engine.
9 . ./test-lib.sh
10 . "$TEST_DIRECTORY"/diff-lib.sh
12 test_expect_success "Ray Lehtiniemi's example" '
13 cat <<-\EOF >x &&
14 do {
15 nothing;
16 } while (0);
17 EOF
18 git update-index --add x &&
19 before=$(git rev-parse --short $(git hash-object x)) &&
21 cat <<-\EOF >x &&
24 nothing;
26 while (0);
27 EOF
28 after=$(git rev-parse --short $(git hash-object x)) &&
30 cat <<-EOF >expect &&
31 diff --git a/x b/x
32 index $before..$after 100644
33 --- a/x
34 +++ b/x
35 @@ -1,3 +1,5 @@
36 -do {
37 +do
39 nothing;
40 -} while (0);
42 +while (0);
43 EOF
45 git diff >out &&
46 test_cmp expect out &&
48 git diff -w >out &&
49 test_cmp expect out &&
51 git diff -b >out &&
52 test_cmp expect out
55 test_expect_success 'another test, without options' '
56 tr Q "\015" <<-\EOF >x &&
57 whitespace at beginning
58 whitespace change
59 whitespace in the middle
60 whitespace at end
61 unchanged line
62 CR at endQ
63 EOF
65 git update-index x &&
66 before=$(git rev-parse --short $(git hash-object x)) &&
68 tr "_" " " <<-\EOF >x &&
69 _ whitespace at beginning
70 whitespace change
71 white space in the middle
72 whitespace at end__
73 unchanged line
74 CR at end
75 EOF
76 after=$(git rev-parse --short $(git hash-object x)) &&
78 tr "Q_" "\015 " <<-EOF >expect &&
79 diff --git a/x b/x
80 index $before..$after 100644
81 --- a/x
82 +++ b/x
83 @@ -1,6 +1,6 @@
84 -whitespace at beginning
85 -whitespace change
86 -whitespace in the middle
87 -whitespace at end
88 + whitespace at beginning
89 +whitespace change
90 +white space in the middle
91 +whitespace at end__
92 unchanged line
93 -CR at endQ
94 +CR at end
95 EOF
97 git diff >out &&
98 test_cmp expect out &&
100 git diff -w >out &&
101 test_must_be_empty out &&
103 git diff -w -b >out &&
104 test_must_be_empty out &&
106 git diff -w --ignore-space-at-eol >out &&
107 test_must_be_empty out &&
109 git diff -w -b --ignore-space-at-eol >out &&
110 test_must_be_empty out &&
112 git diff -w --ignore-cr-at-eol >out &&
113 test_must_be_empty out &&
115 tr "Q_" "\015 " <<-EOF >expect &&
116 diff --git a/x b/x
117 index $before..$after 100644
118 --- a/x
119 +++ b/x
120 @@ -1,6 +1,6 @@
121 -whitespace at beginning
122 +_ whitespace at beginning
123 whitespace change
124 -whitespace in the middle
125 +white space in the middle
126 whitespace at end__
127 unchanged line
128 CR at end
130 git diff -b >out &&
131 test_cmp expect out &&
133 git diff -b --ignore-space-at-eol >out &&
134 test_cmp expect out &&
136 git diff -b --ignore-cr-at-eol >out &&
137 test_cmp expect out &&
139 tr "Q_" "\015 " <<-EOF >expect &&
140 diff --git a/x b/x
141 index $before..$after 100644
142 --- a/x
143 +++ b/x
144 @@ -1,6 +1,6 @@
145 -whitespace at beginning
146 -whitespace change
147 -whitespace in the middle
148 +_ whitespace at beginning
149 +whitespace change
150 +white space in the middle
151 whitespace at end__
152 unchanged line
153 CR at end
155 git diff --ignore-space-at-eol >out &&
156 test_cmp expect out &&
158 git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
159 test_cmp expect out &&
161 tr "Q_" "\015 " <<-EOF >expect &&
162 diff --git a/x b/x
163 index_$before..$after 100644
164 --- a/x
165 +++ b/x
166 @@ -1,6 +1,6 @@
167 -whitespace at beginning
168 -whitespace change
169 -whitespace in the middle
170 -whitespace at end
171 +_ whitespace at beginning
172 +whitespace_ _change
173 +white space in the middle
174 +whitespace at end__
175 unchanged line
176 CR at end
178 git diff --ignore-cr-at-eol >out &&
179 test_cmp expect out
182 test_expect_success 'ignore-blank-lines: only new lines' '
183 test_seq 5 >x &&
184 git update-index x &&
185 test_seq 5 | sed "/3/i\\
186 " >x &&
187 git diff --ignore-blank-lines >out &&
188 test_must_be_empty out
191 test_expect_success 'ignore-blank-lines: only new lines with space' '
192 test_seq 5 >x &&
193 git update-index x &&
194 test_seq 5 | sed "/3/i\\
195 " >x &&
196 git diff -w --ignore-blank-lines >out &&
197 test_must_be_empty out
200 test_expect_success 'ignore-blank-lines: after change' '
201 cat <<-\EOF >x &&
212 git update-index x &&
213 cat <<-\EOF >x &&
214 change
225 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
226 cat <<-\EOF >expected &&
227 diff --git a/x b/x
228 --- a/x
229 +++ b/x
230 @@ -1,6 +1,7 @@
231 +change
240 compare_diff_patch expected out.tmp
243 test_expect_success 'ignore-blank-lines: before change' '
244 cat <<-\EOF >x &&
254 git update-index x &&
255 cat <<-\EOF >x &&
265 change
267 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
268 cat <<-\EOF >expected &&
269 diff --git a/x b/x
270 --- a/x
271 +++ b/x
272 @@ -4,5 +4,7 @@
279 +change
281 compare_diff_patch expected out.tmp
284 test_expect_success 'ignore-blank-lines: between changes' '
285 cat <<-\EOF >x &&
299 git update-index x &&
300 cat <<-\EOF >x &&
301 change
314 change
316 git diff --ignore-blank-lines >out.tmp &&
317 cat <<-\EOF >expected &&
318 diff --git a/x b/x
319 --- a/x
320 +++ b/x
321 @@ -1,5 +1,7 @@
322 +change
329 @@ -8,5 +8,7 @@
336 +change
338 compare_diff_patch expected out.tmp
341 test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
342 test_seq 10 >x &&
343 git update-index x &&
344 cat <<-\EOF >x &&
345 change
359 change
361 git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
362 cat <<-\EOF >expected &&
363 diff --git a/x b/x
364 --- a/x
365 +++ b/x
366 @@ -1,10 +1,15 @@
367 +change
381 +change
383 compare_diff_patch expected out.tmp
386 test_expect_success 'ignore-blank-lines: scattered spaces' '
387 test_seq 10 >x &&
388 git update-index x &&
389 cat <<-\EOF >x &&
390 change
407 change
409 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
410 cat <<-\EOF >expected &&
411 diff --git a/x b/x
412 --- a/x
413 +++ b/x
414 @@ -1,3 +1,4 @@
415 +change
419 @@ -8,3 +15,4 @@
423 +change
425 compare_diff_patch expected out.tmp
428 test_expect_success 'ignore-blank-lines: spaces coalesce' '
429 test_seq 6 >x &&
430 git update-index x &&
431 cat <<-\EOF >x &&
432 change
442 change
444 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
445 cat <<-\EOF >expected &&
446 diff --git a/x b/x
447 --- a/x
448 +++ b/x
449 @@ -1,6 +1,11 @@
450 +change
460 +change
462 compare_diff_patch expected out.tmp
465 test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
466 test_seq 16 >x &&
467 git update-index x &&
468 cat <<-\EOF >x &&
469 change
476 change
484 change
491 change
493 git diff --ignore-blank-lines >out.tmp &&
494 cat <<-\EOF >expected &&
495 diff --git a/x b/x
496 --- a/x
497 +++ b/x
498 @@ -1,8 +1,11 @@
499 +change
506 +change
510 @@ -9,8 +13,11 @@
514 +change
521 +change
523 compare_diff_patch expected out.tmp
526 test_expect_success 'check mixed spaces and tabs in indent' '
527 # This is indented with SP HT SP.
528 echo " foo();" >x &&
529 git diff --check | grep "space before tab in indent"
532 test_expect_success 'check mixed tabs and spaces in indent' '
533 # This is indented with HT SP HT.
534 echo " foo();" >x &&
535 git diff --check | grep "space before tab in indent"
538 test_expect_success 'check with no whitespace errors' '
539 git commit -m "snapshot" &&
540 echo "foo();" >x &&
541 git diff --check
544 test_expect_success 'check with trailing whitespace' '
545 echo "foo(); " >x &&
546 test_must_fail git diff --check
549 test_expect_success 'check with space before tab in indent' '
550 # indent has space followed by hard tab
551 echo " foo();" >x &&
552 test_must_fail git diff --check
555 test_expect_success '--check and --exit-code are not exclusive' '
556 git checkout x &&
557 git diff --check --exit-code
560 test_expect_success '--check and --quiet are not exclusive' '
561 git diff --check --quiet
564 test_expect_success 'check staged with no whitespace errors' '
565 echo "foo();" >x &&
566 git add x &&
567 git diff --cached --check
570 test_expect_success 'check staged with trailing whitespace' '
571 echo "foo(); " >x &&
572 git add x &&
573 test_must_fail git diff --cached --check
576 test_expect_success 'check staged with space before tab in indent' '
577 # indent has space followed by hard tab
578 echo " foo();" >x &&
579 git add x &&
580 test_must_fail git diff --cached --check
583 test_expect_success 'check with no whitespace errors (diff-index)' '
584 echo "foo();" >x &&
585 git add x &&
586 git diff-index --check HEAD
589 test_expect_success 'check with trailing whitespace (diff-index)' '
590 echo "foo(); " >x &&
591 git add x &&
592 test_must_fail git diff-index --check HEAD
595 test_expect_success 'check with space before tab in indent (diff-index)' '
596 # indent has space followed by hard tab
597 echo " foo();" >x &&
598 git add x &&
599 test_must_fail git diff-index --check HEAD
602 test_expect_success 'check staged with no whitespace errors (diff-index)' '
603 echo "foo();" >x &&
604 git add x &&
605 git diff-index --cached --check HEAD
608 test_expect_success 'check staged with trailing whitespace (diff-index)' '
609 echo "foo(); " >x &&
610 git add x &&
611 test_must_fail git diff-index --cached --check HEAD
614 test_expect_success 'check staged with space before tab in indent (diff-index)' '
615 # indent has space followed by hard tab
616 echo " foo();" >x &&
617 git add x &&
618 test_must_fail git diff-index --cached --check HEAD
621 test_expect_success 'check with no whitespace errors (diff-tree)' '
622 echo "foo();" >x &&
623 git commit -m "new commit" x &&
624 git diff-tree --check HEAD^ HEAD
627 test_expect_success 'check with trailing whitespace (diff-tree)' '
628 echo "foo(); " >x &&
629 git commit -m "another commit" x &&
630 test_must_fail git diff-tree --check HEAD^ HEAD
633 test_expect_success 'check with space before tab in indent (diff-tree)' '
634 # indent has space followed by hard tab
635 echo " foo();" >x &&
636 git commit -m "yet another" x &&
637 test_must_fail git diff-tree --check HEAD^ HEAD
640 test_expect_success 'check with ignored trailing whitespace attr (diff-tree)' '
641 test_when_finished "git reset --hard HEAD^" &&
643 # create a whitespace error that should be ignored
644 echo "* -whitespace" >.gitattributes &&
645 git add .gitattributes &&
646 echo "foo(); " >x &&
647 git add x &&
648 git commit -m "add trailing space" &&
650 # with a worktree diff-tree ignores the whitespace error
651 git diff-tree --root --check HEAD &&
653 # without a worktree diff-tree still ignores the whitespace error
654 git -C .git diff-tree --root --check HEAD
657 test_expect_success 'check trailing whitespace (trailing-space: off)' '
658 git config core.whitespace "-trailing-space" &&
659 echo "foo (); " >x &&
660 git diff --check
663 test_expect_success 'check trailing whitespace (trailing-space: on)' '
664 git config core.whitespace "trailing-space" &&
665 echo "foo (); " >x &&
666 test_must_fail git diff --check
669 test_expect_success 'check space before tab in indent (space-before-tab: off)' '
670 # indent contains space followed by HT
671 git config core.whitespace "-space-before-tab" &&
672 echo " foo ();" >x &&
673 git diff --check
676 test_expect_success 'check space before tab in indent (space-before-tab: on)' '
677 # indent contains space followed by HT
678 git config core.whitespace "space-before-tab" &&
679 echo " foo (); " >x &&
680 test_must_fail git diff --check
683 test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
684 git config core.whitespace "-indent-with-non-tab" &&
685 echo " foo ();" >x &&
686 git diff --check
689 test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
690 git config core.whitespace "indent-with-non-tab" &&
691 echo " foo ();" >x &&
692 test_must_fail git diff --check
695 test_expect_success 'ditto, but tabwidth=9' '
696 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
697 git diff --check
700 test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
701 git config core.whitespace "indent-with-non-tab" &&
702 echo " foo ();" >x &&
703 test_must_fail git diff --check
706 test_expect_success 'ditto, but tabwidth=10' '
707 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
708 test_must_fail git diff --check
711 test_expect_success 'ditto, but tabwidth=20' '
712 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
713 git diff --check
716 test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
717 git config core.whitespace "-tab-in-indent" &&
718 echo " foo ();" >x &&
719 git diff --check
722 test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
723 git config core.whitespace "tab-in-indent" &&
724 echo " foo ();" >x &&
725 test_must_fail git diff --check
728 test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
729 git config core.whitespace "tab-in-indent" &&
730 echo " foo ();" >x &&
731 test_must_fail git diff --check
734 test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
735 git config core.whitespace "tab-in-indent,tabwidth=1" &&
736 test_must_fail git diff --check
739 test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
740 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
741 echo "foo ();" >x &&
742 test_must_fail git diff --check
745 test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
746 git config --unset core.whitespace &&
747 echo "x whitespace" >.gitattributes &&
748 echo " foo ();" >x &&
749 git diff --check &&
750 rm -f .gitattributes
753 test_expect_success 'line numbers in --check output are correct' '
754 echo "" >x &&
755 echo "foo(); " >>x &&
756 git diff --check | grep "x:2:"
759 test_expect_success 'checkdiff detects new trailing blank lines (1)' '
760 echo "foo();" >x &&
761 echo "" >>x &&
762 git diff --check | grep "new blank line"
765 test_expect_success 'checkdiff detects new trailing blank lines (2)' '
766 { echo a; echo b; echo; echo; } >x &&
767 git add x &&
768 { echo a; echo; echo; echo; echo; } >x &&
769 git diff --check | grep "new blank line"
772 test_expect_success 'checkdiff allows new blank lines' '
773 git checkout x &&
774 mv x y &&
776 echo "/* This is new */" &&
777 echo "" &&
778 cat y
779 ) >x &&
780 git diff --check
783 test_expect_success 'whitespace-only changes not reported' '
784 git reset --hard &&
785 echo >x "hello world" &&
786 git add x &&
787 git commit -m "hello 1" &&
788 echo >x "hello world" &&
789 git diff -b >actual &&
790 test_must_be_empty actual
793 test_expect_success 'whitespace-only changes reported across renames' '
794 git reset --hard &&
795 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
796 git add x &&
797 before=$(git rev-parse --short $(git hash-object x)) &&
798 git commit -m "base" &&
799 sed -e "5s/^/ /" x >z &&
800 git rm x &&
801 git add z &&
802 after=$(git rev-parse --short $(git hash-object z)) &&
803 git diff -w -M --cached |
804 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual &&
805 cat <<-EOF >expect &&
806 diff --git a/x b/z
807 similarity index NUM%
808 rename from x
809 rename to z
810 index $before..$after 100644
812 test_cmp expect actual
815 cat >expected <<\EOF
816 diff --git a/empty b/void
817 similarity index 100%
818 rename from empty
819 rename to void
822 test_expect_success 'rename empty' '
823 git reset --hard &&
824 >empty &&
825 git add empty &&
826 git commit -m empty &&
827 git mv empty void &&
828 git diff -w --cached -M >current &&
829 test_cmp expected current
832 test_expect_success 'combined diff with autocrlf conversion' '
834 git reset --hard &&
835 echo >x hello &&
836 git commit -m "one side" x &&
837 git checkout HEAD^ &&
838 echo >x goodbye &&
839 git commit -m "the other side" x &&
840 git config core.autocrlf true &&
841 test_must_fail git merge master &&
843 git diff | sed -e "1,/^@@@/d" >actual &&
844 ! grep "^-" actual
848 # Start testing the colored format for whitespace checks
850 test_expect_success 'setup diff colors' '
851 git config color.diff.plain normal &&
852 git config color.diff.meta bold &&
853 git config color.diff.frag cyan &&
854 git config color.diff.func normal &&
855 git config color.diff.old red &&
856 git config color.diff.new green &&
857 git config color.diff.commit yellow &&
858 git config color.diff.whitespace blue &&
860 git config core.autocrlf false
863 test_expect_success 'diff that introduces a line with only tabs' '
864 git config core.whitespace blank-at-eol &&
865 git reset --hard &&
866 echo "test" >x &&
867 before=$(git rev-parse --short $(git hash-object x)) &&
868 git commit -m "initial" x &&
869 echo "{NTN}" | tr "NT" "\n\t" >>x &&
870 after=$(git rev-parse --short $(git hash-object x)) &&
871 git diff --color | test_decode_color >current &&
873 cat >expected <<-EOF &&
874 <BOLD>diff --git a/x b/x<RESET>
875 <BOLD>index $before..$after 100644<RESET>
876 <BOLD>--- a/x<RESET>
877 <BOLD>+++ b/x<RESET>
878 <CYAN>@@ -1 +1,4 @@<RESET>
879 test<RESET>
880 <GREEN>+<RESET><GREEN>{<RESET>
881 <GREEN>+<RESET><BLUE> <RESET>
882 <GREEN>+<RESET><GREEN>}<RESET>
885 test_cmp expected current
888 test_expect_success 'diff that introduces and removes ws breakages' '
889 git reset --hard &&
891 echo "0. blank-at-eol " &&
892 echo "1. blank-at-eol "
893 } >x &&
894 before=$(git rev-parse --short $(git hash-object x)) &&
895 git commit -a --allow-empty -m preimage &&
897 echo "0. blank-at-eol " &&
898 echo "1. still-blank-at-eol " &&
899 echo "2. and a new line "
900 } >x &&
901 after=$(git rev-parse --short $(git hash-object x)) &&
903 git diff --color |
904 test_decode_color >current &&
906 cat >expected <<-EOF &&
907 <BOLD>diff --git a/x b/x<RESET>
908 <BOLD>index $before..$after 100644<RESET>
909 <BOLD>--- a/x<RESET>
910 <BOLD>+++ b/x<RESET>
911 <CYAN>@@ -1,2 +1,3 @@<RESET>
912 0. blank-at-eol <RESET>
913 <RED>-1. blank-at-eol <RESET>
914 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
915 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
918 test_cmp expected current
921 test_expect_success 'ws-error-highlight test setup' '
923 git reset --hard &&
925 echo "0. blank-at-eol " &&
926 echo "1. blank-at-eol "
927 } >x &&
928 before=$(git rev-parse --short $(git hash-object x)) &&
929 git commit -a --allow-empty -m preimage &&
931 echo "0. blank-at-eol " &&
932 echo "1. still-blank-at-eol " &&
933 echo "2. and a new line "
934 } >x &&
935 after=$(git rev-parse --short $(git hash-object x)) &&
937 cat >expect.default-old <<-EOF &&
938 <BOLD>diff --git a/x b/x<RESET>
939 <BOLD>index $before..$after 100644<RESET>
940 <BOLD>--- a/x<RESET>
941 <BOLD>+++ b/x<RESET>
942 <CYAN>@@ -1,2 +1,3 @@<RESET>
943 0. blank-at-eol <RESET>
944 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
945 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
946 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
949 cat >expect.all <<-EOF &&
950 <BOLD>diff --git a/x b/x<RESET>
951 <BOLD>index $before..$after 100644<RESET>
952 <BOLD>--- a/x<RESET>
953 <BOLD>+++ b/x<RESET>
954 <CYAN>@@ -1,2 +1,3 @@<RESET>
955 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
956 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
957 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
958 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
961 cat >expect.none <<-EOF
962 <BOLD>diff --git a/x b/x<RESET>
963 <BOLD>index $before..$after 100644<RESET>
964 <BOLD>--- a/x<RESET>
965 <BOLD>+++ b/x<RESET>
966 <CYAN>@@ -1,2 +1,3 @@<RESET>
967 0. blank-at-eol <RESET>
968 <RED>-1. blank-at-eol <RESET>
969 <GREEN>+1. still-blank-at-eol <RESET>
970 <GREEN>+2. and a new line <RESET>
975 test_expect_success 'test --ws-error-highlight option' '
977 git diff --color --ws-error-highlight=default,old |
978 test_decode_color >current &&
979 test_cmp expect.default-old current &&
981 git diff --color --ws-error-highlight=all |
982 test_decode_color >current &&
983 test_cmp expect.all current &&
985 git diff --color --ws-error-highlight=none |
986 test_decode_color >current &&
987 test_cmp expect.none current
991 test_expect_success 'test diff.wsErrorHighlight config' '
993 git -c diff.wsErrorHighlight=default,old diff --color |
994 test_decode_color >current &&
995 test_cmp expect.default-old current &&
997 git -c diff.wsErrorHighlight=all diff --color |
998 test_decode_color >current &&
999 test_cmp expect.all current &&
1001 git -c diff.wsErrorHighlight=none diff --color |
1002 test_decode_color >current &&
1003 test_cmp expect.none current
1007 test_expect_success 'option overrides diff.wsErrorHighlight' '
1009 git -c diff.wsErrorHighlight=none \
1010 diff --color --ws-error-highlight=default,old |
1011 test_decode_color >current &&
1012 test_cmp expect.default-old current &&
1014 git -c diff.wsErrorHighlight=default \
1015 diff --color --ws-error-highlight=all |
1016 test_decode_color >current &&
1017 test_cmp expect.all current &&
1019 git -c diff.wsErrorHighlight=all \
1020 diff --color --ws-error-highlight=none |
1021 test_decode_color >current &&
1022 test_cmp expect.none current
1026 test_expect_success 'detect moved code, complete file' '
1027 git reset --hard &&
1028 cat <<-\EOF >test.c &&
1029 #include<stdio.h>
1030 main()
1032 printf("Hello World");
1035 git add test.c &&
1036 git commit -m "add main function" &&
1037 file=$(git rev-parse --short HEAD:test.c) &&
1038 git mv test.c main.c &&
1039 test_config color.diff.oldMoved "normal red" &&
1040 test_config color.diff.newMoved "normal green" &&
1041 git diff HEAD --color-moved=zebra --color --no-renames | test_decode_color >actual &&
1042 cat >expected <<-EOF &&
1043 <BOLD>diff --git a/main.c b/main.c<RESET>
1044 <BOLD>new file mode 100644<RESET>
1045 <BOLD>index 0000000..$file<RESET>
1046 <BOLD>--- /dev/null<RESET>
1047 <BOLD>+++ b/main.c<RESET>
1048 <CYAN>@@ -0,0 +1,5 @@<RESET>
1049 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1050 <BGREEN>+<RESET><BGREEN>main()<RESET>
1051 <BGREEN>+<RESET><BGREEN>{<RESET>
1052 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1053 <BGREEN>+<RESET><BGREEN>}<RESET>
1054 <BOLD>diff --git a/test.c b/test.c<RESET>
1055 <BOLD>deleted file mode 100644<RESET>
1056 <BOLD>index $file..0000000<RESET>
1057 <BOLD>--- a/test.c<RESET>
1058 <BOLD>+++ /dev/null<RESET>
1059 <CYAN>@@ -1,5 +0,0 @@<RESET>
1060 <BRED>-#include<stdio.h><RESET>
1061 <BRED>-main()<RESET>
1062 <BRED>-{<RESET>
1063 <BRED>-printf("Hello World");<RESET>
1064 <BRED>-}<RESET>
1067 test_cmp expected actual
1070 test_expect_success 'detect malicious moved code, inside file' '
1071 test_config color.diff.oldMoved "normal red" &&
1072 test_config color.diff.newMoved "normal green" &&
1073 test_config color.diff.oldMovedAlternative "blue" &&
1074 test_config color.diff.newMovedAlternative "yellow" &&
1075 git reset --hard &&
1076 cat <<-\EOF >main.c &&
1077 #include<stdio.h>
1078 int stuff()
1080 printf("Hello ");
1081 printf("World\n");
1084 int secure_foo(struct user *u)
1086 if (!u->is_allowed_foo)
1087 return;
1088 foo(u);
1091 int main()
1093 foo();
1096 cat <<-\EOF >test.c &&
1097 #include<stdio.h>
1098 int bar()
1100 printf("Hello World, but different\n");
1103 int another_function()
1105 bar();
1108 git add main.c test.c &&
1109 git commit -m "add main and test file" &&
1110 before_main=$(git rev-parse --short HEAD:main.c) &&
1111 before_test=$(git rev-parse --short HEAD:test.c) &&
1112 cat <<-\EOF >main.c &&
1113 #include<stdio.h>
1114 int stuff()
1116 printf("Hello ");
1117 printf("World\n");
1120 int main()
1122 foo();
1125 cat <<-\EOF >test.c &&
1126 #include<stdio.h>
1127 int bar()
1129 printf("Hello World, but different\n");
1132 int secure_foo(struct user *u)
1134 foo(u);
1135 if (!u->is_allowed_foo)
1136 return;
1139 int another_function()
1141 bar();
1144 after_main=$(git rev-parse --short $(git hash-object main.c)) &&
1145 after_test=$(git rev-parse --short $(git hash-object test.c)) &&
1146 git diff HEAD --no-renames --color-moved=zebra --color | test_decode_color >actual &&
1147 cat <<-EOF >expected &&
1148 <BOLD>diff --git a/main.c b/main.c<RESET>
1149 <BOLD>index $before_main..$after_main 100644<RESET>
1150 <BOLD>--- a/main.c<RESET>
1151 <BOLD>+++ b/main.c<RESET>
1152 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1153 printf("World\n");<RESET>
1154 }<RESET>
1155 <RESET>
1156 <BRED>-int secure_foo(struct user *u)<RESET>
1157 <BRED>-{<RESET>
1158 <BLUE>-if (!u->is_allowed_foo)<RESET>
1159 <BLUE>-return;<RESET>
1160 <RED>-foo(u);<RESET>
1161 <RED>-}<RESET>
1162 <RED>-<RESET>
1163 int main()<RESET>
1164 {<RESET>
1165 foo();<RESET>
1166 <BOLD>diff --git a/test.c b/test.c<RESET>
1167 <BOLD>index $before_test..$after_test 100644<RESET>
1168 <BOLD>--- a/test.c<RESET>
1169 <BOLD>+++ b/test.c<RESET>
1170 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1171 printf("Hello World, but different\n");<RESET>
1172 }<RESET>
1173 <RESET>
1174 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1175 <BGREEN>+<RESET><BGREEN>{<RESET>
1176 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1177 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1178 <BGREEN>+<RESET><BGREEN>return;<RESET>
1179 <GREEN>+<RESET><GREEN>}<RESET>
1180 <GREEN>+<RESET>
1181 int another_function()<RESET>
1182 {<RESET>
1183 bar();<RESET>
1186 test_cmp expected actual
1189 test_expect_success 'plain moved code, inside file' '
1190 test_config color.diff.oldMoved "normal red" &&
1191 test_config color.diff.newMoved "normal green" &&
1192 test_config color.diff.oldMovedAlternative "blue" &&
1193 test_config color.diff.newMovedAlternative "yellow" &&
1194 # needs previous test as setup
1195 git diff HEAD --no-renames --color-moved=plain --color | test_decode_color >actual &&
1196 cat <<-EOF >expected &&
1197 <BOLD>diff --git a/main.c b/main.c<RESET>
1198 <BOLD>index $before_main..$after_main 100644<RESET>
1199 <BOLD>--- a/main.c<RESET>
1200 <BOLD>+++ b/main.c<RESET>
1201 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1202 printf("World\n");<RESET>
1203 }<RESET>
1204 <RESET>
1205 <BRED>-int secure_foo(struct user *u)<RESET>
1206 <BRED>-{<RESET>
1207 <BRED>-if (!u->is_allowed_foo)<RESET>
1208 <BRED>-return;<RESET>
1209 <BRED>-foo(u);<RESET>
1210 <BRED>-}<RESET>
1211 <BRED>-<RESET>
1212 int main()<RESET>
1213 {<RESET>
1214 foo();<RESET>
1215 <BOLD>diff --git a/test.c b/test.c<RESET>
1216 <BOLD>index $before_test..$after_test 100644<RESET>
1217 <BOLD>--- a/test.c<RESET>
1218 <BOLD>+++ b/test.c<RESET>
1219 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1220 printf("Hello World, but different\n");<RESET>
1221 }<RESET>
1222 <RESET>
1223 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1224 <BGREEN>+<RESET><BGREEN>{<RESET>
1225 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1226 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1227 <BGREEN>+<RESET><BGREEN>return;<RESET>
1228 <BGREEN>+<RESET><BGREEN>}<RESET>
1229 <BGREEN>+<RESET>
1230 int another_function()<RESET>
1231 {<RESET>
1232 bar();<RESET>
1235 test_cmp expected actual
1238 test_expect_success 'detect blocks of moved code' '
1239 git reset --hard &&
1240 cat <<-\EOF >lines.txt &&
1241 long line 1
1242 long line 2
1243 long line 3
1244 line 4
1245 line 5
1246 line 6
1247 line 7
1248 line 8
1249 line 9
1250 line 10
1251 line 11
1252 line 12
1253 line 13
1254 long line 14
1255 long line 15
1256 long line 16
1258 git add lines.txt &&
1259 git commit -m "add poetry" &&
1260 cat <<-\EOF >lines.txt &&
1261 line 4
1262 line 5
1263 line 6
1264 line 7
1265 line 8
1266 line 9
1267 long line 1
1268 long line 2
1269 long line 3
1270 long line 14
1271 long line 15
1272 long line 16
1273 line 10
1274 line 11
1275 line 12
1276 line 13
1278 test_config color.diff.oldMoved "magenta" &&
1279 test_config color.diff.newMoved "cyan" &&
1280 test_config color.diff.oldMovedAlternative "blue" &&
1281 test_config color.diff.newMovedAlternative "yellow" &&
1282 test_config color.diff.oldMovedDimmed "normal magenta" &&
1283 test_config color.diff.newMovedDimmed "normal cyan" &&
1284 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1285 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1286 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1287 grep -v "index" actual.raw | test_decode_color >actual &&
1288 cat <<-\EOF >expected &&
1289 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1290 <BOLD>--- a/lines.txt<RESET>
1291 <BOLD>+++ b/lines.txt<RESET>
1292 <CYAN>@@ -1,16 +1,16 @@<RESET>
1293 <MAGENTA>-long line 1<RESET>
1294 <MAGENTA>-long line 2<RESET>
1295 <MAGENTA>-long line 3<RESET>
1296 line 4<RESET>
1297 line 5<RESET>
1298 line 6<RESET>
1299 line 7<RESET>
1300 line 8<RESET>
1301 line 9<RESET>
1302 <CYAN>+<RESET><CYAN>long line 1<RESET>
1303 <CYAN>+<RESET><CYAN>long line 2<RESET>
1304 <CYAN>+<RESET><CYAN>long line 3<RESET>
1305 <CYAN>+<RESET><CYAN>long line 14<RESET>
1306 <CYAN>+<RESET><CYAN>long line 15<RESET>
1307 <CYAN>+<RESET><CYAN>long line 16<RESET>
1308 line 10<RESET>
1309 line 11<RESET>
1310 line 12<RESET>
1311 line 13<RESET>
1312 <MAGENTA>-long line 14<RESET>
1313 <MAGENTA>-long line 15<RESET>
1314 <MAGENTA>-long line 16<RESET>
1316 test_cmp expected actual
1320 test_expect_success 'detect permutations inside moved code -- dimmed-zebra' '
1321 # reuse setup from test before!
1322 test_config color.diff.oldMoved "magenta" &&
1323 test_config color.diff.newMoved "cyan" &&
1324 test_config color.diff.oldMovedAlternative "blue" &&
1325 test_config color.diff.newMovedAlternative "yellow" &&
1326 test_config color.diff.oldMovedDimmed "normal magenta" &&
1327 test_config color.diff.newMovedDimmed "normal cyan" &&
1328 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1329 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1330 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1331 grep -v "index" actual.raw | test_decode_color >actual &&
1332 cat <<-\EOF >expected &&
1333 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1334 <BOLD>--- a/lines.txt<RESET>
1335 <BOLD>+++ b/lines.txt<RESET>
1336 <CYAN>@@ -1,16 +1,16 @@<RESET>
1337 <BMAGENTA>-long line 1<RESET>
1338 <BMAGENTA>-long line 2<RESET>
1339 <BMAGENTA>-long line 3<RESET>
1340 line 4<RESET>
1341 line 5<RESET>
1342 line 6<RESET>
1343 line 7<RESET>
1344 line 8<RESET>
1345 line 9<RESET>
1346 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1347 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1348 <CYAN>+<RESET><CYAN>long line 3<RESET>
1349 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1350 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1351 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1352 line 10<RESET>
1353 line 11<RESET>
1354 line 12<RESET>
1355 line 13<RESET>
1356 <BMAGENTA>-long line 14<RESET>
1357 <BMAGENTA>-long line 15<RESET>
1358 <BMAGENTA>-long line 16<RESET>
1360 test_cmp expected actual
1363 test_expect_success 'cmd option assumes configured colored-moved' '
1364 test_config color.diff.oldMoved "magenta" &&
1365 test_config color.diff.newMoved "cyan" &&
1366 test_config color.diff.oldMovedAlternative "blue" &&
1367 test_config color.diff.newMovedAlternative "yellow" &&
1368 test_config color.diff.oldMovedDimmed "normal magenta" &&
1369 test_config color.diff.newMovedDimmed "normal cyan" &&
1370 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1371 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1372 test_config diff.colorMoved zebra &&
1373 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1374 grep -v "index" actual.raw | test_decode_color >actual &&
1375 cat <<-\EOF >expected &&
1376 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1377 <BOLD>--- a/lines.txt<RESET>
1378 <BOLD>+++ b/lines.txt<RESET>
1379 <CYAN>@@ -1,16 +1,16 @@<RESET>
1380 <MAGENTA>-long line 1<RESET>
1381 <MAGENTA>-long line 2<RESET>
1382 <MAGENTA>-long line 3<RESET>
1383 line 4<RESET>
1384 line 5<RESET>
1385 line 6<RESET>
1386 line 7<RESET>
1387 line 8<RESET>
1388 line 9<RESET>
1389 <CYAN>+<RESET><CYAN>long line 1<RESET>
1390 <CYAN>+<RESET><CYAN>long line 2<RESET>
1391 <CYAN>+<RESET><CYAN>long line 3<RESET>
1392 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1393 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1394 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1395 line 10<RESET>
1396 line 11<RESET>
1397 line 12<RESET>
1398 line 13<RESET>
1399 <MAGENTA>-long line 14<RESET>
1400 <MAGENTA>-long line 15<RESET>
1401 <MAGENTA>-long line 16<RESET>
1403 test_cmp expected actual
1406 test_expect_success 'no effect from --color-moved with --word-diff' '
1407 cat <<-\EOF >text.txt &&
1408 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1410 git add text.txt &&
1411 git commit -a -m "clean state" &&
1412 cat <<-\EOF >text.txt &&
1413 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1415 git diff --color-moved --word-diff >actual &&
1416 git diff --word-diff >expect &&
1417 test_cmp expect actual
1420 test_expect_success 'set up whitespace tests' '
1421 git reset --hard &&
1422 # Note that these lines have no leading or trailing whitespace.
1423 cat <<-\EOF >lines.txt &&
1424 line 1
1425 line 2
1426 line 3
1427 line 4
1428 line 5
1429 long line 6
1430 long line 7
1431 long line 8
1432 long line 9
1434 git add lines.txt &&
1435 git commit -m "add poetry" &&
1436 git config color.diff.oldMoved "magenta" &&
1437 git config color.diff.newMoved "cyan"
1440 test_expect_success 'move detection ignoring whitespace ' '
1441 q_to_tab <<-\EOF >lines.txt &&
1442 Qlong line 6
1443 Qlong line 7
1444 Qlong line 8
1445 Qchanged long line 9
1446 line 1
1447 line 2
1448 line 3
1449 line 4
1450 line 5
1452 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1453 grep -v "index" actual.raw | test_decode_color >actual &&
1454 cat <<-\EOF >expected &&
1455 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1456 <BOLD>--- a/lines.txt<RESET>
1457 <BOLD>+++ b/lines.txt<RESET>
1458 <CYAN>@@ -1,9 +1,9 @@<RESET>
1459 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1460 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1461 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1462 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1463 line 1<RESET>
1464 line 2<RESET>
1465 line 3<RESET>
1466 line 4<RESET>
1467 line 5<RESET>
1468 <RED>-long line 6<RESET>
1469 <RED>-long line 7<RESET>
1470 <RED>-long line 8<RESET>
1471 <RED>-long line 9<RESET>
1473 test_cmp expected actual &&
1475 git diff HEAD --no-renames --color-moved --color \
1476 --color-moved-ws=ignore-all-space >actual.raw &&
1477 grep -v "index" actual.raw | test_decode_color >actual &&
1478 cat <<-\EOF >expected &&
1479 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1480 <BOLD>--- a/lines.txt<RESET>
1481 <BOLD>+++ b/lines.txt<RESET>
1482 <CYAN>@@ -1,9 +1,9 @@<RESET>
1483 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1484 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1485 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1486 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1487 line 1<RESET>
1488 line 2<RESET>
1489 line 3<RESET>
1490 line 4<RESET>
1491 line 5<RESET>
1492 <MAGENTA>-long line 6<RESET>
1493 <MAGENTA>-long line 7<RESET>
1494 <MAGENTA>-long line 8<RESET>
1495 <RED>-long line 9<RESET>
1497 test_cmp expected actual
1500 test_expect_success 'move detection ignoring whitespace changes' '
1501 git reset --hard &&
1502 # Lines 6-8 have a space change, but 9 is new whitespace
1503 q_to_tab <<-\EOF >lines.txt &&
1504 longQline 6
1505 longQline 7
1506 longQline 8
1507 long liQne 9
1508 line 1
1509 line 2
1510 line 3
1511 line 4
1512 line 5
1515 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1516 grep -v "index" actual.raw | test_decode_color >actual &&
1517 cat <<-\EOF >expected &&
1518 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1519 <BOLD>--- a/lines.txt<RESET>
1520 <BOLD>+++ b/lines.txt<RESET>
1521 <CYAN>@@ -1,9 +1,9 @@<RESET>
1522 <GREEN>+<RESET><GREEN>long line 6<RESET>
1523 <GREEN>+<RESET><GREEN>long line 7<RESET>
1524 <GREEN>+<RESET><GREEN>long line 8<RESET>
1525 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1526 line 1<RESET>
1527 line 2<RESET>
1528 line 3<RESET>
1529 line 4<RESET>
1530 line 5<RESET>
1531 <RED>-long line 6<RESET>
1532 <RED>-long line 7<RESET>
1533 <RED>-long line 8<RESET>
1534 <RED>-long line 9<RESET>
1536 test_cmp expected actual &&
1538 git diff HEAD --no-renames --color-moved --color \
1539 --color-moved-ws=ignore-space-change >actual.raw &&
1540 grep -v "index" actual.raw | test_decode_color >actual &&
1541 cat <<-\EOF >expected &&
1542 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1543 <BOLD>--- a/lines.txt<RESET>
1544 <BOLD>+++ b/lines.txt<RESET>
1545 <CYAN>@@ -1,9 +1,9 @@<RESET>
1546 <CYAN>+<RESET><CYAN>long line 6<RESET>
1547 <CYAN>+<RESET><CYAN>long line 7<RESET>
1548 <CYAN>+<RESET><CYAN>long line 8<RESET>
1549 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1550 line 1<RESET>
1551 line 2<RESET>
1552 line 3<RESET>
1553 line 4<RESET>
1554 line 5<RESET>
1555 <MAGENTA>-long line 6<RESET>
1556 <MAGENTA>-long line 7<RESET>
1557 <MAGENTA>-long line 8<RESET>
1558 <RED>-long line 9<RESET>
1560 test_cmp expected actual
1563 test_expect_success 'move detection ignoring whitespace at eol' '
1564 git reset --hard &&
1565 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1566 q_to_tab <<-\EOF >lines.txt &&
1567 long line 6Q
1568 long line 7Q
1569 long line 8Q
1570 longQline 9Q
1571 line 1
1572 line 2
1573 line 3
1574 line 4
1575 line 5
1578 # avoid cluttering the output with complaints about our eol whitespace
1579 test_config core.whitespace -blank-at-eol &&
1581 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1582 grep -v "index" actual.raw | test_decode_color >actual &&
1583 cat <<-\EOF >expected &&
1584 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1585 <BOLD>--- a/lines.txt<RESET>
1586 <BOLD>+++ b/lines.txt<RESET>
1587 <CYAN>@@ -1,9 +1,9 @@<RESET>
1588 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1589 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1590 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1591 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1592 line 1<RESET>
1593 line 2<RESET>
1594 line 3<RESET>
1595 line 4<RESET>
1596 line 5<RESET>
1597 <RED>-long line 6<RESET>
1598 <RED>-long line 7<RESET>
1599 <RED>-long line 8<RESET>
1600 <RED>-long line 9<RESET>
1602 test_cmp expected actual &&
1604 git diff HEAD --no-renames --color-moved --color \
1605 --color-moved-ws=ignore-space-at-eol >actual.raw &&
1606 grep -v "index" actual.raw | test_decode_color >actual &&
1607 cat <<-\EOF >expected &&
1608 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1609 <BOLD>--- a/lines.txt<RESET>
1610 <BOLD>+++ b/lines.txt<RESET>
1611 <CYAN>@@ -1,9 +1,9 @@<RESET>
1612 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1613 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1614 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1615 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1616 line 1<RESET>
1617 line 2<RESET>
1618 line 3<RESET>
1619 line 4<RESET>
1620 line 5<RESET>
1621 <MAGENTA>-long line 6<RESET>
1622 <MAGENTA>-long line 7<RESET>
1623 <MAGENTA>-long line 8<RESET>
1624 <RED>-long line 9<RESET>
1626 test_cmp expected actual
1629 test_expect_success 'clean up whitespace-test colors' '
1630 git config --unset color.diff.oldMoved &&
1631 git config --unset color.diff.newMoved
1634 test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1635 git reset --hard &&
1636 >bar &&
1637 cat <<-\EOF >foo &&
1638 irrelevant_line
1639 line1
1641 git add foo bar &&
1642 git commit -m x &&
1644 cat <<-\EOF >bar &&
1645 line1
1647 cat <<-\EOF >foo &&
1648 irrelevant_line
1651 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1652 grep -v "index" actual.raw | test_decode_color >actual &&
1653 cat >expected <<-\EOF &&
1654 <BOLD>diff --git a/bar b/bar<RESET>
1655 <BOLD>--- a/bar<RESET>
1656 <BOLD>+++ b/bar<RESET>
1657 <CYAN>@@ -0,0 +1 @@<RESET>
1658 <GREEN>+<RESET><GREEN>line1<RESET>
1659 <BOLD>diff --git a/foo b/foo<RESET>
1660 <BOLD>--- a/foo<RESET>
1661 <BOLD>+++ b/foo<RESET>
1662 <CYAN>@@ -1,2 +1 @@<RESET>
1663 irrelevant_line<RESET>
1664 <RED>-line1<RESET>
1667 test_cmp expected actual
1670 test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
1671 git reset --hard &&
1672 cat <<-\EOF >foo &&
1673 nineteen chars 456789
1674 irrelevant_line
1675 twenty chars 234567890
1677 >bar &&
1678 git add foo bar &&
1679 git commit -m x &&
1681 cat <<-\EOF >foo &&
1682 irrelevant_line
1684 cat <<-\EOF >bar &&
1685 twenty chars 234567890
1686 nineteen chars 456789
1689 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1690 grep -v "index" actual.raw | test_decode_color >actual &&
1691 cat >expected <<-\EOF &&
1692 <BOLD>diff --git a/bar b/bar<RESET>
1693 <BOLD>--- a/bar<RESET>
1694 <BOLD>+++ b/bar<RESET>
1695 <CYAN>@@ -0,0 +1,2 @@<RESET>
1696 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1697 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1698 <BOLD>diff --git a/foo b/foo<RESET>
1699 <BOLD>--- a/foo<RESET>
1700 <BOLD>+++ b/foo<RESET>
1701 <CYAN>@@ -1,3 +1 @@<RESET>
1702 <RED>-nineteen chars 456789<RESET>
1703 irrelevant_line<RESET>
1704 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1707 test_cmp expected actual
1710 test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1711 git reset --hard &&
1712 cat <<-\EOF >foo &&
1713 7charsA
1714 irrelevant_line
1715 7charsB
1716 7charsC
1718 >bar &&
1719 git add foo bar &&
1720 git commit -m x &&
1722 cat <<-\EOF >foo &&
1723 irrelevant_line
1725 cat <<-\EOF >bar &&
1726 7charsB
1727 7charsC
1728 7charsA
1731 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1732 grep -v "index" actual.raw | test_decode_color >actual &&
1733 cat >expected <<-\EOF &&
1734 <BOLD>diff --git a/bar b/bar<RESET>
1735 <BOLD>--- a/bar<RESET>
1736 <BOLD>+++ b/bar<RESET>
1737 <CYAN>@@ -0,0 +1,3 @@<RESET>
1738 <GREEN>+<RESET><GREEN>7charsB<RESET>
1739 <GREEN>+<RESET><GREEN>7charsC<RESET>
1740 <GREEN>+<RESET><GREEN>7charsA<RESET>
1741 <BOLD>diff --git a/foo b/foo<RESET>
1742 <BOLD>--- a/foo<RESET>
1743 <BOLD>+++ b/foo<RESET>
1744 <CYAN>@@ -1,4 +1 @@<RESET>
1745 <RED>-7charsA<RESET>
1746 irrelevant_line<RESET>
1747 <RED>-7charsB<RESET>
1748 <RED>-7charsC<RESET>
1751 test_cmp expected actual
1754 test_expect_success 'move detection with submodules' '
1755 test_create_repo bananas &&
1756 echo ripe >bananas/recipe &&
1757 git -C bananas add recipe &&
1758 test_commit fruit &&
1759 test_commit -C bananas recipe &&
1760 git submodule add ./bananas &&
1761 git add bananas &&
1762 git commit -a -m "bananas are like a heavy library?" &&
1763 echo foul >bananas/recipe &&
1764 echo ripe >fruit.t &&
1766 git diff --submodule=diff --color-moved --color >actual &&
1768 # no move detection as the moved line is across repository boundaries.
1769 test_decode_color <actual >decoded_actual &&
1770 ! grep BGREEN decoded_actual &&
1771 ! grep BRED decoded_actual &&
1773 # nor did we mess with it another way
1774 git diff --submodule=diff --color | test_decode_color >expect &&
1775 test_cmp expect decoded_actual &&
1776 rm -rf bananas &&
1777 git submodule deinit bananas
1780 test_expect_success 'only move detection ignores white spaces' '
1781 git reset --hard &&
1782 q_to_tab <<-\EOF >text.txt &&
1783 a long line to exceed per-line minimum
1784 another long line to exceed per-line minimum
1785 original file
1787 git add text.txt &&
1788 git commit -m "add text" &&
1789 q_to_tab <<-\EOF >text.txt &&
1790 Qa long line to exceed per-line minimum
1791 Qanother long line to exceed per-line minimum
1792 new file
1795 # Make sure we get a different diff using -w
1796 git diff --color --color-moved -w >actual.raw &&
1797 grep -v "index" actual.raw | test_decode_color >actual &&
1798 q_to_tab <<-\EOF >expected &&
1799 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1800 <BOLD>--- a/text.txt<RESET>
1801 <BOLD>+++ b/text.txt<RESET>
1802 <CYAN>@@ -1,3 +1,3 @@<RESET>
1803 Qa long line to exceed per-line minimum<RESET>
1804 Qanother long line to exceed per-line minimum<RESET>
1805 <RED>-original file<RESET>
1806 <GREEN>+<RESET><GREEN>new file<RESET>
1808 test_cmp expected actual &&
1810 # And now ignoring white space only in the move detection
1811 git diff --color --color-moved \
1812 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
1813 grep -v "index" actual.raw | test_decode_color >actual &&
1814 q_to_tab <<-\EOF >expected &&
1815 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1816 <BOLD>--- a/text.txt<RESET>
1817 <BOLD>+++ b/text.txt<RESET>
1818 <CYAN>@@ -1,3 +1,3 @@<RESET>
1819 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
1820 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
1821 <RED>-original file<RESET>
1822 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>a long line to exceed per-line minimum<RESET>
1823 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>another long line to exceed per-line minimum<RESET>
1824 <GREEN>+<RESET><GREEN>new file<RESET>
1826 test_cmp expected actual
1829 test_expect_success 'compare whitespace delta across moved blocks' '
1831 git reset --hard &&
1832 q_to_tab <<-\EOF >text.txt &&
1833 QIndented
1834 QText across
1835 Qsome lines
1836 QBut! <- this stands out
1837 QAdjusting with
1838 QQdifferent starting
1839 Qwhite spaces
1840 QAnother outlier
1841 QQQIndented
1842 QQQText across
1843 QQQfive lines
1844 QQQthat has similar lines
1845 QQQto previous blocks, but with different indent
1846 QQQYetQAnotherQoutlierQ
1847 QLine with internal w h i t e s p a c e change
1850 git add text.txt &&
1851 git commit -m "add text.txt" &&
1853 q_to_tab <<-\EOF >text.txt &&
1854 QQIndented
1855 QQText across
1856 QQsome lines
1857 QQQBut! <- this stands out
1858 Adjusting with
1859 Qdifferent starting
1860 white spaces
1861 AnotherQoutlier
1862 QQIndented
1863 QQText across
1864 QQfive lines
1865 QQthat has similar lines
1866 QQto previous blocks, but with different indent
1867 QQYetQAnotherQoutlier
1868 QLine with internal whitespace change
1871 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
1872 grep -v "index" actual.raw | test_decode_color >actual &&
1874 q_to_tab <<-\EOF >expected &&
1875 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1876 <BOLD>--- a/text.txt<RESET>
1877 <BOLD>+++ b/text.txt<RESET>
1878 <CYAN>@@ -1,15 +1,15 @@<RESET>
1879 <BOLD;MAGENTA>-QIndented<RESET>
1880 <BOLD;MAGENTA>-QText across<RESET>
1881 <BOLD;MAGENTA>-Qsome lines<RESET>
1882 <RED>-QBut! <- this stands out<RESET>
1883 <BOLD;MAGENTA>-QAdjusting with<RESET>
1884 <BOLD;MAGENTA>-QQdifferent starting<RESET>
1885 <BOLD;MAGENTA>-Qwhite spaces<RESET>
1886 <RED>-QAnother outlier<RESET>
1887 <BOLD;MAGENTA>-QQQIndented<RESET>
1888 <BOLD;MAGENTA>-QQQText across<RESET>
1889 <BOLD;MAGENTA>-QQQfive lines<RESET>
1890 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
1891 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
1892 <RED>-QQQYetQAnotherQoutlierQ<RESET>
1893 <RED>-QLine with internal w h i t e s p a c e change<RESET>
1894 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1895 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1896 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
1897 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
1898 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
1899 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
1900 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
1901 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
1902 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1903 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1904 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
1905 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
1906 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
1907 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
1908 <GREEN>+<RESET>Q<GREEN>Line with internal whitespace change<RESET>
1911 test_cmp expected actual
1914 test_expect_success 'bogus settings in move detection erroring out' '
1915 test_must_fail git diff --color-moved=bogus 2>err &&
1916 test_i18ngrep "must be one of" err &&
1917 test_i18ngrep bogus err &&
1919 test_must_fail git -c diff.colormoved=bogus diff 2>err &&
1920 test_i18ngrep "must be one of" err &&
1921 test_i18ngrep "from command-line config" err &&
1923 test_must_fail git diff --color-moved-ws=bogus 2>err &&
1924 test_i18ngrep "possible values" err &&
1925 test_i18ngrep bogus err &&
1927 test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
1928 test_i18ngrep "possible values" err &&
1929 test_i18ngrep "from command-line config" err
1932 test_expect_success 'compare whitespace delta incompatible with other space options' '
1933 test_must_fail git diff \
1934 --color-moved-ws=allow-indentation-change,ignore-all-space \
1935 2>err &&
1936 test_i18ngrep allow-indentation-change err
1939 EMPTY=''
1940 test_expect_success 'compare mixed whitespace delta across moved blocks' '
1942 git reset --hard &&
1943 tr Q_ "\t " <<-EOF >text.txt &&
1944 ${EMPTY}
1945 ____too short without
1946 ${EMPTY}
1947 ___being grouped across blank line
1948 ${EMPTY}
1949 context
1950 lines
1952 anchor
1953 ____Indented text to
1954 _Q____be further indented by four spaces across
1955 ____Qseveral lines
1956 QQ____These two lines have had their
1957 ____indentation reduced by four spaces
1958 Qdifferent indentation change
1959 ____too short
1962 git add text.txt &&
1963 git commit -m "add text.txt" &&
1965 tr Q_ "\t " <<-EOF >text.txt &&
1966 context
1967 lines
1969 anchor
1970 QIndented text to
1971 QQbe further indented by four spaces across
1972 Q____several lines
1973 ${EMPTY}
1974 QQtoo short without
1975 ${EMPTY}
1976 Q_______being grouped across blank line
1977 ${EMPTY}
1978 Q_QThese two lines have had their
1979 indentation reduced by four spaces
1980 QQdifferent indentation change
1981 __Qtoo short
1984 git -c color.diff.whitespace="normal red" \
1985 -c core.whitespace=space-before-tab \
1986 diff --color --color-moved --ws-error-highlight=all \
1987 --color-moved-ws=allow-indentation-change >actual.raw &&
1988 grep -v "index" actual.raw | test_decode_color >actual &&
1990 cat <<-\EOF >expected &&
1991 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1992 <BOLD>--- a/text.txt<RESET>
1993 <BOLD>+++ b/text.txt<RESET>
1994 <CYAN>@@ -1,16 +1,16 @@<RESET>
1995 <BOLD;MAGENTA>-<RESET>
1996 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> too short without<RESET>
1997 <BOLD;MAGENTA>-<RESET>
1998 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
1999 <BOLD;MAGENTA>-<RESET>
2000 <RESET>context<RESET>
2001 <RESET>lines<RESET>
2002 <RESET>to<RESET>
2003 <RESET>anchor<RESET>
2004 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
2005 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
2006 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
2007 <BOLD;BLUE>-<RESET> <BOLD;BLUE> These two lines have had their<RESET>
2008 <BOLD;BLUE>-<RESET><BOLD;BLUE> indentation reduced by four spaces<RESET>
2009 <BOLD;MAGENTA>-<RESET> <BOLD;MAGENTA>different indentation change<RESET>
2010 <RED>-<RESET><RED> too short<RESET>
2011 <BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
2012 <BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
2013 <BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
2014 <BOLD;YELLOW>+<RESET>
2015 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
2016 <BOLD;YELLOW>+<RESET>
2017 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW> being grouped across blank line<RESET>
2018 <BOLD;YELLOW>+<RESET>
2019 <BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
2020 <BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
2021 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
2022 <GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
2025 test_cmp expected actual
2028 # Note that the "6" in the expected hunk header below is funny, since we only
2029 # show 5 lines (the missing one was blank and thus ignored). This is how
2030 # --ignore-blank-lines behaves even without --function-context, and this test
2031 # is just checking the interaction of the two features. Don't take it as an
2032 # endorsement of that output.
2033 test_expect_success 'combine --ignore-blank-lines with --function-context' '
2034 test_write_lines 1 "" 2 3 4 5 >a &&
2035 test_write_lines 1 2 3 4 >b &&
2036 test_must_fail git diff --no-index \
2037 --ignore-blank-lines --function-context a b >actual.raw &&
2038 sed -n "/@@/,\$p" <actual.raw >actual &&
2039 cat <<-\EOF >expect &&
2040 @@ -1,6 +1,4 @@
2047 test_cmp expect actual
2050 test_done