debian: prepare for upload
[git/debian.git] / t / t4015-diff-whitespace.sh
blob8bdaa0a693fa52adf2314d5777a195d035d6009c
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 old_hash_x=$(git hash-object x) &&
20 before=$(git rev-parse --short "$old_hash_x") &&
22 cat <<-\EOF >x &&
25 nothing;
27 while (0);
28 EOF
29 new_hash_x=$(git hash-object x) &&
30 after=$(git rev-parse --short "$new_hash_x") &&
32 cat <<-EOF >expect &&
33 diff --git a/x b/x
34 index $before..$after 100644
35 --- a/x
36 +++ b/x
37 @@ -1,3 +1,5 @@
38 -do {
39 +do
41 nothing;
42 -} while (0);
44 +while (0);
45 EOF
47 git diff >out &&
48 test_cmp expect out &&
50 git diff -w >out &&
51 test_cmp expect out &&
53 git diff -b >out &&
54 test_cmp expect out
57 test_expect_success 'another test, without options' '
58 tr Q "\015" <<-\EOF >x &&
59 whitespace at beginning
60 whitespace change
61 whitespace in the middle
62 whitespace at end
63 unchanged line
64 CR at endQ
65 EOF
67 git update-index x &&
68 old_hash_x=$(git hash-object x) &&
69 before=$(git rev-parse --short "$old_hash_x") &&
71 tr "_" " " <<-\EOF >x &&
72 _ whitespace at beginning
73 whitespace change
74 white space in the middle
75 whitespace at end__
76 unchanged line
77 CR at end
78 EOF
79 new_hash_x=$(git hash-object x) &&
80 after=$(git rev-parse --short "$new_hash_x") &&
82 tr "Q_" "\015 " <<-EOF >expect &&
83 diff --git a/x b/x
84 index $before..$after 100644
85 --- a/x
86 +++ b/x
87 @@ -1,6 +1,6 @@
88 -whitespace at beginning
89 -whitespace change
90 -whitespace in the middle
91 -whitespace at end
92 + whitespace at beginning
93 +whitespace change
94 +white space in the middle
95 +whitespace at end__
96 unchanged line
97 -CR at endQ
98 +CR at end
99 EOF
101 git diff >out &&
102 test_cmp expect out &&
104 git diff -w >out &&
105 test_must_be_empty out &&
107 git diff -w -b >out &&
108 test_must_be_empty out &&
110 git diff -w --ignore-space-at-eol >out &&
111 test_must_be_empty out &&
113 git diff -w -b --ignore-space-at-eol >out &&
114 test_must_be_empty out &&
116 git diff -w --ignore-cr-at-eol >out &&
117 test_must_be_empty out &&
119 tr "Q_" "\015 " <<-EOF >expect &&
120 diff --git a/x b/x
121 index $before..$after 100644
122 --- a/x
123 +++ b/x
124 @@ -1,6 +1,6 @@
125 -whitespace at beginning
126 +_ whitespace at beginning
127 whitespace change
128 -whitespace in the middle
129 +white space in the middle
130 whitespace at end__
131 unchanged line
132 CR at end
134 git diff -b >out &&
135 test_cmp expect out &&
137 git diff -b --ignore-space-at-eol >out &&
138 test_cmp expect out &&
140 git diff -b --ignore-cr-at-eol >out &&
141 test_cmp expect out &&
143 tr "Q_" "\015 " <<-EOF >expect &&
144 diff --git a/x b/x
145 index $before..$after 100644
146 --- a/x
147 +++ b/x
148 @@ -1,6 +1,6 @@
149 -whitespace at beginning
150 -whitespace change
151 -whitespace in the middle
152 +_ whitespace at beginning
153 +whitespace change
154 +white space in the middle
155 whitespace at end__
156 unchanged line
157 CR at end
159 git diff --ignore-space-at-eol >out &&
160 test_cmp expect out &&
162 git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
163 test_cmp expect out &&
165 tr "Q_" "\015 " <<-EOF >expect &&
166 diff --git a/x b/x
167 index_$before..$after 100644
168 --- a/x
169 +++ b/x
170 @@ -1,6 +1,6 @@
171 -whitespace at beginning
172 -whitespace change
173 -whitespace in the middle
174 -whitespace at end
175 +_ whitespace at beginning
176 +whitespace_ _change
177 +white space in the middle
178 +whitespace at end__
179 unchanged line
180 CR at end
182 git diff --ignore-cr-at-eol >out &&
183 test_cmp expect out
186 test_expect_success 'ignore-blank-lines: only new lines' '
187 test_seq 5 >x &&
188 git update-index x &&
189 test_seq 5 | sed "/3/i\\
190 " >x &&
191 git diff --ignore-blank-lines >out &&
192 test_must_be_empty out
195 test_expect_success 'ignore-blank-lines: only new lines with space' '
196 test_seq 5 >x &&
197 git update-index x &&
198 test_seq 5 | sed "/3/i\\
199 " >x &&
200 git diff -w --ignore-blank-lines >out &&
201 test_must_be_empty out
204 test_expect_success 'ignore-blank-lines: after change' '
205 cat <<-\EOF >x &&
216 git update-index x &&
217 cat <<-\EOF >x &&
218 change
229 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
230 cat <<-\EOF >expected &&
231 diff --git a/x b/x
232 --- a/x
233 +++ b/x
234 @@ -1,6 +1,7 @@
235 +change
244 compare_diff_patch expected out.tmp
247 test_expect_success 'ignore-blank-lines: before change' '
248 cat <<-\EOF >x &&
258 git update-index x &&
259 cat <<-\EOF >x &&
269 change
271 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
272 cat <<-\EOF >expected &&
273 diff --git a/x b/x
274 --- a/x
275 +++ b/x
276 @@ -4,5 +4,7 @@
283 +change
285 compare_diff_patch expected out.tmp
288 test_expect_success 'ignore-blank-lines: between changes' '
289 cat <<-\EOF >x &&
303 git update-index x &&
304 cat <<-\EOF >x &&
305 change
318 change
320 git diff --ignore-blank-lines >out.tmp &&
321 cat <<-\EOF >expected &&
322 diff --git a/x b/x
323 --- a/x
324 +++ b/x
325 @@ -1,5 +1,7 @@
326 +change
333 @@ -8,5 +8,7 @@
340 +change
342 compare_diff_patch expected out.tmp
345 test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
346 test_seq 10 >x &&
347 git update-index x &&
348 cat <<-\EOF >x &&
349 change
363 change
365 git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
366 cat <<-\EOF >expected &&
367 diff --git a/x b/x
368 --- a/x
369 +++ b/x
370 @@ -1,10 +1,15 @@
371 +change
385 +change
387 compare_diff_patch expected out.tmp
390 test_expect_success 'ignore-blank-lines: scattered spaces' '
391 test_seq 10 >x &&
392 git update-index x &&
393 cat <<-\EOF >x &&
394 change
411 change
413 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
414 cat <<-\EOF >expected &&
415 diff --git a/x b/x
416 --- a/x
417 +++ b/x
418 @@ -1,3 +1,4 @@
419 +change
423 @@ -8,3 +15,4 @@
427 +change
429 compare_diff_patch expected out.tmp
432 test_expect_success 'ignore-blank-lines: spaces coalesce' '
433 test_seq 6 >x &&
434 git update-index x &&
435 cat <<-\EOF >x &&
436 change
446 change
448 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
449 cat <<-\EOF >expected &&
450 diff --git a/x b/x
451 --- a/x
452 +++ b/x
453 @@ -1,6 +1,11 @@
454 +change
464 +change
466 compare_diff_patch expected out.tmp
469 test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
470 test_seq 16 >x &&
471 git update-index x &&
472 cat <<-\EOF >x &&
473 change
480 change
488 change
495 change
497 git diff --ignore-blank-lines >out.tmp &&
498 cat <<-\EOF >expected &&
499 diff --git a/x b/x
500 --- a/x
501 +++ b/x
502 @@ -1,8 +1,11 @@
503 +change
510 +change
514 @@ -9,8 +13,11 @@
518 +change
525 +change
527 compare_diff_patch expected out.tmp
530 test_expect_success 'check mixed spaces and tabs in indent' '
531 # This is indented with SP HT SP.
532 echo " foo();" >x &&
533 test_must_fail git diff --check >check &&
534 grep "space before tab in indent" check
537 test_expect_success 'check mixed tabs and spaces in indent' '
538 # This is indented with HT SP HT.
539 echo " foo();" >x &&
540 test_must_fail git diff --check >check &&
541 grep "space before tab in indent" check
544 test_expect_success 'check with no whitespace errors' '
545 git commit -m "snapshot" &&
546 echo "foo();" >x &&
547 git diff --check
550 test_expect_success 'check with trailing whitespace' '
551 echo "foo(); " >x &&
552 test_must_fail git diff --check
555 test_expect_success 'check with space before tab in indent' '
556 # indent has space followed by hard tab
557 echo " foo();" >x &&
558 test_must_fail git diff --check
561 test_expect_success '--check and --exit-code are not exclusive' '
562 git checkout x &&
563 git diff --check --exit-code
566 test_expect_success '--check and --quiet are not exclusive' '
567 git diff --check --quiet
570 test_expect_success 'check staged with no whitespace errors' '
571 echo "foo();" >x &&
572 git add x &&
573 git diff --cached --check
576 test_expect_success 'check staged with trailing whitespace' '
577 echo "foo(); " >x &&
578 git add x &&
579 test_must_fail git diff --cached --check
582 test_expect_success 'check staged with space before tab in indent' '
583 # indent has space followed by hard tab
584 echo " foo();" >x &&
585 git add x &&
586 test_must_fail git diff --cached --check
589 test_expect_success 'check with no whitespace errors (diff-index)' '
590 echo "foo();" >x &&
591 git add x &&
592 git diff-index --check HEAD
595 test_expect_success 'check with trailing whitespace (diff-index)' '
596 echo "foo(); " >x &&
597 git add x &&
598 test_must_fail git diff-index --check HEAD
601 test_expect_success 'check with space before tab in indent (diff-index)' '
602 # indent has space followed by hard tab
603 echo " foo();" >x &&
604 git add x &&
605 test_must_fail git diff-index --check HEAD
608 test_expect_success 'check staged with no whitespace errors (diff-index)' '
609 echo "foo();" >x &&
610 git add x &&
611 git diff-index --cached --check HEAD
614 test_expect_success 'check staged with trailing whitespace (diff-index)' '
615 echo "foo(); " >x &&
616 git add x &&
617 test_must_fail git diff-index --cached --check HEAD
620 test_expect_success 'check staged with space before tab in indent (diff-index)' '
621 # indent has space followed by hard tab
622 echo " foo();" >x &&
623 git add x &&
624 test_must_fail git diff-index --cached --check HEAD
627 test_expect_success 'check with no whitespace errors (diff-tree)' '
628 echo "foo();" >x &&
629 git commit -m "new commit" x &&
630 git diff-tree --check HEAD^ HEAD
633 test_expect_success 'check with trailing whitespace (diff-tree)' '
634 echo "foo(); " >x &&
635 git commit -m "another commit" x &&
636 test_must_fail git diff-tree --check HEAD^ HEAD
639 test_expect_success 'check with space before tab in indent (diff-tree)' '
640 # indent has space followed by hard tab
641 echo " foo();" >x &&
642 git commit -m "yet another" x &&
643 test_must_fail git diff-tree --check HEAD^ HEAD
646 test_expect_success 'check with ignored trailing whitespace attr (diff-tree)' '
647 test_when_finished "git reset --hard HEAD^" &&
649 # create a whitespace error that should be ignored
650 echo "* -whitespace" >.gitattributes &&
651 git add .gitattributes &&
652 echo "foo(); " >x &&
653 git add x &&
654 git commit -m "add trailing space" &&
656 # with a worktree diff-tree ignores the whitespace error
657 git diff-tree --root --check HEAD &&
659 # without a worktree diff-tree still ignores the whitespace error
660 git -C .git diff-tree --root --check HEAD
663 test_expect_success 'check trailing whitespace (trailing-space: off)' '
664 git config core.whitespace "-trailing-space" &&
665 echo "foo (); " >x &&
666 git diff --check
669 test_expect_success 'check trailing whitespace (trailing-space: on)' '
670 git config core.whitespace "trailing-space" &&
671 echo "foo (); " >x &&
672 test_must_fail git diff --check
675 test_expect_success 'check space before tab in indent (space-before-tab: off)' '
676 # indent contains space followed by HT
677 git config core.whitespace "-space-before-tab" &&
678 echo " foo ();" >x &&
679 git diff --check
682 test_expect_success 'check space before tab in indent (space-before-tab: on)' '
683 # indent contains space followed by HT
684 git config core.whitespace "space-before-tab" &&
685 echo " foo (); " >x &&
686 test_must_fail git diff --check
689 test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
690 git config core.whitespace "-indent-with-non-tab" &&
691 echo " foo ();" >x &&
692 git diff --check
695 test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
696 git config core.whitespace "indent-with-non-tab" &&
697 echo " foo ();" >x &&
698 test_must_fail git diff --check
701 test_expect_success 'ditto, but tabwidth=9' '
702 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
703 git diff --check
706 test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
707 git config core.whitespace "indent-with-non-tab" &&
708 echo " foo ();" >x &&
709 test_must_fail git diff --check
712 test_expect_success 'ditto, but tabwidth=10' '
713 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
714 test_must_fail git diff --check
717 test_expect_success 'ditto, but tabwidth=20' '
718 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
719 git diff --check
722 test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
723 git config core.whitespace "-tab-in-indent" &&
724 echo " foo ();" >x &&
725 git diff --check
728 test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
729 git config core.whitespace "tab-in-indent" &&
730 echo " foo ();" >x &&
731 test_must_fail git diff --check
734 test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
735 git config core.whitespace "tab-in-indent" &&
736 echo " foo ();" >x &&
737 test_must_fail git diff --check
740 test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
741 git config core.whitespace "tab-in-indent,tabwidth=1" &&
742 test_must_fail git diff --check
745 test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
746 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
747 echo "foo ();" >x &&
748 test_must_fail git diff --check
751 test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
752 git config --unset core.whitespace &&
753 echo "x whitespace" >.gitattributes &&
754 echo " foo ();" >x &&
755 git diff --check &&
756 rm -f .gitattributes
759 test_expect_success 'line numbers in --check output are correct' '
760 echo "" >x &&
761 echo "foo(); " >>x &&
762 test_must_fail git diff --check >check &&
763 grep "x:2:" check
766 test_expect_success 'checkdiff detects new trailing blank lines (1)' '
767 echo "foo();" >x &&
768 echo "" >>x &&
769 test_must_fail git diff --check >check &&
770 grep "new blank line" check
773 test_expect_success 'checkdiff detects new trailing blank lines (2)' '
774 test_write_lines a b "" "" >x &&
775 git add x &&
776 test_write_lines a "" "" "" "" >x &&
777 test_must_fail git diff --check >check &&
778 grep "new blank line" check
781 test_expect_success 'checkdiff allows new blank lines' '
782 git checkout x &&
783 mv x y &&
785 echo "/* This is new */" &&
786 echo "" &&
787 cat y
788 ) >x &&
789 git diff --check
792 test_expect_success 'whitespace-only changes not reported (diff)' '
793 git reset --hard &&
794 echo >x "hello world" &&
795 git add x &&
796 git commit -m "hello 1" &&
797 echo >x "hello world" &&
798 git diff -b >actual &&
799 test_must_be_empty actual
802 test_expect_success 'whitespace-only changes not reported (diffstat)' '
803 # reuse state from previous test
804 git diff --stat -b >actual &&
805 test_must_be_empty actual
808 test_expect_success 'whitespace changes with modification reported (diffstat)' '
809 git reset --hard &&
810 echo >x "hello world" &&
811 git update-index --chmod=+x x &&
812 git diff --stat --cached -b >actual &&
813 cat <<-EOF >expect &&
814 x | 0
815 1 file changed, 0 insertions(+), 0 deletions(-)
817 test_cmp expect actual
820 test_expect_success 'whitespace-only changes reported across renames (diffstat)' '
821 git reset --hard &&
822 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
823 git add x &&
824 git commit -m "base" &&
825 sed -e "5s/^/ /" x >z &&
826 git rm x &&
827 git add z &&
828 git diff -w -M --cached --stat >actual &&
829 cat <<-EOF >expect &&
830 x => z | 0
831 1 file changed, 0 insertions(+), 0 deletions(-)
833 test_cmp expect actual
836 test_expect_success 'whitespace-only changes reported across renames' '
837 git reset --hard HEAD~1 &&
838 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
839 git add x &&
840 hash_x=$(git hash-object x) &&
841 before=$(git rev-parse --short "$hash_x") &&
842 git commit -m "base" &&
843 sed -e "5s/^/ /" x >z &&
844 git rm x &&
845 git add z &&
846 hash_z=$(git hash-object z) &&
847 after=$(git rev-parse --short "$hash_z") &&
848 git diff -w -M --cached >actual.raw &&
849 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" actual.raw >actual &&
850 cat <<-EOF >expect &&
851 diff --git a/x b/z
852 similarity index NUM%
853 rename from x
854 rename to z
855 index $before..$after 100644
857 test_cmp expect actual
860 cat >expected <<\EOF
861 diff --git a/empty b/void
862 similarity index 100%
863 rename from empty
864 rename to void
867 test_expect_success 'rename empty' '
868 git reset --hard &&
869 >empty &&
870 git add empty &&
871 git commit -m empty &&
872 git mv empty void &&
873 git diff -w --cached -M >current &&
874 test_cmp expected current
877 test_expect_success 'combined diff with autocrlf conversion' '
879 git reset --hard &&
880 echo >x hello &&
881 git commit -m "one side" x &&
882 git checkout HEAD^ &&
883 echo >x goodbye &&
884 git commit -m "the other side" x &&
885 git config core.autocrlf true &&
886 test_must_fail git merge master &&
888 git diff >actual.raw &&
889 sed -e "1,/^@@@/d" actual.raw >actual &&
890 ! grep "^-" actual
894 # Start testing the colored format for whitespace checks
896 test_expect_success 'setup diff colors' '
897 git config color.diff.plain normal &&
898 git config color.diff.meta bold &&
899 git config color.diff.frag cyan &&
900 git config color.diff.func normal &&
901 git config color.diff.old red &&
902 git config color.diff.new green &&
903 git config color.diff.commit yellow &&
904 git config color.diff.whitespace blue &&
906 git config core.autocrlf false
909 test_expect_success 'diff that introduces a line with only tabs' '
910 git config core.whitespace blank-at-eol &&
911 git reset --hard &&
912 echo "test" >x &&
913 old_hash_x=$(git hash-object x) &&
914 before=$(git rev-parse --short "$old_hash_x") &&
915 git commit -m "initial" x &&
916 echo "{NTN}" | tr "NT" "\n\t" >>x &&
917 new_hash_x=$(git hash-object x) &&
918 after=$(git rev-parse --short "$new_hash_x") &&
919 git diff --color >current.raw &&
920 test_decode_color <current.raw >current &&
922 cat >expected <<-EOF &&
923 <BOLD>diff --git a/x b/x<RESET>
924 <BOLD>index $before..$after 100644<RESET>
925 <BOLD>--- a/x<RESET>
926 <BOLD>+++ b/x<RESET>
927 <CYAN>@@ -1 +1,4 @@<RESET>
928 test<RESET>
929 <GREEN>+<RESET><GREEN>{<RESET>
930 <GREEN>+<RESET><BLUE> <RESET>
931 <GREEN>+<RESET><GREEN>}<RESET>
934 test_cmp expected current
937 test_expect_success 'diff that introduces and removes ws breakages' '
938 git reset --hard &&
940 echo "0. blank-at-eol " &&
941 echo "1. blank-at-eol "
942 } >x &&
943 old_hash_x=$(git hash-object x) &&
944 before=$(git rev-parse --short "$old_hash_x") &&
945 git commit -a --allow-empty -m preimage &&
947 echo "0. blank-at-eol " &&
948 echo "1. still-blank-at-eol " &&
949 echo "2. and a new line "
950 } >x &&
951 new_hash_x=$(git hash-object x) &&
952 after=$(git rev-parse --short "$new_hash_x") &&
954 git diff --color >current.raw &&
955 test_decode_color <current.raw >current &&
957 cat >expected <<-EOF &&
958 <BOLD>diff --git a/x b/x<RESET>
959 <BOLD>index $before..$after 100644<RESET>
960 <BOLD>--- a/x<RESET>
961 <BOLD>+++ b/x<RESET>
962 <CYAN>@@ -1,2 +1,3 @@<RESET>
963 0. blank-at-eol <RESET>
964 <RED>-1. blank-at-eol <RESET>
965 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
966 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
969 test_cmp expected current
972 test_expect_success 'ws-error-highlight test setup' '
974 git reset --hard &&
976 echo "0. blank-at-eol " &&
977 echo "1. blank-at-eol "
978 } >x &&
979 old_hash_x=$(git hash-object x) &&
980 before=$(git rev-parse --short "$old_hash_x") &&
981 git commit -a --allow-empty -m preimage &&
983 echo "0. blank-at-eol " &&
984 echo "1. still-blank-at-eol " &&
985 echo "2. and a new line "
986 } >x &&
987 new_hash_x=$(git hash-object x) &&
988 after=$(git rev-parse --short "$new_hash_x") &&
990 cat >expect.default-old <<-EOF &&
991 <BOLD>diff --git a/x b/x<RESET>
992 <BOLD>index $before..$after 100644<RESET>
993 <BOLD>--- a/x<RESET>
994 <BOLD>+++ b/x<RESET>
995 <CYAN>@@ -1,2 +1,3 @@<RESET>
996 0. blank-at-eol <RESET>
997 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
998 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
999 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1002 cat >expect.all <<-EOF &&
1003 <BOLD>diff --git a/x b/x<RESET>
1004 <BOLD>index $before..$after 100644<RESET>
1005 <BOLD>--- a/x<RESET>
1006 <BOLD>+++ b/x<RESET>
1007 <CYAN>@@ -1,2 +1,3 @@<RESET>
1008 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
1009 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1010 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1011 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1014 cat >expect.none <<-EOF
1015 <BOLD>diff --git a/x b/x<RESET>
1016 <BOLD>index $before..$after 100644<RESET>
1017 <BOLD>--- a/x<RESET>
1018 <BOLD>+++ b/x<RESET>
1019 <CYAN>@@ -1,2 +1,3 @@<RESET>
1020 0. blank-at-eol <RESET>
1021 <RED>-1. blank-at-eol <RESET>
1022 <GREEN>+1. still-blank-at-eol <RESET>
1023 <GREEN>+2. and a new line <RESET>
1028 test_expect_success 'test --ws-error-highlight option' '
1030 git diff --color --ws-error-highlight=default,old >current.raw &&
1031 test_decode_color <current.raw >current &&
1032 test_cmp expect.default-old current &&
1034 git diff --color --ws-error-highlight=all >current.raw &&
1035 test_decode_color <current.raw >current &&
1036 test_cmp expect.all current &&
1038 git diff --color --ws-error-highlight=none >current.raw &&
1039 test_decode_color <current.raw >current &&
1040 test_cmp expect.none current
1044 test_expect_success 'test diff.wsErrorHighlight config' '
1046 git -c diff.wsErrorHighlight=default,old diff --color >current.raw &&
1047 test_decode_color <current.raw >current &&
1048 test_cmp expect.default-old current &&
1050 git -c diff.wsErrorHighlight=all diff --color >current.raw &&
1051 test_decode_color <current.raw >current &&
1052 test_cmp expect.all current &&
1054 git -c diff.wsErrorHighlight=none diff --color >current.raw &&
1055 test_decode_color <current.raw >current &&
1056 test_cmp expect.none current
1060 test_expect_success 'option overrides diff.wsErrorHighlight' '
1062 git -c diff.wsErrorHighlight=none \
1063 diff --color --ws-error-highlight=default,old >current.raw &&
1064 test_decode_color <current.raw >current &&
1065 test_cmp expect.default-old current &&
1067 git -c diff.wsErrorHighlight=default \
1068 diff --color --ws-error-highlight=all >current.raw &&
1069 test_decode_color <current.raw >current &&
1070 test_cmp expect.all current &&
1072 git -c diff.wsErrorHighlight=all \
1073 diff --color --ws-error-highlight=none >current.raw &&
1074 test_decode_color <current.raw >current &&
1075 test_cmp expect.none current
1079 test_expect_success 'detect moved code, complete file' '
1080 git reset --hard &&
1081 cat <<-\EOF >test.c &&
1082 #include<stdio.h>
1083 main()
1085 printf("Hello World");
1088 git add test.c &&
1089 git commit -m "add main function" &&
1090 file=$(git rev-parse --short HEAD:test.c) &&
1091 git mv test.c main.c &&
1092 test_config color.diff.oldMoved "normal red" &&
1093 test_config color.diff.newMoved "normal green" &&
1094 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1095 test_decode_color <actual.raw >actual &&
1096 cat >expected <<-EOF &&
1097 <BOLD>diff --git a/main.c b/main.c<RESET>
1098 <BOLD>new file mode 100644<RESET>
1099 <BOLD>index 0000000..$file<RESET>
1100 <BOLD>--- /dev/null<RESET>
1101 <BOLD>+++ b/main.c<RESET>
1102 <CYAN>@@ -0,0 +1,5 @@<RESET>
1103 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1104 <BGREEN>+<RESET><BGREEN>main()<RESET>
1105 <BGREEN>+<RESET><BGREEN>{<RESET>
1106 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1107 <BGREEN>+<RESET><BGREEN>}<RESET>
1108 <BOLD>diff --git a/test.c b/test.c<RESET>
1109 <BOLD>deleted file mode 100644<RESET>
1110 <BOLD>index $file..0000000<RESET>
1111 <BOLD>--- a/test.c<RESET>
1112 <BOLD>+++ /dev/null<RESET>
1113 <CYAN>@@ -1,5 +0,0 @@<RESET>
1114 <BRED>-#include<stdio.h><RESET>
1115 <BRED>-main()<RESET>
1116 <BRED>-{<RESET>
1117 <BRED>-printf("Hello World");<RESET>
1118 <BRED>-}<RESET>
1121 test_cmp expected actual
1124 test_expect_success 'detect malicious moved code, inside file' '
1125 test_config color.diff.oldMoved "normal red" &&
1126 test_config color.diff.newMoved "normal green" &&
1127 test_config color.diff.oldMovedAlternative "blue" &&
1128 test_config color.diff.newMovedAlternative "yellow" &&
1129 git reset --hard &&
1130 cat <<-\EOF >main.c &&
1131 #include<stdio.h>
1132 int stuff()
1134 printf("Hello ");
1135 printf("World\n");
1138 int secure_foo(struct user *u)
1140 if (!u->is_allowed_foo)
1141 return;
1142 foo(u);
1145 int main()
1147 foo();
1150 cat <<-\EOF >test.c &&
1151 #include<stdio.h>
1152 int bar()
1154 printf("Hello World, but different\n");
1157 int another_function()
1159 bar();
1162 git add main.c test.c &&
1163 git commit -m "add main and test file" &&
1164 before_main=$(git rev-parse --short HEAD:main.c) &&
1165 before_test=$(git rev-parse --short HEAD:test.c) &&
1166 cat <<-\EOF >main.c &&
1167 #include<stdio.h>
1168 int stuff()
1170 printf("Hello ");
1171 printf("World\n");
1174 int main()
1176 foo();
1179 cat <<-\EOF >test.c &&
1180 #include<stdio.h>
1181 int bar()
1183 printf("Hello World, but different\n");
1186 int secure_foo(struct user *u)
1188 foo(u);
1189 if (!u->is_allowed_foo)
1190 return;
1193 int another_function()
1195 bar();
1198 hash_main=$(git hash-object main.c) &&
1199 after_main=$(git rev-parse --short "$hash_main") &&
1200 hash_test=$(git hash-object test.c) &&
1201 after_test=$(git rev-parse --short "$hash_test") &&
1202 git diff HEAD --no-renames --color-moved=zebra --color >actual.raw &&
1203 test_decode_color <actual.raw >actual &&
1204 cat <<-EOF >expected &&
1205 <BOLD>diff --git a/main.c b/main.c<RESET>
1206 <BOLD>index $before_main..$after_main 100644<RESET>
1207 <BOLD>--- a/main.c<RESET>
1208 <BOLD>+++ b/main.c<RESET>
1209 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1210 printf("World\n");<RESET>
1211 }<RESET>
1212 <RESET>
1213 <BRED>-int secure_foo(struct user *u)<RESET>
1214 <BRED>-{<RESET>
1215 <BLUE>-if (!u->is_allowed_foo)<RESET>
1216 <BLUE>-return;<RESET>
1217 <RED>-foo(u);<RESET>
1218 <RED>-}<RESET>
1219 <RED>-<RESET>
1220 int main()<RESET>
1221 {<RESET>
1222 foo();<RESET>
1223 <BOLD>diff --git a/test.c b/test.c<RESET>
1224 <BOLD>index $before_test..$after_test 100644<RESET>
1225 <BOLD>--- a/test.c<RESET>
1226 <BOLD>+++ b/test.c<RESET>
1227 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1228 printf("Hello World, but different\n");<RESET>
1229 }<RESET>
1230 <RESET>
1231 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1232 <BGREEN>+<RESET><BGREEN>{<RESET>
1233 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1234 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1235 <BGREEN>+<RESET><BGREEN>return;<RESET>
1236 <GREEN>+<RESET><GREEN>}<RESET>
1237 <GREEN>+<RESET>
1238 int another_function()<RESET>
1239 {<RESET>
1240 bar();<RESET>
1243 test_cmp expected actual
1246 test_expect_success 'plain moved code, inside file' '
1247 test_config color.diff.oldMoved "normal red" &&
1248 test_config color.diff.newMoved "normal green" &&
1249 test_config color.diff.oldMovedAlternative "blue" &&
1250 test_config color.diff.newMovedAlternative "yellow" &&
1251 # needs previous test as setup
1252 git diff HEAD --no-renames --color-moved=plain --color >actual.raw &&
1253 test_decode_color <actual.raw >actual &&
1254 cat <<-EOF >expected &&
1255 <BOLD>diff --git a/main.c b/main.c<RESET>
1256 <BOLD>index $before_main..$after_main 100644<RESET>
1257 <BOLD>--- a/main.c<RESET>
1258 <BOLD>+++ b/main.c<RESET>
1259 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1260 printf("World\n");<RESET>
1261 }<RESET>
1262 <RESET>
1263 <BRED>-int secure_foo(struct user *u)<RESET>
1264 <BRED>-{<RESET>
1265 <BRED>-if (!u->is_allowed_foo)<RESET>
1266 <BRED>-return;<RESET>
1267 <BRED>-foo(u);<RESET>
1268 <BRED>-}<RESET>
1269 <BRED>-<RESET>
1270 int main()<RESET>
1271 {<RESET>
1272 foo();<RESET>
1273 <BOLD>diff --git a/test.c b/test.c<RESET>
1274 <BOLD>index $before_test..$after_test 100644<RESET>
1275 <BOLD>--- a/test.c<RESET>
1276 <BOLD>+++ b/test.c<RESET>
1277 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1278 printf("Hello World, but different\n");<RESET>
1279 }<RESET>
1280 <RESET>
1281 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1282 <BGREEN>+<RESET><BGREEN>{<RESET>
1283 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1284 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1285 <BGREEN>+<RESET><BGREEN>return;<RESET>
1286 <BGREEN>+<RESET><BGREEN>}<RESET>
1287 <BGREEN>+<RESET>
1288 int another_function()<RESET>
1289 {<RESET>
1290 bar();<RESET>
1293 test_cmp expected actual
1296 test_expect_success 'detect blocks of moved code' '
1297 git reset --hard &&
1298 cat <<-\EOF >lines.txt &&
1299 long line 1
1300 long line 2
1301 long line 3
1302 line 4
1303 line 5
1304 line 6
1305 line 7
1306 line 8
1307 line 9
1308 line 10
1309 line 11
1310 line 12
1311 line 13
1312 long line 14
1313 long line 15
1314 long line 16
1316 git add lines.txt &&
1317 git commit -m "add poetry" &&
1318 cat <<-\EOF >lines.txt &&
1319 line 4
1320 line 5
1321 line 6
1322 line 7
1323 line 8
1324 line 9
1325 long line 1
1326 long line 2
1327 long line 3
1328 long line 14
1329 long line 15
1330 long line 16
1331 line 10
1332 line 11
1333 line 12
1334 line 13
1336 test_config color.diff.oldMoved "magenta" &&
1337 test_config color.diff.newMoved "cyan" &&
1338 test_config color.diff.oldMovedAlternative "blue" &&
1339 test_config color.diff.newMovedAlternative "yellow" &&
1340 test_config color.diff.oldMovedDimmed "normal magenta" &&
1341 test_config color.diff.newMovedDimmed "normal cyan" &&
1342 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1343 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1344 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1345 grep -v "index" actual.raw | test_decode_color >actual &&
1346 cat <<-\EOF >expected &&
1347 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1348 <BOLD>--- a/lines.txt<RESET>
1349 <BOLD>+++ b/lines.txt<RESET>
1350 <CYAN>@@ -1,16 +1,16 @@<RESET>
1351 <MAGENTA>-long line 1<RESET>
1352 <MAGENTA>-long line 2<RESET>
1353 <MAGENTA>-long line 3<RESET>
1354 line 4<RESET>
1355 line 5<RESET>
1356 line 6<RESET>
1357 line 7<RESET>
1358 line 8<RESET>
1359 line 9<RESET>
1360 <CYAN>+<RESET><CYAN>long line 1<RESET>
1361 <CYAN>+<RESET><CYAN>long line 2<RESET>
1362 <CYAN>+<RESET><CYAN>long line 3<RESET>
1363 <CYAN>+<RESET><CYAN>long line 14<RESET>
1364 <CYAN>+<RESET><CYAN>long line 15<RESET>
1365 <CYAN>+<RESET><CYAN>long line 16<RESET>
1366 line 10<RESET>
1367 line 11<RESET>
1368 line 12<RESET>
1369 line 13<RESET>
1370 <MAGENTA>-long line 14<RESET>
1371 <MAGENTA>-long line 15<RESET>
1372 <MAGENTA>-long line 16<RESET>
1374 test_cmp expected actual
1378 test_expect_success 'detect permutations inside moved code -- dimmed-zebra' '
1379 # reuse setup from test before!
1380 test_config color.diff.oldMoved "magenta" &&
1381 test_config color.diff.newMoved "cyan" &&
1382 test_config color.diff.oldMovedAlternative "blue" &&
1383 test_config color.diff.newMovedAlternative "yellow" &&
1384 test_config color.diff.oldMovedDimmed "normal magenta" &&
1385 test_config color.diff.newMovedDimmed "normal cyan" &&
1386 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1387 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1388 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1389 grep -v "index" actual.raw | test_decode_color >actual &&
1390 cat <<-\EOF >expected &&
1391 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1392 <BOLD>--- a/lines.txt<RESET>
1393 <BOLD>+++ b/lines.txt<RESET>
1394 <CYAN>@@ -1,16 +1,16 @@<RESET>
1395 <BMAGENTA>-long line 1<RESET>
1396 <BMAGENTA>-long line 2<RESET>
1397 <BMAGENTA>-long line 3<RESET>
1398 line 4<RESET>
1399 line 5<RESET>
1400 line 6<RESET>
1401 line 7<RESET>
1402 line 8<RESET>
1403 line 9<RESET>
1404 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1405 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1406 <CYAN>+<RESET><CYAN>long line 3<RESET>
1407 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1408 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1409 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1410 line 10<RESET>
1411 line 11<RESET>
1412 line 12<RESET>
1413 line 13<RESET>
1414 <BMAGENTA>-long line 14<RESET>
1415 <BMAGENTA>-long line 15<RESET>
1416 <BMAGENTA>-long line 16<RESET>
1418 test_cmp expected actual
1421 test_expect_success 'cmd option assumes configured colored-moved' '
1422 test_config color.diff.oldMoved "magenta" &&
1423 test_config color.diff.newMoved "cyan" &&
1424 test_config color.diff.oldMovedAlternative "blue" &&
1425 test_config color.diff.newMovedAlternative "yellow" &&
1426 test_config color.diff.oldMovedDimmed "normal magenta" &&
1427 test_config color.diff.newMovedDimmed "normal cyan" &&
1428 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1429 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1430 test_config diff.colorMoved zebra &&
1431 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1432 grep -v "index" actual.raw | test_decode_color >actual &&
1433 cat <<-\EOF >expected &&
1434 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1435 <BOLD>--- a/lines.txt<RESET>
1436 <BOLD>+++ b/lines.txt<RESET>
1437 <CYAN>@@ -1,16 +1,16 @@<RESET>
1438 <MAGENTA>-long line 1<RESET>
1439 <MAGENTA>-long line 2<RESET>
1440 <MAGENTA>-long line 3<RESET>
1441 line 4<RESET>
1442 line 5<RESET>
1443 line 6<RESET>
1444 line 7<RESET>
1445 line 8<RESET>
1446 line 9<RESET>
1447 <CYAN>+<RESET><CYAN>long line 1<RESET>
1448 <CYAN>+<RESET><CYAN>long line 2<RESET>
1449 <CYAN>+<RESET><CYAN>long line 3<RESET>
1450 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1451 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1452 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1453 line 10<RESET>
1454 line 11<RESET>
1455 line 12<RESET>
1456 line 13<RESET>
1457 <MAGENTA>-long line 14<RESET>
1458 <MAGENTA>-long line 15<RESET>
1459 <MAGENTA>-long line 16<RESET>
1461 test_cmp expected actual
1464 test_expect_success 'no effect from --color-moved with --word-diff' '
1465 cat <<-\EOF >text.txt &&
1466 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1468 git add text.txt &&
1469 git commit -a -m "clean state" &&
1470 cat <<-\EOF >text.txt &&
1471 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1473 git diff --color-moved --word-diff >actual &&
1474 git diff --word-diff >expect &&
1475 test_cmp expect actual
1478 test_expect_success 'set up whitespace tests' '
1479 git reset --hard &&
1480 # Note that these lines have no leading or trailing whitespace.
1481 cat <<-\EOF >lines.txt &&
1482 line 1
1483 line 2
1484 line 3
1485 line 4
1486 line 5
1487 long line 6
1488 long line 7
1489 long line 8
1490 long line 9
1492 git add lines.txt &&
1493 git commit -m "add poetry" &&
1494 git config color.diff.oldMoved "magenta" &&
1495 git config color.diff.newMoved "cyan"
1498 test_expect_success 'move detection ignoring whitespace ' '
1499 q_to_tab <<-\EOF >lines.txt &&
1500 Qlong line 6
1501 Qlong line 7
1502 Qlong line 8
1503 Qchanged long line 9
1504 line 1
1505 line 2
1506 line 3
1507 line 4
1508 line 5
1510 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1511 grep -v "index" actual.raw | test_decode_color >actual &&
1512 cat <<-\EOF >expected &&
1513 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1514 <BOLD>--- a/lines.txt<RESET>
1515 <BOLD>+++ b/lines.txt<RESET>
1516 <CYAN>@@ -1,9 +1,9 @@<RESET>
1517 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1518 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1519 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1520 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1521 line 1<RESET>
1522 line 2<RESET>
1523 line 3<RESET>
1524 line 4<RESET>
1525 line 5<RESET>
1526 <RED>-long line 6<RESET>
1527 <RED>-long line 7<RESET>
1528 <RED>-long line 8<RESET>
1529 <RED>-long line 9<RESET>
1531 test_cmp expected actual &&
1533 git diff HEAD --no-renames --color-moved --color \
1534 --color-moved-ws=ignore-all-space >actual.raw &&
1535 grep -v "index" actual.raw | test_decode_color >actual &&
1536 cat <<-\EOF >expected &&
1537 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1538 <BOLD>--- a/lines.txt<RESET>
1539 <BOLD>+++ b/lines.txt<RESET>
1540 <CYAN>@@ -1,9 +1,9 @@<RESET>
1541 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1542 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1543 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1544 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1545 line 1<RESET>
1546 line 2<RESET>
1547 line 3<RESET>
1548 line 4<RESET>
1549 line 5<RESET>
1550 <MAGENTA>-long line 6<RESET>
1551 <MAGENTA>-long line 7<RESET>
1552 <MAGENTA>-long line 8<RESET>
1553 <RED>-long line 9<RESET>
1555 test_cmp expected actual
1558 test_expect_success 'move detection ignoring whitespace changes' '
1559 git reset --hard &&
1560 # Lines 6-8 have a space change, but 9 is new whitespace
1561 q_to_tab <<-\EOF >lines.txt &&
1562 longQline 6
1563 longQline 7
1564 longQline 8
1565 long liQne 9
1566 line 1
1567 line 2
1568 line 3
1569 line 4
1570 line 5
1573 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1574 grep -v "index" actual.raw | test_decode_color >actual &&
1575 cat <<-\EOF >expected &&
1576 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1577 <BOLD>--- a/lines.txt<RESET>
1578 <BOLD>+++ b/lines.txt<RESET>
1579 <CYAN>@@ -1,9 +1,9 @@<RESET>
1580 <GREEN>+<RESET><GREEN>long line 6<RESET>
1581 <GREEN>+<RESET><GREEN>long line 7<RESET>
1582 <GREEN>+<RESET><GREEN>long line 8<RESET>
1583 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1584 line 1<RESET>
1585 line 2<RESET>
1586 line 3<RESET>
1587 line 4<RESET>
1588 line 5<RESET>
1589 <RED>-long line 6<RESET>
1590 <RED>-long line 7<RESET>
1591 <RED>-long line 8<RESET>
1592 <RED>-long line 9<RESET>
1594 test_cmp expected actual &&
1596 git diff HEAD --no-renames --color-moved --color \
1597 --color-moved-ws=ignore-space-change >actual.raw &&
1598 grep -v "index" actual.raw | test_decode_color >actual &&
1599 cat <<-\EOF >expected &&
1600 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1601 <BOLD>--- a/lines.txt<RESET>
1602 <BOLD>+++ b/lines.txt<RESET>
1603 <CYAN>@@ -1,9 +1,9 @@<RESET>
1604 <CYAN>+<RESET><CYAN>long line 6<RESET>
1605 <CYAN>+<RESET><CYAN>long line 7<RESET>
1606 <CYAN>+<RESET><CYAN>long line 8<RESET>
1607 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1608 line 1<RESET>
1609 line 2<RESET>
1610 line 3<RESET>
1611 line 4<RESET>
1612 line 5<RESET>
1613 <MAGENTA>-long line 6<RESET>
1614 <MAGENTA>-long line 7<RESET>
1615 <MAGENTA>-long line 8<RESET>
1616 <RED>-long line 9<RESET>
1618 test_cmp expected actual
1621 test_expect_success 'move detection ignoring whitespace at eol' '
1622 git reset --hard &&
1623 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1624 q_to_tab <<-\EOF >lines.txt &&
1625 long line 6Q
1626 long line 7Q
1627 long line 8Q
1628 longQline 9Q
1629 line 1
1630 line 2
1631 line 3
1632 line 4
1633 line 5
1636 # avoid cluttering the output with complaints about our eol whitespace
1637 test_config core.whitespace -blank-at-eol &&
1639 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1640 grep -v "index" actual.raw | test_decode_color >actual &&
1641 cat <<-\EOF >expected &&
1642 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1643 <BOLD>--- a/lines.txt<RESET>
1644 <BOLD>+++ b/lines.txt<RESET>
1645 <CYAN>@@ -1,9 +1,9 @@<RESET>
1646 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1647 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1648 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1649 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1650 line 1<RESET>
1651 line 2<RESET>
1652 line 3<RESET>
1653 line 4<RESET>
1654 line 5<RESET>
1655 <RED>-long line 6<RESET>
1656 <RED>-long line 7<RESET>
1657 <RED>-long line 8<RESET>
1658 <RED>-long line 9<RESET>
1660 test_cmp expected actual &&
1662 git diff HEAD --no-renames --color-moved --color \
1663 --color-moved-ws=ignore-space-at-eol >actual.raw &&
1664 grep -v "index" actual.raw | test_decode_color >actual &&
1665 cat <<-\EOF >expected &&
1666 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1667 <BOLD>--- a/lines.txt<RESET>
1668 <BOLD>+++ b/lines.txt<RESET>
1669 <CYAN>@@ -1,9 +1,9 @@<RESET>
1670 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1671 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1672 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1673 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1674 line 1<RESET>
1675 line 2<RESET>
1676 line 3<RESET>
1677 line 4<RESET>
1678 line 5<RESET>
1679 <MAGENTA>-long line 6<RESET>
1680 <MAGENTA>-long line 7<RESET>
1681 <MAGENTA>-long line 8<RESET>
1682 <RED>-long line 9<RESET>
1684 test_cmp expected actual
1687 test_expect_success 'clean up whitespace-test colors' '
1688 git config --unset color.diff.oldMoved &&
1689 git config --unset color.diff.newMoved
1692 test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1693 git reset --hard &&
1694 >bar &&
1695 cat <<-\EOF >foo &&
1696 irrelevant_line
1697 line1
1699 git add foo bar &&
1700 git commit -m x &&
1702 cat <<-\EOF >bar &&
1703 line1
1705 cat <<-\EOF >foo &&
1706 irrelevant_line
1709 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1710 grep -v "index" actual.raw | test_decode_color >actual &&
1711 cat >expected <<-\EOF &&
1712 <BOLD>diff --git a/bar b/bar<RESET>
1713 <BOLD>--- a/bar<RESET>
1714 <BOLD>+++ b/bar<RESET>
1715 <CYAN>@@ -0,0 +1 @@<RESET>
1716 <GREEN>+<RESET><GREEN>line1<RESET>
1717 <BOLD>diff --git a/foo b/foo<RESET>
1718 <BOLD>--- a/foo<RESET>
1719 <BOLD>+++ b/foo<RESET>
1720 <CYAN>@@ -1,2 +1 @@<RESET>
1721 irrelevant_line<RESET>
1722 <RED>-line1<RESET>
1725 test_cmp expected actual
1728 test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
1729 git reset --hard &&
1730 cat <<-\EOF >foo &&
1731 nineteen chars 456789
1732 irrelevant_line
1733 twenty chars 234567890
1735 >bar &&
1736 git add foo bar &&
1737 git commit -m x &&
1739 cat <<-\EOF >foo &&
1740 irrelevant_line
1742 cat <<-\EOF >bar &&
1743 twenty chars 234567890
1744 nineteen chars 456789
1747 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1748 grep -v "index" actual.raw | test_decode_color >actual &&
1749 cat >expected <<-\EOF &&
1750 <BOLD>diff --git a/bar b/bar<RESET>
1751 <BOLD>--- a/bar<RESET>
1752 <BOLD>+++ b/bar<RESET>
1753 <CYAN>@@ -0,0 +1,2 @@<RESET>
1754 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1755 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1756 <BOLD>diff --git a/foo b/foo<RESET>
1757 <BOLD>--- a/foo<RESET>
1758 <BOLD>+++ b/foo<RESET>
1759 <CYAN>@@ -1,3 +1 @@<RESET>
1760 <RED>-nineteen chars 456789<RESET>
1761 irrelevant_line<RESET>
1762 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1765 test_cmp expected actual
1768 test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1769 git reset --hard &&
1770 cat <<-\EOF >foo &&
1771 7charsA
1772 irrelevant_line
1773 7charsB
1774 7charsC
1776 >bar &&
1777 git add foo bar &&
1778 git commit -m x &&
1780 cat <<-\EOF >foo &&
1781 irrelevant_line
1783 cat <<-\EOF >bar &&
1784 7charsB
1785 7charsC
1786 7charsA
1789 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1790 grep -v "index" actual.raw | test_decode_color >actual &&
1791 cat >expected <<-\EOF &&
1792 <BOLD>diff --git a/bar b/bar<RESET>
1793 <BOLD>--- a/bar<RESET>
1794 <BOLD>+++ b/bar<RESET>
1795 <CYAN>@@ -0,0 +1,3 @@<RESET>
1796 <GREEN>+<RESET><GREEN>7charsB<RESET>
1797 <GREEN>+<RESET><GREEN>7charsC<RESET>
1798 <GREEN>+<RESET><GREEN>7charsA<RESET>
1799 <BOLD>diff --git a/foo b/foo<RESET>
1800 <BOLD>--- a/foo<RESET>
1801 <BOLD>+++ b/foo<RESET>
1802 <CYAN>@@ -1,4 +1 @@<RESET>
1803 <RED>-7charsA<RESET>
1804 irrelevant_line<RESET>
1805 <RED>-7charsB<RESET>
1806 <RED>-7charsC<RESET>
1809 test_cmp expected actual
1812 test_expect_success 'move detection with submodules' '
1813 test_create_repo bananas &&
1814 echo ripe >bananas/recipe &&
1815 git -C bananas add recipe &&
1816 test_commit fruit &&
1817 test_commit -C bananas recipe &&
1818 git submodule add ./bananas &&
1819 git add bananas &&
1820 git commit -a -m "bananas are like a heavy library?" &&
1821 echo foul >bananas/recipe &&
1822 echo ripe >fruit.t &&
1824 git diff --submodule=diff --color-moved --color >actual &&
1826 # no move detection as the moved line is across repository boundaries.
1827 test_decode_color <actual >decoded_actual &&
1828 ! grep BGREEN decoded_actual &&
1829 ! grep BRED decoded_actual &&
1831 # nor did we mess with it another way
1832 git diff --submodule=diff --color >expect.raw &&
1833 test_decode_color <expect.raw >expect &&
1834 test_cmp expect decoded_actual &&
1835 rm -rf bananas &&
1836 git submodule deinit bananas
1839 test_expect_success 'only move detection ignores white spaces' '
1840 git reset --hard &&
1841 q_to_tab <<-\EOF >text.txt &&
1842 a long line to exceed per-line minimum
1843 another long line to exceed per-line minimum
1844 original file
1846 git add text.txt &&
1847 git commit -m "add text" &&
1848 q_to_tab <<-\EOF >text.txt &&
1849 Qa long line to exceed per-line minimum
1850 Qanother long line to exceed per-line minimum
1851 new file
1854 # Make sure we get a different diff using -w
1855 git diff --color --color-moved -w >actual.raw &&
1856 grep -v "index" actual.raw | test_decode_color >actual &&
1857 q_to_tab <<-\EOF >expected &&
1858 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1859 <BOLD>--- a/text.txt<RESET>
1860 <BOLD>+++ b/text.txt<RESET>
1861 <CYAN>@@ -1,3 +1,3 @@<RESET>
1862 Qa long line to exceed per-line minimum<RESET>
1863 Qanother long line to exceed per-line minimum<RESET>
1864 <RED>-original file<RESET>
1865 <GREEN>+<RESET><GREEN>new file<RESET>
1867 test_cmp expected actual &&
1869 # And now ignoring white space only in the move detection
1870 git diff --color --color-moved \
1871 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
1872 grep -v "index" actual.raw | test_decode_color >actual &&
1873 q_to_tab <<-\EOF >expected &&
1874 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1875 <BOLD>--- a/text.txt<RESET>
1876 <BOLD>+++ b/text.txt<RESET>
1877 <CYAN>@@ -1,3 +1,3 @@<RESET>
1878 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
1879 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
1880 <RED>-original file<RESET>
1881 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>a long line to exceed per-line minimum<RESET>
1882 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>another long line to exceed per-line minimum<RESET>
1883 <GREEN>+<RESET><GREEN>new file<RESET>
1885 test_cmp expected actual
1888 test_expect_success 'compare whitespace delta across moved blocks' '
1890 git reset --hard &&
1891 q_to_tab <<-\EOF >text.txt &&
1892 QIndented
1893 QText across
1894 Qsome lines
1895 QBut! <- this stands out
1896 QAdjusting with
1897 QQdifferent starting
1898 Qwhite spaces
1899 QAnother outlier
1900 QQQIndented
1901 QQQText across
1902 QQQfive lines
1903 QQQthat has similar lines
1904 QQQto previous blocks, but with different indent
1905 QQQYetQAnotherQoutlierQ
1906 QLine with internal w h i t e s p a c e change
1909 git add text.txt &&
1910 git commit -m "add text.txt" &&
1912 q_to_tab <<-\EOF >text.txt &&
1913 QQIndented
1914 QQText across
1915 QQsome lines
1916 QQQBut! <- this stands out
1917 Adjusting with
1918 Qdifferent starting
1919 white spaces
1920 AnotherQoutlier
1921 QQIndented
1922 QQText across
1923 QQfive lines
1924 QQthat has similar lines
1925 QQto previous blocks, but with different indent
1926 QQYetQAnotherQoutlier
1927 QLine with internal whitespace change
1930 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
1931 grep -v "index" actual.raw | test_decode_color >actual &&
1933 q_to_tab <<-\EOF >expected &&
1934 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1935 <BOLD>--- a/text.txt<RESET>
1936 <BOLD>+++ b/text.txt<RESET>
1937 <CYAN>@@ -1,15 +1,15 @@<RESET>
1938 <BOLD;MAGENTA>-QIndented<RESET>
1939 <BOLD;MAGENTA>-QText across<RESET>
1940 <BOLD;MAGENTA>-Qsome lines<RESET>
1941 <RED>-QBut! <- this stands out<RESET>
1942 <BOLD;MAGENTA>-QAdjusting with<RESET>
1943 <BOLD;MAGENTA>-QQdifferent starting<RESET>
1944 <BOLD;MAGENTA>-Qwhite spaces<RESET>
1945 <RED>-QAnother outlier<RESET>
1946 <BOLD;MAGENTA>-QQQIndented<RESET>
1947 <BOLD;MAGENTA>-QQQText across<RESET>
1948 <BOLD;MAGENTA>-QQQfive lines<RESET>
1949 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
1950 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
1951 <RED>-QQQYetQAnotherQoutlierQ<RESET>
1952 <RED>-QLine with internal w h i t e s p a c e change<RESET>
1953 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1954 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1955 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
1956 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
1957 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
1958 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
1959 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
1960 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
1961 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1962 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1963 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
1964 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
1965 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
1966 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
1967 <GREEN>+<RESET>Q<GREEN>Line with internal whitespace change<RESET>
1970 test_cmp expected actual
1973 test_expect_success 'bogus settings in move detection erroring out' '
1974 test_must_fail git diff --color-moved=bogus 2>err &&
1975 test_i18ngrep "must be one of" err &&
1976 test_i18ngrep bogus err &&
1978 test_must_fail git -c diff.colormoved=bogus diff 2>err &&
1979 test_i18ngrep "must be one of" err &&
1980 test_i18ngrep "from command-line config" err &&
1982 test_must_fail git diff --color-moved-ws=bogus 2>err &&
1983 test_i18ngrep "possible values" err &&
1984 test_i18ngrep bogus err &&
1986 test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
1987 test_i18ngrep "possible values" err &&
1988 test_i18ngrep "from command-line config" err
1991 test_expect_success 'compare whitespace delta incompatible with other space options' '
1992 test_must_fail git diff \
1993 --color-moved-ws=allow-indentation-change,ignore-all-space \
1994 2>err &&
1995 test_i18ngrep allow-indentation-change err
1998 EMPTY=''
1999 test_expect_success 'compare mixed whitespace delta across moved blocks' '
2001 git reset --hard &&
2002 tr Q_ "\t " <<-EOF >text.txt &&
2003 ${EMPTY}
2004 ____too short without
2005 ${EMPTY}
2006 ___being grouped across blank line
2007 ${EMPTY}
2008 context
2009 lines
2011 anchor
2012 ____Indented text to
2013 _Q____be further indented by four spaces across
2014 ____Qseveral lines
2015 QQ____These two lines have had their
2016 ____indentation reduced by four spaces
2017 Qdifferent indentation change
2018 ____too short
2021 git add text.txt &&
2022 git commit -m "add text.txt" &&
2024 tr Q_ "\t " <<-EOF >text.txt &&
2025 context
2026 lines
2028 anchor
2029 QIndented text to
2030 QQbe further indented by four spaces across
2031 Q____several lines
2032 ${EMPTY}
2033 QQtoo short without
2034 ${EMPTY}
2035 Q_______being grouped across blank line
2036 ${EMPTY}
2037 Q_QThese two lines have had their
2038 indentation reduced by four spaces
2039 QQdifferent indentation change
2040 __Qtoo short
2043 git -c color.diff.whitespace="normal red" \
2044 -c core.whitespace=space-before-tab \
2045 diff --color --color-moved --ws-error-highlight=all \
2046 --color-moved-ws=allow-indentation-change >actual.raw &&
2047 grep -v "index" actual.raw | test_decode_color >actual &&
2049 cat <<-\EOF >expected &&
2050 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2051 <BOLD>--- a/text.txt<RESET>
2052 <BOLD>+++ b/text.txt<RESET>
2053 <CYAN>@@ -1,16 +1,16 @@<RESET>
2054 <BOLD;MAGENTA>-<RESET>
2055 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> too short without<RESET>
2056 <BOLD;MAGENTA>-<RESET>
2057 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
2058 <BOLD;MAGENTA>-<RESET>
2059 <RESET>context<RESET>
2060 <RESET>lines<RESET>
2061 <RESET>to<RESET>
2062 <RESET>anchor<RESET>
2063 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
2064 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
2065 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
2066 <BOLD;BLUE>-<RESET> <BOLD;BLUE> These two lines have had their<RESET>
2067 <BOLD;BLUE>-<RESET><BOLD;BLUE> indentation reduced by four spaces<RESET>
2068 <BOLD;MAGENTA>-<RESET> <BOLD;MAGENTA>different indentation change<RESET>
2069 <RED>-<RESET><RED> too short<RESET>
2070 <BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
2071 <BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
2072 <BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
2073 <BOLD;YELLOW>+<RESET>
2074 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
2075 <BOLD;YELLOW>+<RESET>
2076 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW> being grouped across blank line<RESET>
2077 <BOLD;YELLOW>+<RESET>
2078 <BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
2079 <BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
2080 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
2081 <GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
2084 test_cmp expected actual
2087 test_expect_success 'combine --ignore-blank-lines with --function-context' '
2088 test_write_lines 1 "" 2 3 4 5 >a &&
2089 test_write_lines 1 2 3 4 >b &&
2090 test_must_fail git diff --no-index \
2091 --ignore-blank-lines --function-context a b >actual.raw &&
2092 sed -n "/@@/,\$p" <actual.raw >actual &&
2093 cat <<-\EOF >expect &&
2094 @@ -1,6 +1,4 @@
2102 test_cmp expect actual
2105 test_expect_success 'combine --ignore-blank-lines with --function-context 2' '
2106 test_write_lines a b c "" function 1 2 3 4 5 "" 6 7 8 9 >a &&
2107 test_write_lines "" a b c "" function 1 2 3 4 5 6 7 8 >b &&
2108 test_must_fail git diff --no-index \
2109 --ignore-blank-lines --function-context a b >actual.raw &&
2110 sed -n "/@@/,\$p" <actual.raw >actual &&
2111 cat <<-\EOF >expect &&
2112 @@ -5,11 +6,9 @@ c
2113 function
2125 test_cmp expect actual
2128 test_done