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