1#!/bin/sh
2#
3# Copyright (c) 2006 Johannes E. Schindelin
4#
5
6test_description='Test special whitespace in diff engine.
7
8'
9. ./test-lib.sh
10. "$TEST_DIRECTORY"/diff-lib.sh
11
12test_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
20 cat <<-\EOF >x &&
21 do
22 {
23 nothing;
24 }
25 while (0);
26 EOF
27
28 cat <<-\EOF >expect &&
29 diff --git a/x b/x
30 index adf3937..6edc172 100644
31 --- a/x
32 +++ b/x
33 @@ -1,3 +1,5 @@
34 -do {
35 +do
36 +{
37 nothing;
38 -} while (0);
39 +}
40 +while (0);
41 EOF
42
43 git diff >out &&
44 test_cmp expect out &&
45
46 git diff -w >out &&
47 test_cmp expect out &&
48
49 git diff -b >out &&
50 test_cmp expect out
51'
52
53test_expect_success 'another test, without options' '
54 tr Q "\015" <<-\EOF >x &&
55 whitespace at beginning
56 whitespace change
57 whitespace in the middle
58 whitespace at end
59 unchanged line
60 CR at endQ
61 EOF
62
63 git update-index x &&
64
65 tr "_" " " <<-\EOF >x &&
66 _ whitespace at beginning
67 whitespace change
68 white space in the middle
69 whitespace at end__
70 unchanged line
71 CR at end
72 EOF
73
74 tr "Q_" "\015 " <<-\EOF >expect &&
75 diff --git a/x b/x
76 index d99af23..22d9f73 100644
77 --- a/x
78 +++ b/x
79 @@ -1,6 +1,6 @@
80 -whitespace at beginning
81 -whitespace change
82 -whitespace in the middle
83 -whitespace at end
84 + whitespace at beginning
85 +whitespace change
86 +white space in the middle
87 +whitespace at end__
88 unchanged line
89 -CR at endQ
90 +CR at end
91 EOF
92
93 git diff >out &&
94 test_cmp expect out &&
95
96 git diff -w >out &&
97 test_must_be_empty out &&
98
99 git diff -w -b >out &&
100 test_must_be_empty out &&
101
102 git diff -w --ignore-space-at-eol >out &&
103 test_must_be_empty out &&
104
105 git diff -w -b --ignore-space-at-eol >out &&
106 test_must_be_empty out &&
107
108 git diff -w --ignore-cr-at-eol >out &&
109 test_must_be_empty out &&
110
111 tr "Q_" "\015 " <<-\EOF >expect &&
112 diff --git a/x b/x
113 index d99af23..22d9f73 100644
114 --- a/x
115 +++ b/x
116 @@ -1,6 +1,6 @@
117 -whitespace at beginning
118 +_ whitespace at beginning
119 whitespace change
120 -whitespace in the middle
121 +white space in the middle
122 whitespace at end__
123 unchanged line
124 CR at end
125 EOF
126 git diff -b >out &&
127 test_cmp expect out &&
128
129 git diff -b --ignore-space-at-eol >out &&
130 test_cmp expect out &&
131
132 git diff -b --ignore-cr-at-eol >out &&
133 test_cmp expect out &&
134
135 tr "Q_" "\015 " <<-\EOF >expect &&
136 diff --git a/x b/x
137 index d99af23..22d9f73 100644
138 --- a/x
139 +++ b/x
140 @@ -1,6 +1,6 @@
141 -whitespace at beginning
142 -whitespace change
143 -whitespace in the middle
144 +_ whitespace at beginning
145 +whitespace change
146 +white space in the middle
147 whitespace at end__
148 unchanged line
149 CR at end
150 EOF
151 git diff --ignore-space-at-eol >out &&
152 test_cmp expect out &&
153
154 git diff --ignore-space-at-eol --ignore-cr-at-eol >out &&
155 test_cmp expect out &&
156
157 tr "Q_" "\015 " <<-\EOF >expect &&
158 diff --git a/x b/x
159 index_d99af23..22d9f73 100644
160 --- a/x
161 +++ b/x
162 @@ -1,6 +1,6 @@
163 -whitespace at beginning
164 -whitespace change
165 -whitespace in the middle
166 -whitespace at end
167 +_ whitespace at beginning
168 +whitespace_ _change
169 +white space in the middle
170 +whitespace at end__
171 unchanged line
172 CR at end
173 EOF
174 git diff --ignore-cr-at-eol >out &&
175 test_cmp expect out
176'
177
178test_expect_success 'ignore-blank-lines: only new lines' '
179 test_seq 5 >x &&
180 git update-index x &&
181 test_seq 5 | sed "/3/i\\
182" >x &&
183 git diff --ignore-blank-lines >out &&
184 test_must_be_empty out
185'
186
187test_expect_success 'ignore-blank-lines: only new lines with space' '
188 test_seq 5 >x &&
189 git update-index x &&
190 test_seq 5 | sed "/3/i\\
191 " >x &&
192 git diff -w --ignore-blank-lines >out &&
193 test_must_be_empty out
194'
195
196test_expect_success 'ignore-blank-lines: after change' '
197 cat <<-\EOF >x &&
198 1
199 2
200
201 3
202 4
203 5
204
205 6
206 7
207 EOF
208 git update-index x &&
209 cat <<-\EOF >x &&
210 change
211
212 1
213 2
214 3
215 4
216 5
217 6
218
219 7
220 EOF
221 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
222 cat <<-\EOF >expected &&
223 diff --git a/x b/x
224 --- a/x
225 +++ b/x
226 @@ -1,6 +1,7 @@
227 +change
228 +
229 1
230 2
231 -
232 3
233 4
234 5
235 EOF
236 compare_diff_patch expected out.tmp
237'
238
239test_expect_success 'ignore-blank-lines: before change' '
240 cat <<-\EOF >x &&
241 1
242 2
243
244 3
245 4
246 5
247 6
248 7
249 EOF
250 git update-index x &&
251 cat <<-\EOF >x &&
252
253 1
254 2
255 3
256 4
257 5
258
259 6
260 7
261 change
262 EOF
263 git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
264 cat <<-\EOF >expected &&
265 diff --git a/x b/x
266 --- a/x
267 +++ b/x
268 @@ -4,5 +4,7 @@
269 3
270 4
271 5
272 +
273 6
274 7
275 +change
276 EOF
277 compare_diff_patch expected out.tmp
278'
279
280test_expect_success 'ignore-blank-lines: between changes' '
281 cat <<-\EOF >x &&
282 1
283 2
284 3
285 4
286 5
287
288
289 6
290 7
291 8
292 9
293 10
294 EOF
295 git update-index x &&
296 cat <<-\EOF >x &&
297 change
298 1
299 2
300
301 3
302 4
303 5
304 6
305 7
306 8
307
308 9
309 10
310 change
311 EOF
312 git diff --ignore-blank-lines >out.tmp &&
313 cat <<-\EOF >expected &&
314 diff --git a/x b/x
315 --- a/x
316 +++ b/x
317 @@ -1,5 +1,7 @@
318 +change
319 1
320 2
321 +
322 3
323 4
324 5
325 @@ -8,5 +8,7 @@
326 6
327 7
328 8
329 +
330 9
331 10
332 +change
333 EOF
334 compare_diff_patch expected out.tmp
335'
336
337test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
338 test_seq 10 >x &&
339 git update-index x &&
340 cat <<-\EOF >x &&
341 change
342 1
343 2
344
345 3
346 4
347 5
348
349 6
350 7
351 8
352 9
353
354 10
355 change
356 EOF
357 git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
358 cat <<-\EOF >expected &&
359 diff --git a/x b/x
360 --- a/x
361 +++ b/x
362 @@ -1,10 +1,15 @@
363 +change
364 1
365 2
366 +
367 3
368 4
369 5
370 +
371 6
372 7
373 8
374 9
375 +
376 10
377 +change
378 EOF
379 compare_diff_patch expected out.tmp
380'
381
382test_expect_success 'ignore-blank-lines: scattered spaces' '
383 test_seq 10 >x &&
384 git update-index x &&
385 cat <<-\EOF >x &&
386 change
387 1
388 2
389 3
390
391 4
392
393 5
394
395 6
396
397
398 7
399
400 8
401 9
402 10
403 change
404 EOF
405 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
406 cat <<-\EOF >expected &&
407 diff --git a/x b/x
408 --- a/x
409 +++ b/x
410 @@ -1,3 +1,4 @@
411 +change
412 1
413 2
414 3
415 @@ -8,3 +15,4 @@
416 8
417 9
418 10
419 +change
420 EOF
421 compare_diff_patch expected out.tmp
422'
423
424test_expect_success 'ignore-blank-lines: spaces coalesce' '
425 test_seq 6 >x &&
426 git update-index x &&
427 cat <<-\EOF >x &&
428 change
429 1
430 2
431 3
432
433 4
434
435 5
436
437 6
438 change
439 EOF
440 git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
441 cat <<-\EOF >expected &&
442 diff --git a/x b/x
443 --- a/x
444 +++ b/x
445 @@ -1,6 +1,11 @@
446 +change
447 1
448 2
449 3
450 +
451 4
452 +
453 5
454 +
455 6
456 +change
457 EOF
458 compare_diff_patch expected out.tmp
459'
460
461test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
462 test_seq 16 >x &&
463 git update-index x &&
464 cat <<-\EOF >x &&
465 change
466 1
467 2
468
469 3
470 4
471 5
472 change
473 6
474 7
475 8
476
477 9
478 10
479 11
480 change
481 12
482 13
483 14
484
485 15
486 16
487 change
488 EOF
489 git diff --ignore-blank-lines >out.tmp &&
490 cat <<-\EOF >expected &&
491 diff --git a/x b/x
492 --- a/x
493 +++ b/x
494 @@ -1,8 +1,11 @@
495 +change
496 1
497 2
498 +
499 3
500 4
501 5
502 +change
503 6
504 7
505 8
506 @@ -9,8 +13,11 @@
507 9
508 10
509 11
510 +change
511 12
512 13
513 14
514 +
515 15
516 16
517 +change
518 EOF
519 compare_diff_patch expected out.tmp
520'
521
522test_expect_success 'check mixed spaces and tabs in indent' '
523 # This is indented with SP HT SP.
524 echo " foo();" >x &&
525 git diff --check | grep "space before tab in indent"
526'
527
528test_expect_success 'check mixed tabs and spaces in indent' '
529 # This is indented with HT SP HT.
530 echo " foo();" >x &&
531 git diff --check | grep "space before tab in indent"
532'
533
534test_expect_success 'check with no whitespace errors' '
535 git commit -m "snapshot" &&
536 echo "foo();" >x &&
537 git diff --check
538'
539
540test_expect_success 'check with trailing whitespace' '
541 echo "foo(); " >x &&
542 test_must_fail git diff --check
543'
544
545test_expect_success 'check with space before tab in indent' '
546 # indent has space followed by hard tab
547 echo " foo();" >x &&
548 test_must_fail git diff --check
549'
550
551test_expect_success '--check and --exit-code are not exclusive' '
552 git checkout x &&
553 git diff --check --exit-code
554'
555
556test_expect_success '--check and --quiet are not exclusive' '
557 git diff --check --quiet
558'
559
560test_expect_success 'check staged with no whitespace errors' '
561 echo "foo();" >x &&
562 git add x &&
563 git diff --cached --check
564'
565
566test_expect_success 'check staged with trailing whitespace' '
567 echo "foo(); " >x &&
568 git add x &&
569 test_must_fail git diff --cached --check
570'
571
572test_expect_success 'check staged with space before tab in indent' '
573 # indent has space followed by hard tab
574 echo " foo();" >x &&
575 git add x &&
576 test_must_fail git diff --cached --check
577'
578
579test_expect_success 'check with no whitespace errors (diff-index)' '
580 echo "foo();" >x &&
581 git add x &&
582 git diff-index --check HEAD
583'
584
585test_expect_success 'check with trailing whitespace (diff-index)' '
586 echo "foo(); " >x &&
587 git add x &&
588 test_must_fail git diff-index --check HEAD
589'
590
591test_expect_success 'check with space before tab in indent (diff-index)' '
592 # indent has space followed by hard tab
593 echo " foo();" >x &&
594 git add x &&
595 test_must_fail git diff-index --check HEAD
596'
597
598test_expect_success 'check staged with no whitespace errors (diff-index)' '
599 echo "foo();" >x &&
600 git add x &&
601 git diff-index --cached --check HEAD
602'
603
604test_expect_success 'check staged with trailing whitespace (diff-index)' '
605 echo "foo(); " >x &&
606 git add x &&
607 test_must_fail git diff-index --cached --check HEAD
608'
609
610test_expect_success 'check staged with space before tab in indent (diff-index)' '
611 # indent has space followed by hard tab
612 echo " foo();" >x &&
613 git add x &&
614 test_must_fail git diff-index --cached --check HEAD
615'
616
617test_expect_success 'check with no whitespace errors (diff-tree)' '
618 echo "foo();" >x &&
619 git commit -m "new commit" x &&
620 git diff-tree --check HEAD^ HEAD
621'
622
623test_expect_success 'check with trailing whitespace (diff-tree)' '
624 echo "foo(); " >x &&
625 git commit -m "another commit" x &&
626 test_must_fail git diff-tree --check HEAD^ HEAD
627'
628
629test_expect_success 'check with space before tab in indent (diff-tree)' '
630 # indent has space followed by hard tab
631 echo " foo();" >x &&
632 git commit -m "yet another" x &&
633 test_must_fail git diff-tree --check HEAD^ HEAD
634'
635
636test_expect_success 'check with ignored trailing whitespace attr (diff-tree)' '
637 test_when_finished "git reset --hard HEAD^" &&
638
639 # create a whitespace error that should be ignored
640 echo "* -whitespace" >.gitattributes &&
641 git add .gitattributes &&
642 echo "foo(); " >x &&
643 git add x &&
644 git commit -m "add trailing space" &&
645
646 # with a worktree diff-tree ignores the whitespace error
647 git diff-tree --root --check HEAD &&
648
649 # without a worktree diff-tree still ignores the whitespace error
650 git -C .git diff-tree --root --check HEAD
651'
652
653test_expect_success 'check trailing whitespace (trailing-space: off)' '
654 git config core.whitespace "-trailing-space" &&
655 echo "foo (); " >x &&
656 git diff --check
657'
658
659test_expect_success 'check trailing whitespace (trailing-space: on)' '
660 git config core.whitespace "trailing-space" &&
661 echo "foo (); " >x &&
662 test_must_fail git diff --check
663'
664
665test_expect_success 'check space before tab in indent (space-before-tab: off)' '
666 # indent contains space followed by HT
667 git config core.whitespace "-space-before-tab" &&
668 echo " foo ();" >x &&
669 git diff --check
670'
671
672test_expect_success 'check space before tab in indent (space-before-tab: on)' '
673 # indent contains space followed by HT
674 git config core.whitespace "space-before-tab" &&
675 echo " foo (); " >x &&
676 test_must_fail git diff --check
677'
678
679test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
680 git config core.whitespace "-indent-with-non-tab" &&
681 echo " foo ();" >x &&
682 git diff --check
683'
684
685test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
686 git config core.whitespace "indent-with-non-tab" &&
687 echo " foo ();" >x &&
688 test_must_fail git diff --check
689'
690
691test_expect_success 'ditto, but tabwidth=9' '
692 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
693 git diff --check
694'
695
696test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
697 git config core.whitespace "indent-with-non-tab" &&
698 echo " foo ();" >x &&
699 test_must_fail git diff --check
700'
701
702test_expect_success 'ditto, but tabwidth=10' '
703 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
704 test_must_fail git diff --check
705'
706
707test_expect_success 'ditto, but tabwidth=20' '
708 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
709 git diff --check
710'
711
712test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
713 git config core.whitespace "-tab-in-indent" &&
714 echo " foo ();" >x &&
715 git diff --check
716'
717
718test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
719 git config core.whitespace "tab-in-indent" &&
720 echo " foo ();" >x &&
721 test_must_fail git diff --check
722'
723
724test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
725 git config core.whitespace "tab-in-indent" &&
726 echo " foo ();" >x &&
727 test_must_fail git diff --check
728'
729
730test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
731 git config core.whitespace "tab-in-indent,tabwidth=1" &&
732 test_must_fail git diff --check
733'
734
735test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
736 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
737 echo "foo ();" >x &&
738 test_must_fail git diff --check
739'
740
741test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
742 git config --unset core.whitespace &&
743 echo "x whitespace" >.gitattributes &&
744 echo " foo ();" >x &&
745 git diff --check &&
746 rm -f .gitattributes
747'
748
749test_expect_success 'line numbers in --check output are correct' '
750 echo "" >x &&
751 echo "foo(); " >>x &&
752 git diff --check | grep "x:2:"
753'
754
755test_expect_success 'checkdiff detects new trailing blank lines (1)' '
756 echo "foo();" >x &&
757 echo "" >>x &&
758 git diff --check | grep "new blank line"
759'
760
761test_expect_success 'checkdiff detects new trailing blank lines (2)' '
762 { echo a; echo b; echo; echo; } >x &&
763 git add x &&
764 { echo a; echo; echo; echo; echo; } >x &&
765 git diff --check | grep "new blank line"
766'
767
768test_expect_success 'checkdiff allows new blank lines' '
769 git checkout x &&
770 mv x y &&
771 (
772 echo "/* This is new */" &&
773 echo "" &&
774 cat y
775 ) >x &&
776 git diff --check
777'
778
779cat <<EOF >expect
780EOF
781test_expect_success 'whitespace-only changes not reported' '
782 git reset --hard &&
783 echo >x "hello world" &&
784 git add x &&
785 git commit -m "hello 1" &&
786 echo >x "hello world" &&
787 git diff -b >actual &&
788 test_cmp expect actual
789'
790
791cat <<EOF >expect
792diff --git a/x b/z
793similarity index NUM%
794rename from x
795rename to z
796index 380c32a..a97b785 100644
797EOF
798test_expect_success 'whitespace-only changes reported across renames' '
799 git reset --hard &&
800 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
801 git add x &&
802 git commit -m "base" &&
803 sed -e "5s/^/ /" x >z &&
804 git rm x &&
805 git add z &&
806 git diff -w -M --cached |
807 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual &&
808 test_cmp expect actual
809'
810
811cat >expected <<\EOF
812diff --git a/empty b/void
813similarity index 100%
814rename from empty
815rename to void
816EOF
817
818test_expect_success 'rename empty' '
819 git reset --hard &&
820 >empty &&
821 git add empty &&
822 git commit -m empty &&
823 git mv empty void &&
824 git diff -w --cached -M >current &&
825 test_cmp expected current
826'
827
828test_expect_success 'combined diff with autocrlf conversion' '
829
830 git reset --hard &&
831 echo >x hello &&
832 git commit -m "one side" x &&
833 git checkout HEAD^ &&
834 echo >x goodbye &&
835 git commit -m "the other side" x &&
836 git config core.autocrlf true &&
837 test_must_fail git merge master &&
838
839 git diff | sed -e "1,/^@@@/d" >actual &&
840 ! grep "^-" actual
841
842'
843
844# Start testing the colored format for whitespace checks
845
846test_expect_success 'setup diff colors' '
847 git config color.diff.plain normal &&
848 git config color.diff.meta bold &&
849 git config color.diff.frag cyan &&
850 git config color.diff.func normal &&
851 git config color.diff.old red &&
852 git config color.diff.new green &&
853 git config color.diff.commit yellow &&
854 git config color.diff.whitespace blue &&
855
856 git config core.autocrlf false
857'
858
859test_expect_success 'diff that introduces a line with only tabs' '
860 git config core.whitespace blank-at-eol &&
861 git reset --hard &&
862 echo "test" >x &&
863 git commit -m "initial" x &&
864 echo "{NTN}" | tr "NT" "\n\t" >>x &&
865 git diff --color | test_decode_color >current &&
866
867 cat >expected <<-\EOF &&
868 <BOLD>diff --git a/x b/x<RESET>
869 <BOLD>index 9daeafb..2874b91 100644<RESET>
870 <BOLD>--- a/x<RESET>
871 <BOLD>+++ b/x<RESET>
872 <CYAN>@@ -1 +1,4 @@<RESET>
873 test<RESET>
874 <GREEN>+<RESET><GREEN>{<RESET>
875 <GREEN>+<RESET><BLUE> <RESET>
876 <GREEN>+<RESET><GREEN>}<RESET>
877 EOF
878
879 test_cmp expected current
880'
881
882test_expect_success 'diff that introduces and removes ws breakages' '
883 git reset --hard &&
884 {
885 echo "0. blank-at-eol " &&
886 echo "1. blank-at-eol "
887 } >x &&
888 git commit -a --allow-empty -m preimage &&
889 {
890 echo "0. blank-at-eol " &&
891 echo "1. still-blank-at-eol " &&
892 echo "2. and a new line "
893 } >x &&
894
895 git diff --color |
896 test_decode_color >current &&
897
898 cat >expected <<-\EOF &&
899 <BOLD>diff --git a/x b/x<RESET>
900 <BOLD>index d0233a2..700886e 100644<RESET>
901 <BOLD>--- a/x<RESET>
902 <BOLD>+++ b/x<RESET>
903 <CYAN>@@ -1,2 +1,3 @@<RESET>
904 0. blank-at-eol <RESET>
905 <RED>-1. blank-at-eol <RESET>
906 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
907 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
908 EOF
909
910 test_cmp expected current
911'
912
913test_expect_success 'ws-error-highlight test setup' '
914
915 git reset --hard &&
916 {
917 echo "0. blank-at-eol " &&
918 echo "1. blank-at-eol "
919 } >x &&
920 git commit -a --allow-empty -m preimage &&
921 {
922 echo "0. blank-at-eol " &&
923 echo "1. still-blank-at-eol " &&
924 echo "2. and a new line "
925 } >x &&
926
927 cat >expect.default-old <<-\EOF &&
928 <BOLD>diff --git a/x b/x<RESET>
929 <BOLD>index d0233a2..700886e 100644<RESET>
930 <BOLD>--- a/x<RESET>
931 <BOLD>+++ b/x<RESET>
932 <CYAN>@@ -1,2 +1,3 @@<RESET>
933 0. blank-at-eol <RESET>
934 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
935 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
936 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
937 EOF
938
939 cat >expect.all <<-\EOF &&
940 <BOLD>diff --git a/x b/x<RESET>
941 <BOLD>index d0233a2..700886e 100644<RESET>
942 <BOLD>--- a/x<RESET>
943 <BOLD>+++ b/x<RESET>
944 <CYAN>@@ -1,2 +1,3 @@<RESET>
945 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
946 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
947 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
948 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
949 EOF
950
951 cat >expect.none <<-\EOF
952 <BOLD>diff --git a/x b/x<RESET>
953 <BOLD>index d0233a2..700886e 100644<RESET>
954 <BOLD>--- a/x<RESET>
955 <BOLD>+++ b/x<RESET>
956 <CYAN>@@ -1,2 +1,3 @@<RESET>
957 0. blank-at-eol <RESET>
958 <RED>-1. blank-at-eol <RESET>
959 <GREEN>+1. still-blank-at-eol <RESET>
960 <GREEN>+2. and a new line <RESET>
961 EOF
962
963'
964
965test_expect_success 'test --ws-error-highlight option' '
966
967 git diff --color --ws-error-highlight=default,old |
968 test_decode_color >current &&
969 test_cmp expect.default-old current &&
970
971 git diff --color --ws-error-highlight=all |
972 test_decode_color >current &&
973 test_cmp expect.all current &&
974
975 git diff --color --ws-error-highlight=none |
976 test_decode_color >current &&
977 test_cmp expect.none current
978
979'
980
981test_expect_success 'test diff.wsErrorHighlight config' '
982
983 git -c diff.wsErrorHighlight=default,old diff --color |
984 test_decode_color >current &&
985 test_cmp expect.default-old current &&
986
987 git -c diff.wsErrorHighlight=all diff --color |
988 test_decode_color >current &&
989 test_cmp expect.all current &&
990
991 git -c diff.wsErrorHighlight=none diff --color |
992 test_decode_color >current &&
993 test_cmp expect.none current
994
995'
996
997test_expect_success 'option overrides diff.wsErrorHighlight' '
998
999 git -c diff.wsErrorHighlight=none \
1000 diff --color --ws-error-highlight=default,old |
1001 test_decode_color >current &&
1002 test_cmp expect.default-old current &&
1003
1004 git -c diff.wsErrorHighlight=default \
1005 diff --color --ws-error-highlight=all |
1006 test_decode_color >current &&
1007 test_cmp expect.all current &&
1008
1009 git -c diff.wsErrorHighlight=all \
1010 diff --color --ws-error-highlight=none |
1011 test_decode_color >current &&
1012 test_cmp expect.none current
1013
1014'
1015
1016test_expect_success 'detect moved code, complete file' '
1017 git reset --hard &&
1018 cat <<-\EOF >test.c &&
1019 #include<stdio.h>
1020 main()
1021 {
1022 printf("Hello World");
1023 }
1024 EOF
1025 git add test.c &&
1026 git commit -m "add main function" &&
1027 git mv test.c main.c &&
1028 test_config color.diff.oldMoved "normal red" &&
1029 test_config color.diff.newMoved "normal green" &&
1030 git diff HEAD --color-moved=zebra --color --no-renames | test_decode_color >actual &&
1031 cat >expected <<-\EOF &&
1032 <BOLD>diff --git a/main.c b/main.c<RESET>
1033 <BOLD>new file mode 100644<RESET>
1034 <BOLD>index 0000000..a986c57<RESET>
1035 <BOLD>--- /dev/null<RESET>
1036 <BOLD>+++ b/main.c<RESET>
1037 <CYAN>@@ -0,0 +1,5 @@<RESET>
1038 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1039 <BGREEN>+<RESET><BGREEN>main()<RESET>
1040 <BGREEN>+<RESET><BGREEN>{<RESET>
1041 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1042 <BGREEN>+<RESET><BGREEN>}<RESET>
1043 <BOLD>diff --git a/test.c b/test.c<RESET>
1044 <BOLD>deleted file mode 100644<RESET>
1045 <BOLD>index a986c57..0000000<RESET>
1046 <BOLD>--- a/test.c<RESET>
1047 <BOLD>+++ /dev/null<RESET>
1048 <CYAN>@@ -1,5 +0,0 @@<RESET>
1049 <BRED>-#include<stdio.h><RESET>
1050 <BRED>-main()<RESET>
1051 <BRED>-{<RESET>
1052 <BRED>-printf("Hello World");<RESET>
1053 <BRED>-}<RESET>
1054 EOF
1055
1056 test_cmp expected actual
1057'
1058
1059test_expect_success 'detect malicious moved code, inside file' '
1060 test_config color.diff.oldMoved "normal red" &&
1061 test_config color.diff.newMoved "normal green" &&
1062 test_config color.diff.oldMovedAlternative "blue" &&
1063 test_config color.diff.newMovedAlternative "yellow" &&
1064 git reset --hard &&
1065 cat <<-\EOF >main.c &&
1066 #include<stdio.h>
1067 int stuff()
1068 {
1069 printf("Hello ");
1070 printf("World\n");
1071 }
1072
1073 int secure_foo(struct user *u)
1074 {
1075 if (!u->is_allowed_foo)
1076 return;
1077 foo(u);
1078 }
1079
1080 int main()
1081 {
1082 foo();
1083 }
1084 EOF
1085 cat <<-\EOF >test.c &&
1086 #include<stdio.h>
1087 int bar()
1088 {
1089 printf("Hello World, but different\n");
1090 }
1091
1092 int another_function()
1093 {
1094 bar();
1095 }
1096 EOF
1097 git add main.c test.c &&
1098 git commit -m "add main and test file" &&
1099 cat <<-\EOF >main.c &&
1100 #include<stdio.h>
1101 int stuff()
1102 {
1103 printf("Hello ");
1104 printf("World\n");
1105 }
1106
1107 int main()
1108 {
1109 foo();
1110 }
1111 EOF
1112 cat <<-\EOF >test.c &&
1113 #include<stdio.h>
1114 int bar()
1115 {
1116 printf("Hello World, but different\n");
1117 }
1118
1119 int secure_foo(struct user *u)
1120 {
1121 foo(u);
1122 if (!u->is_allowed_foo)
1123 return;
1124 }
1125
1126 int another_function()
1127 {
1128 bar();
1129 }
1130 EOF
1131 git diff HEAD --no-renames --color-moved=zebra --color | test_decode_color >actual &&
1132 cat <<-\EOF >expected &&
1133 <BOLD>diff --git a/main.c b/main.c<RESET>
1134 <BOLD>index 27a619c..7cf9336 100644<RESET>
1135 <BOLD>--- a/main.c<RESET>
1136 <BOLD>+++ b/main.c<RESET>
1137 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1138 printf("World\n");<RESET>
1139 }<RESET>
1140 <RESET>
1141 <BRED>-int secure_foo(struct user *u)<RESET>
1142 <BRED>-{<RESET>
1143 <BLUE>-if (!u->is_allowed_foo)<RESET>
1144 <BLUE>-return;<RESET>
1145 <RED>-foo(u);<RESET>
1146 <RED>-}<RESET>
1147 <RED>-<RESET>
1148 int main()<RESET>
1149 {<RESET>
1150 foo();<RESET>
1151 <BOLD>diff --git a/test.c b/test.c<RESET>
1152 <BOLD>index 1dc1d85..2bedec9 100644<RESET>
1153 <BOLD>--- a/test.c<RESET>
1154 <BOLD>+++ b/test.c<RESET>
1155 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1156 printf("Hello World, but different\n");<RESET>
1157 }<RESET>
1158 <RESET>
1159 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1160 <BGREEN>+<RESET><BGREEN>{<RESET>
1161 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1162 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1163 <BGREEN>+<RESET><BGREEN>return;<RESET>
1164 <GREEN>+<RESET><GREEN>}<RESET>
1165 <GREEN>+<RESET>
1166 int another_function()<RESET>
1167 {<RESET>
1168 bar();<RESET>
1169 EOF
1170
1171 test_cmp expected actual
1172'
1173
1174test_expect_success 'plain moved code, inside file' '
1175 test_config color.diff.oldMoved "normal red" &&
1176 test_config color.diff.newMoved "normal green" &&
1177 test_config color.diff.oldMovedAlternative "blue" &&
1178 test_config color.diff.newMovedAlternative "yellow" &&
1179 # needs previous test as setup
1180 git diff HEAD --no-renames --color-moved=plain --color | test_decode_color >actual &&
1181 cat <<-\EOF >expected &&
1182 <BOLD>diff --git a/main.c b/main.c<RESET>
1183 <BOLD>index 27a619c..7cf9336 100644<RESET>
1184 <BOLD>--- a/main.c<RESET>
1185 <BOLD>+++ b/main.c<RESET>
1186 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1187 printf("World\n");<RESET>
1188 }<RESET>
1189 <RESET>
1190 <BRED>-int secure_foo(struct user *u)<RESET>
1191 <BRED>-{<RESET>
1192 <BRED>-if (!u->is_allowed_foo)<RESET>
1193 <BRED>-return;<RESET>
1194 <BRED>-foo(u);<RESET>
1195 <BRED>-}<RESET>
1196 <BRED>-<RESET>
1197 int main()<RESET>
1198 {<RESET>
1199 foo();<RESET>
1200 <BOLD>diff --git a/test.c b/test.c<RESET>
1201 <BOLD>index 1dc1d85..2bedec9 100644<RESET>
1202 <BOLD>--- a/test.c<RESET>
1203 <BOLD>+++ b/test.c<RESET>
1204 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1205 printf("Hello World, but different\n");<RESET>
1206 }<RESET>
1207 <RESET>
1208 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1209 <BGREEN>+<RESET><BGREEN>{<RESET>
1210 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1211 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1212 <BGREEN>+<RESET><BGREEN>return;<RESET>
1213 <BGREEN>+<RESET><BGREEN>}<RESET>
1214 <BGREEN>+<RESET>
1215 int another_function()<RESET>
1216 {<RESET>
1217 bar();<RESET>
1218 EOF
1219
1220 test_cmp expected actual
1221'
1222
1223test_expect_success 'detect blocks of moved code' '
1224 git reset --hard &&
1225 cat <<-\EOF >lines.txt &&
1226 long line 1
1227 long line 2
1228 long line 3
1229 line 4
1230 line 5
1231 line 6
1232 line 7
1233 line 8
1234 line 9
1235 line 10
1236 line 11
1237 line 12
1238 line 13
1239 long line 14
1240 long line 15
1241 long line 16
1242 EOF
1243 git add lines.txt &&
1244 git commit -m "add poetry" &&
1245 cat <<-\EOF >lines.txt &&
1246 line 4
1247 line 5
1248 line 6
1249 line 7
1250 line 8
1251 line 9
1252 long line 1
1253 long line 2
1254 long line 3
1255 long line 14
1256 long line 15
1257 long line 16
1258 line 10
1259 line 11
1260 line 12
1261 line 13
1262 EOF
1263 test_config color.diff.oldMoved "magenta" &&
1264 test_config color.diff.newMoved "cyan" &&
1265 test_config color.diff.oldMovedAlternative "blue" &&
1266 test_config color.diff.newMovedAlternative "yellow" &&
1267 test_config color.diff.oldMovedDimmed "normal magenta" &&
1268 test_config color.diff.newMovedDimmed "normal cyan" &&
1269 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1270 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1271 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1272 grep -v "index" actual.raw | test_decode_color >actual &&
1273 cat <<-\EOF >expected &&
1274 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1275 <BOLD>--- a/lines.txt<RESET>
1276 <BOLD>+++ b/lines.txt<RESET>
1277 <CYAN>@@ -1,16 +1,16 @@<RESET>
1278 <MAGENTA>-long line 1<RESET>
1279 <MAGENTA>-long line 2<RESET>
1280 <MAGENTA>-long line 3<RESET>
1281 line 4<RESET>
1282 line 5<RESET>
1283 line 6<RESET>
1284 line 7<RESET>
1285 line 8<RESET>
1286 line 9<RESET>
1287 <CYAN>+<RESET><CYAN>long line 1<RESET>
1288 <CYAN>+<RESET><CYAN>long line 2<RESET>
1289 <CYAN>+<RESET><CYAN>long line 3<RESET>
1290 <CYAN>+<RESET><CYAN>long line 14<RESET>
1291 <CYAN>+<RESET><CYAN>long line 15<RESET>
1292 <CYAN>+<RESET><CYAN>long line 16<RESET>
1293 line 10<RESET>
1294 line 11<RESET>
1295 line 12<RESET>
1296 line 13<RESET>
1297 <MAGENTA>-long line 14<RESET>
1298 <MAGENTA>-long line 15<RESET>
1299 <MAGENTA>-long line 16<RESET>
1300 EOF
1301 test_cmp expected actual
1302
1303'
1304
1305test_expect_success 'detect permutations inside moved code -- dimmed-zebra' '
1306 # reuse setup from test before!
1307 test_config color.diff.oldMoved "magenta" &&
1308 test_config color.diff.newMoved "cyan" &&
1309 test_config color.diff.oldMovedAlternative "blue" &&
1310 test_config color.diff.newMovedAlternative "yellow" &&
1311 test_config color.diff.oldMovedDimmed "normal magenta" &&
1312 test_config color.diff.newMovedDimmed "normal cyan" &&
1313 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1314 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1315 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1316 grep -v "index" actual.raw | test_decode_color >actual &&
1317 cat <<-\EOF >expected &&
1318 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1319 <BOLD>--- a/lines.txt<RESET>
1320 <BOLD>+++ b/lines.txt<RESET>
1321 <CYAN>@@ -1,16 +1,16 @@<RESET>
1322 <BMAGENTA>-long line 1<RESET>
1323 <BMAGENTA>-long line 2<RESET>
1324 <BMAGENTA>-long line 3<RESET>
1325 line 4<RESET>
1326 line 5<RESET>
1327 line 6<RESET>
1328 line 7<RESET>
1329 line 8<RESET>
1330 line 9<RESET>
1331 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1332 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1333 <CYAN>+<RESET><CYAN>long line 3<RESET>
1334 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1335 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1336 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1337 line 10<RESET>
1338 line 11<RESET>
1339 line 12<RESET>
1340 line 13<RESET>
1341 <BMAGENTA>-long line 14<RESET>
1342 <BMAGENTA>-long line 15<RESET>
1343 <BMAGENTA>-long line 16<RESET>
1344 EOF
1345 test_cmp expected actual
1346'
1347
1348test_expect_success 'cmd option assumes configured colored-moved' '
1349 test_config color.diff.oldMoved "magenta" &&
1350 test_config color.diff.newMoved "cyan" &&
1351 test_config color.diff.oldMovedAlternative "blue" &&
1352 test_config color.diff.newMovedAlternative "yellow" &&
1353 test_config color.diff.oldMovedDimmed "normal magenta" &&
1354 test_config color.diff.newMovedDimmed "normal cyan" &&
1355 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1356 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1357 test_config diff.colorMoved zebra &&
1358 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1359 grep -v "index" actual.raw | test_decode_color >actual &&
1360 cat <<-\EOF >expected &&
1361 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1362 <BOLD>--- a/lines.txt<RESET>
1363 <BOLD>+++ b/lines.txt<RESET>
1364 <CYAN>@@ -1,16 +1,16 @@<RESET>
1365 <MAGENTA>-long line 1<RESET>
1366 <MAGENTA>-long line 2<RESET>
1367 <MAGENTA>-long line 3<RESET>
1368 line 4<RESET>
1369 line 5<RESET>
1370 line 6<RESET>
1371 line 7<RESET>
1372 line 8<RESET>
1373 line 9<RESET>
1374 <CYAN>+<RESET><CYAN>long line 1<RESET>
1375 <CYAN>+<RESET><CYAN>long line 2<RESET>
1376 <CYAN>+<RESET><CYAN>long line 3<RESET>
1377 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1378 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1379 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1380 line 10<RESET>
1381 line 11<RESET>
1382 line 12<RESET>
1383 line 13<RESET>
1384 <MAGENTA>-long line 14<RESET>
1385 <MAGENTA>-long line 15<RESET>
1386 <MAGENTA>-long line 16<RESET>
1387 EOF
1388 test_cmp expected actual
1389'
1390
1391test_expect_success 'no effect from --color-moved with --word-diff' '
1392 cat <<-\EOF >text.txt &&
1393 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1394 EOF
1395 git add text.txt &&
1396 git commit -a -m "clean state" &&
1397 cat <<-\EOF >text.txt &&
1398 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1399 EOF
1400 git diff --color-moved --word-diff >actual &&
1401 git diff --word-diff >expect &&
1402 test_cmp expect actual
1403'
1404
1405test_expect_success 'set up whitespace tests' '
1406 git reset --hard &&
1407 # Note that these lines have no leading or trailing whitespace.
1408 cat <<-\EOF >lines.txt &&
1409 line 1
1410 line 2
1411 line 3
1412 line 4
1413 line 5
1414 long line 6
1415 long line 7
1416 long line 8
1417 long line 9
1418 EOF
1419 git add lines.txt &&
1420 git commit -m "add poetry" &&
1421 git config color.diff.oldMoved "magenta" &&
1422 git config color.diff.newMoved "cyan"
1423'
1424
1425test_expect_success 'move detection ignoring whitespace ' '
1426 q_to_tab <<-\EOF >lines.txt &&
1427 Qlong line 6
1428 Qlong line 7
1429 Qlong line 8
1430 Qchanged long line 9
1431 line 1
1432 line 2
1433 line 3
1434 line 4
1435 line 5
1436 EOF
1437 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1438 grep -v "index" actual.raw | test_decode_color >actual &&
1439 cat <<-\EOF >expected &&
1440 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1441 <BOLD>--- a/lines.txt<RESET>
1442 <BOLD>+++ b/lines.txt<RESET>
1443 <CYAN>@@ -1,9 +1,9 @@<RESET>
1444 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1445 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1446 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1447 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1448 line 1<RESET>
1449 line 2<RESET>
1450 line 3<RESET>
1451 line 4<RESET>
1452 line 5<RESET>
1453 <RED>-long line 6<RESET>
1454 <RED>-long line 7<RESET>
1455 <RED>-long line 8<RESET>
1456 <RED>-long line 9<RESET>
1457 EOF
1458 test_cmp expected actual &&
1459
1460 git diff HEAD --no-renames --color-moved --color \
1461 --color-moved-ws=ignore-all-space >actual.raw &&
1462 grep -v "index" actual.raw | test_decode_color >actual &&
1463 cat <<-\EOF >expected &&
1464 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1465 <BOLD>--- a/lines.txt<RESET>
1466 <BOLD>+++ b/lines.txt<RESET>
1467 <CYAN>@@ -1,9 +1,9 @@<RESET>
1468 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1469 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1470 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1471 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1472 line 1<RESET>
1473 line 2<RESET>
1474 line 3<RESET>
1475 line 4<RESET>
1476 line 5<RESET>
1477 <MAGENTA>-long line 6<RESET>
1478 <MAGENTA>-long line 7<RESET>
1479 <MAGENTA>-long line 8<RESET>
1480 <RED>-long line 9<RESET>
1481 EOF
1482 test_cmp expected actual
1483'
1484
1485test_expect_success 'move detection ignoring whitespace changes' '
1486 git reset --hard &&
1487 # Lines 6-8 have a space change, but 9 is new whitespace
1488 q_to_tab <<-\EOF >lines.txt &&
1489 longQline 6
1490 longQline 7
1491 longQline 8
1492 long liQne 9
1493 line 1
1494 line 2
1495 line 3
1496 line 4
1497 line 5
1498 EOF
1499
1500 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1501 grep -v "index" actual.raw | test_decode_color >actual &&
1502 cat <<-\EOF >expected &&
1503 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1504 <BOLD>--- a/lines.txt<RESET>
1505 <BOLD>+++ b/lines.txt<RESET>
1506 <CYAN>@@ -1,9 +1,9 @@<RESET>
1507 <GREEN>+<RESET><GREEN>long line 6<RESET>
1508 <GREEN>+<RESET><GREEN>long line 7<RESET>
1509 <GREEN>+<RESET><GREEN>long line 8<RESET>
1510 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1511 line 1<RESET>
1512 line 2<RESET>
1513 line 3<RESET>
1514 line 4<RESET>
1515 line 5<RESET>
1516 <RED>-long line 6<RESET>
1517 <RED>-long line 7<RESET>
1518 <RED>-long line 8<RESET>
1519 <RED>-long line 9<RESET>
1520 EOF
1521 test_cmp expected actual &&
1522
1523 git diff HEAD --no-renames --color-moved --color \
1524 --color-moved-ws=ignore-space-change >actual.raw &&
1525 grep -v "index" actual.raw | test_decode_color >actual &&
1526 cat <<-\EOF >expected &&
1527 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1528 <BOLD>--- a/lines.txt<RESET>
1529 <BOLD>+++ b/lines.txt<RESET>
1530 <CYAN>@@ -1,9 +1,9 @@<RESET>
1531 <CYAN>+<RESET><CYAN>long line 6<RESET>
1532 <CYAN>+<RESET><CYAN>long line 7<RESET>
1533 <CYAN>+<RESET><CYAN>long line 8<RESET>
1534 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1535 line 1<RESET>
1536 line 2<RESET>
1537 line 3<RESET>
1538 line 4<RESET>
1539 line 5<RESET>
1540 <MAGENTA>-long line 6<RESET>
1541 <MAGENTA>-long line 7<RESET>
1542 <MAGENTA>-long line 8<RESET>
1543 <RED>-long line 9<RESET>
1544 EOF
1545 test_cmp expected actual
1546'
1547
1548test_expect_success 'move detection ignoring whitespace at eol' '
1549 git reset --hard &&
1550 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1551 q_to_tab <<-\EOF >lines.txt &&
1552 long line 6Q
1553 long line 7Q
1554 long line 8Q
1555 longQline 9Q
1556 line 1
1557 line 2
1558 line 3
1559 line 4
1560 line 5
1561 EOF
1562
1563 # avoid cluttering the output with complaints about our eol whitespace
1564 test_config core.whitespace -blank-at-eol &&
1565
1566 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1567 grep -v "index" actual.raw | test_decode_color >actual &&
1568 cat <<-\EOF >expected &&
1569 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1570 <BOLD>--- a/lines.txt<RESET>
1571 <BOLD>+++ b/lines.txt<RESET>
1572 <CYAN>@@ -1,9 +1,9 @@<RESET>
1573 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1574 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1575 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1576 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1577 line 1<RESET>
1578 line 2<RESET>
1579 line 3<RESET>
1580 line 4<RESET>
1581 line 5<RESET>
1582 <RED>-long line 6<RESET>
1583 <RED>-long line 7<RESET>
1584 <RED>-long line 8<RESET>
1585 <RED>-long line 9<RESET>
1586 EOF
1587 test_cmp expected actual &&
1588
1589 git diff HEAD --no-renames --color-moved --color \
1590 --color-moved-ws=ignore-space-at-eol >actual.raw &&
1591 grep -v "index" actual.raw | test_decode_color >actual &&
1592 cat <<-\EOF >expected &&
1593 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1594 <BOLD>--- a/lines.txt<RESET>
1595 <BOLD>+++ b/lines.txt<RESET>
1596 <CYAN>@@ -1,9 +1,9 @@<RESET>
1597 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1598 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1599 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1600 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1601 line 1<RESET>
1602 line 2<RESET>
1603 line 3<RESET>
1604 line 4<RESET>
1605 line 5<RESET>
1606 <MAGENTA>-long line 6<RESET>
1607 <MAGENTA>-long line 7<RESET>
1608 <MAGENTA>-long line 8<RESET>
1609 <RED>-long line 9<RESET>
1610 EOF
1611 test_cmp expected actual
1612'
1613
1614test_expect_success 'clean up whitespace-test colors' '
1615 git config --unset color.diff.oldMoved &&
1616 git config --unset color.diff.newMoved
1617'
1618
1619test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1620 git reset --hard &&
1621 >bar &&
1622 cat <<-\EOF >foo &&
1623 irrelevant_line
1624 line1
1625 EOF
1626 git add foo bar &&
1627 git commit -m x &&
1628
1629 cat <<-\EOF >bar &&
1630 line1
1631 EOF
1632 cat <<-\EOF >foo &&
1633 irrelevant_line
1634 EOF
1635
1636 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1637 grep -v "index" actual.raw | test_decode_color >actual &&
1638 cat >expected <<-\EOF &&
1639 <BOLD>diff --git a/bar b/bar<RESET>
1640 <BOLD>--- a/bar<RESET>
1641 <BOLD>+++ b/bar<RESET>
1642 <CYAN>@@ -0,0 +1 @@<RESET>
1643 <GREEN>+<RESET><GREEN>line1<RESET>
1644 <BOLD>diff --git a/foo b/foo<RESET>
1645 <BOLD>--- a/foo<RESET>
1646 <BOLD>+++ b/foo<RESET>
1647 <CYAN>@@ -1,2 +1 @@<RESET>
1648 irrelevant_line<RESET>
1649 <RED>-line1<RESET>
1650 EOF
1651
1652 test_cmp expected actual
1653'
1654
1655test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
1656 git reset --hard &&
1657 cat <<-\EOF >foo &&
1658 nineteen chars 456789
1659 irrelevant_line
1660 twenty chars 234567890
1661 EOF
1662 >bar &&
1663 git add foo bar &&
1664 git commit -m x &&
1665
1666 cat <<-\EOF >foo &&
1667 irrelevant_line
1668 EOF
1669 cat <<-\EOF >bar &&
1670 twenty chars 234567890
1671 nineteen chars 456789
1672 EOF
1673
1674 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1675 grep -v "index" actual.raw | test_decode_color >actual &&
1676 cat >expected <<-\EOF &&
1677 <BOLD>diff --git a/bar b/bar<RESET>
1678 <BOLD>--- a/bar<RESET>
1679 <BOLD>+++ b/bar<RESET>
1680 <CYAN>@@ -0,0 +1,2 @@<RESET>
1681 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1682 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1683 <BOLD>diff --git a/foo b/foo<RESET>
1684 <BOLD>--- a/foo<RESET>
1685 <BOLD>+++ b/foo<RESET>
1686 <CYAN>@@ -1,3 +1 @@<RESET>
1687 <RED>-nineteen chars 456789<RESET>
1688 irrelevant_line<RESET>
1689 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1690 EOF
1691
1692 test_cmp expected actual
1693'
1694
1695test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1696 git reset --hard &&
1697 cat <<-\EOF >foo &&
1698 7charsA
1699 irrelevant_line
1700 7charsB
1701 7charsC
1702 EOF
1703 >bar &&
1704 git add foo bar &&
1705 git commit -m x &&
1706
1707 cat <<-\EOF >foo &&
1708 irrelevant_line
1709 EOF
1710 cat <<-\EOF >bar &&
1711 7charsB
1712 7charsC
1713 7charsA
1714 EOF
1715
1716 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1717 grep -v "index" actual.raw | test_decode_color >actual &&
1718 cat >expected <<-\EOF &&
1719 <BOLD>diff --git a/bar b/bar<RESET>
1720 <BOLD>--- a/bar<RESET>
1721 <BOLD>+++ b/bar<RESET>
1722 <CYAN>@@ -0,0 +1,3 @@<RESET>
1723 <GREEN>+<RESET><GREEN>7charsB<RESET>
1724 <GREEN>+<RESET><GREEN>7charsC<RESET>
1725 <GREEN>+<RESET><GREEN>7charsA<RESET>
1726 <BOLD>diff --git a/foo b/foo<RESET>
1727 <BOLD>--- a/foo<RESET>
1728 <BOLD>+++ b/foo<RESET>
1729 <CYAN>@@ -1,4 +1 @@<RESET>
1730 <RED>-7charsA<RESET>
1731 irrelevant_line<RESET>
1732 <RED>-7charsB<RESET>
1733 <RED>-7charsC<RESET>
1734 EOF
1735
1736 test_cmp expected actual
1737'
1738
1739test_expect_success 'move detection with submodules' '
1740 test_create_repo bananas &&
1741 echo ripe >bananas/recipe &&
1742 git -C bananas add recipe &&
1743 test_commit fruit &&
1744 test_commit -C bananas recipe &&
1745 git submodule add ./bananas &&
1746 git add bananas &&
1747 git commit -a -m "bananas are like a heavy library?" &&
1748 echo foul >bananas/recipe &&
1749 echo ripe >fruit.t &&
1750
1751 git diff --submodule=diff --color-moved --color >actual &&
1752
1753 # no move detection as the moved line is across repository boundaries.
1754 test_decode_color <actual >decoded_actual &&
1755 ! grep BGREEN decoded_actual &&
1756 ! grep BRED decoded_actual &&
1757
1758 # nor did we mess with it another way
1759 git diff --submodule=diff --color | test_decode_color >expect &&
1760 test_cmp expect decoded_actual &&
1761 rm -rf bananas &&
1762 git submodule deinit bananas
1763'
1764
1765test_expect_success 'only move detection ignores white spaces' '
1766 git reset --hard &&
1767 q_to_tab <<-\EOF >text.txt &&
1768 a long line to exceed per-line minimum
1769 another long line to exceed per-line minimum
1770 original file
1771 EOF
1772 git add text.txt &&
1773 git commit -m "add text" &&
1774 q_to_tab <<-\EOF >text.txt &&
1775 Qa long line to exceed per-line minimum
1776 Qanother long line to exceed per-line minimum
1777 new file
1778 EOF
1779
1780 # Make sure we get a different diff using -w
1781 git diff --color --color-moved -w >actual.raw &&
1782 grep -v "index" actual.raw | test_decode_color >actual &&
1783 q_to_tab <<-\EOF >expected &&
1784 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1785 <BOLD>--- a/text.txt<RESET>
1786 <BOLD>+++ b/text.txt<RESET>
1787 <CYAN>@@ -1,3 +1,3 @@<RESET>
1788 Qa long line to exceed per-line minimum<RESET>
1789 Qanother long line to exceed per-line minimum<RESET>
1790 <RED>-original file<RESET>
1791 <GREEN>+<RESET><GREEN>new file<RESET>
1792 EOF
1793 test_cmp expected actual &&
1794
1795 # And now ignoring white space only in the move detection
1796 git diff --color --color-moved \
1797 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
1798 grep -v "index" actual.raw | test_decode_color >actual &&
1799 q_to_tab <<-\EOF >expected &&
1800 <BOLD>diff --git a/text.txt b/text.txt<RESET>
1801 <BOLD>--- a/text.txt<RESET>
1802 <BOLD>+++ b/text.txt<RESET>
1803 <CYAN>@@ -1,3 +1,3 @@<RESET>
1804 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
1805 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
1806 <RED>-original file<RESET>
1807 <BOLD;YELLOW>+<RESET>Q<BOLD;YELLOW>a long line to exceed per-line minimum<RESET>
1808 <BOLD;YELLOW>+<RESET>Q<BOLD;YELLOW>another long line to exceed per-line minimum<RESET>
1809 <GREEN>+<RESET><GREEN>new file<RESET>
1810 EOF
1811 test_cmp expected actual
1812'
1813
1814test_expect_success 'compare whitespace delta across moved blocks' '
1815
1816 git reset --hard &&
1817 q_to_tab <<-\EOF >text.txt &&
1818 QIndented
1819 QText across
1820 Qsome lines
1821 QBut! <- this stands out
1822 QAdjusting with
1823 QQdifferent starting
1824 Qwhite spaces
1825 QAnother outlier
1826 QQQIndented
1827 QQQText across
1828 QQQfive lines
1829 QQQthat has similar lines
1830 QQQto previous blocks, but with different indent
1831 QQQYetQAnotherQoutlierQ
1832 EOF
1833
1834 git add text.txt &&
1835 git commit -m "add text.txt" &&
1836
1837 q_to_tab <<-\EOF >text.txt &&
1838 QQIndented
1839 QQText across
1840 QQsome lines
1841 QQQBut! <- this stands out
1842 Adjusting with
1843 Qdifferent starting
1844 white spaces
1845 AnotherQoutlier
1846 QQIndented
1847 QQText across
1848 QQfive lines
1849 QQthat has similar lines
1850 QQto previous blocks, but with different indent
1851 QQYetQAnotherQoutlier
1852 EOF
1853
1854 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
1855 grep -v "index" actual.raw | test_decode_color >actual &&
1856
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,14 +1,14 @@<RESET>
1862 <BOLD;MAGENTA>-QIndented<RESET>
1863 <BOLD;MAGENTA>-QText across<RESET>
1864 <BOLD;MAGENTA>-Qsome lines<RESET>
1865 <RED>-QBut! <- this stands out<RESET>
1866 <BOLD;MAGENTA>-QAdjusting with<RESET>
1867 <BOLD;MAGENTA>-QQdifferent starting<RESET>
1868 <BOLD;MAGENTA>-Qwhite spaces<RESET>
1869 <RED>-QAnother outlier<RESET>
1870 <BOLD;MAGENTA>-QQQIndented<RESET>
1871 <BOLD;MAGENTA>-QQQText across<RESET>
1872 <BOLD;MAGENTA>-QQQfive lines<RESET>
1873 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
1874 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
1875 <RED>-QQQYetQAnotherQoutlierQ<RESET>
1876 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1877 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1878 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
1879 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
1880 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
1881 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
1882 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
1883 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
1884 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
1885 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
1886 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
1887 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
1888 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
1889 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
1890 EOF
1891
1892 test_cmp expected actual
1893'
1894
1895test_expect_success 'compare whitespace delta incompatible with other space options' '
1896 test_must_fail git diff \
1897 --color-moved-ws=allow-indentation-change,ignore-all-space \
1898 2>err &&
1899 test_i18ngrep allow-indentation-change err
1900'
1901
1902test_done