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