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