]> git.ipfire.org Git - thirdparty/git.git/blob - t/t4015-diff-whitespace.sh
Merge branch 'en/fetch-negotiation-default-fix'
[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"/lib-diff.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 '-w and --exit-code interact sensibly' '
571 test_when_finished "git checkout x" &&
572 {
573 test_seq 15 &&
574 echo " 16"
575 } >x &&
576 test_must_fail git diff --exit-code &&
577 git diff -w >actual &&
578 test_must_be_empty actual &&
579 git diff -w --exit-code
580 '
581
582 test_expect_success '-I and --exit-code interact sensibly' '
583 test_when_finished "git checkout x" &&
584 {
585 test_seq 15 &&
586 echo " 16"
587 } >x &&
588 test_must_fail git diff --exit-code &&
589 git diff -I. >actual &&
590 test_must_be_empty actual &&
591 git diff -I. --exit-code
592 '
593
594 test_expect_success 'check staged with no whitespace errors' '
595 echo "foo();" >x &&
596 git add x &&
597 git diff --cached --check
598 '
599
600 test_expect_success 'check staged with trailing whitespace' '
601 echo "foo(); " >x &&
602 git add x &&
603 test_must_fail git diff --cached --check
604 '
605
606 test_expect_success 'check staged with space before tab in indent' '
607 # indent has space followed by hard tab
608 echo " foo();" >x &&
609 git add x &&
610 test_must_fail git diff --cached --check
611 '
612
613 test_expect_success 'check with no whitespace errors (diff-index)' '
614 echo "foo();" >x &&
615 git add x &&
616 git diff-index --check HEAD
617 '
618
619 test_expect_success 'check with trailing whitespace (diff-index)' '
620 echo "foo(); " >x &&
621 git add x &&
622 test_must_fail git diff-index --check HEAD
623 '
624
625 test_expect_success 'check with space before tab in indent (diff-index)' '
626 # indent has space followed by hard tab
627 echo " foo();" >x &&
628 git add x &&
629 test_must_fail git diff-index --check HEAD
630 '
631
632 test_expect_success 'check staged with no whitespace errors (diff-index)' '
633 echo "foo();" >x &&
634 git add x &&
635 git diff-index --cached --check HEAD
636 '
637
638 test_expect_success 'check staged with trailing whitespace (diff-index)' '
639 echo "foo(); " >x &&
640 git add x &&
641 test_must_fail git diff-index --cached --check HEAD
642 '
643
644 test_expect_success 'check staged with space before tab in indent (diff-index)' '
645 # indent has space followed by hard tab
646 echo " foo();" >x &&
647 git add x &&
648 test_must_fail git diff-index --cached --check HEAD
649 '
650
651 test_expect_success 'check with no whitespace errors (diff-tree)' '
652 echo "foo();" >x &&
653 git commit -m "new commit" x &&
654 git diff-tree --check HEAD^ HEAD
655 '
656
657 test_expect_success 'check with trailing whitespace (diff-tree)' '
658 echo "foo(); " >x &&
659 git commit -m "another commit" x &&
660 test_must_fail git diff-tree --check HEAD^ HEAD
661 '
662
663 test_expect_success 'check with space before tab in indent (diff-tree)' '
664 # indent has space followed by hard tab
665 echo " foo();" >x &&
666 git commit -m "yet another" x &&
667 test_must_fail git diff-tree --check HEAD^ HEAD
668 '
669
670 test_expect_success 'check with ignored trailing whitespace attr (diff-tree)' '
671 test_when_finished "git reset --hard HEAD^" &&
672
673 # create a whitespace error that should be ignored
674 echo "* -whitespace" >.gitattributes &&
675 git add .gitattributes &&
676 echo "foo(); " >x &&
677 git add x &&
678 git commit -m "add trailing space" &&
679
680 # with a worktree diff-tree ignores the whitespace error
681 git diff-tree --root --check HEAD &&
682
683 # without a worktree diff-tree still ignores the whitespace error
684 git -C .git diff-tree --root --check HEAD
685 '
686
687 test_expect_success 'check trailing whitespace (trailing-space: off)' '
688 git config core.whitespace "-trailing-space" &&
689 echo "foo (); " >x &&
690 git diff --check
691 '
692
693 test_expect_success 'check trailing whitespace (trailing-space: on)' '
694 git config core.whitespace "trailing-space" &&
695 echo "foo (); " >x &&
696 test_must_fail git diff --check
697 '
698
699 test_expect_success 'check space before tab in indent (space-before-tab: off)' '
700 # indent contains space followed by HT
701 git config core.whitespace "-space-before-tab" &&
702 echo " foo ();" >x &&
703 git diff --check
704 '
705
706 test_expect_success 'check space before tab in indent (space-before-tab: on)' '
707 # indent contains space followed by HT
708 git config core.whitespace "space-before-tab" &&
709 echo " foo (); " >x &&
710 test_must_fail git diff --check
711 '
712
713 test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
714 git config core.whitespace "-indent-with-non-tab" &&
715 echo " foo ();" >x &&
716 git diff --check
717 '
718
719 test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
720 git config core.whitespace "indent-with-non-tab" &&
721 echo " foo ();" >x &&
722 test_must_fail git diff --check
723 '
724
725 test_expect_success 'ditto, but tabwidth=9' '
726 git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
727 git diff --check
728 '
729
730 test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
731 git config core.whitespace "indent-with-non-tab" &&
732 echo " foo ();" >x &&
733 test_must_fail git diff --check
734 '
735
736 test_expect_success 'ditto, but tabwidth=10' '
737 git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
738 test_must_fail git diff --check
739 '
740
741 test_expect_success 'ditto, but tabwidth=20' '
742 git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
743 git diff --check
744 '
745
746 test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
747 git config core.whitespace "-tab-in-indent" &&
748 echo " foo ();" >x &&
749 git diff --check
750 '
751
752 test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
753 git config core.whitespace "tab-in-indent" &&
754 echo " foo ();" >x &&
755 test_must_fail git diff --check
756 '
757
758 test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
759 git config core.whitespace "tab-in-indent" &&
760 echo " foo ();" >x &&
761 test_must_fail git diff --check
762 '
763
764 test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
765 git config core.whitespace "tab-in-indent,tabwidth=1" &&
766 test_must_fail git diff --check
767 '
768
769 test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
770 git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
771 echo "foo ();" >x &&
772 test_must_fail git diff --check
773 '
774
775 test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
776 git config --unset core.whitespace &&
777 echo "x whitespace" >.gitattributes &&
778 echo " foo ();" >x &&
779 git diff --check &&
780 rm -f .gitattributes
781 '
782
783 test_expect_success 'line numbers in --check output are correct' '
784 echo "" >x &&
785 echo "foo(); " >>x &&
786 test_must_fail git diff --check >check &&
787 grep "x:2:" check
788 '
789
790 test_expect_success 'checkdiff detects new trailing blank lines (1)' '
791 echo "foo();" >x &&
792 echo "" >>x &&
793 test_must_fail git diff --check >check &&
794 grep "new blank line" check
795 '
796
797 test_expect_success 'checkdiff detects new trailing blank lines (2)' '
798 test_write_lines a b "" "" >x &&
799 git add x &&
800 test_write_lines a "" "" "" "" >x &&
801 test_must_fail git diff --check >check &&
802 grep "new blank line" check
803 '
804
805 test_expect_success 'checkdiff allows new blank lines' '
806 git checkout x &&
807 mv x y &&
808 (
809 echo "/* This is new */" &&
810 echo "" &&
811 cat y
812 ) >x &&
813 git diff --check
814 '
815
816 test_expect_success 'whitespace-only changes not reported (diff)' '
817 git reset --hard &&
818 echo >x "hello world" &&
819 git add x &&
820 git commit -m "hello 1" &&
821 echo >x "hello world" &&
822 git diff -b >actual &&
823 test_must_be_empty actual
824 '
825
826 test_expect_success 'whitespace-only changes not reported (diffstat)' '
827 # reuse state from previous test
828 git diff --stat -b >actual &&
829 test_must_be_empty actual
830 '
831
832 test_expect_success 'whitespace changes with modification reported (diffstat)' '
833 git reset --hard &&
834 echo >x "hello world" &&
835 git update-index --chmod=+x x &&
836 git diff --stat --cached -b >actual &&
837 cat <<-EOF >expect &&
838 x | 0
839 1 file changed, 0 insertions(+), 0 deletions(-)
840 EOF
841 test_cmp expect actual
842 '
843
844 test_expect_success 'whitespace-only changes reported across renames (diffstat)' '
845 git reset --hard &&
846 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i" || return 1; done >x &&
847 git add x &&
848 git commit -m "base" &&
849 sed -e "5s/^/ /" x >z &&
850 git rm x &&
851 git add z &&
852 git diff -w -M --cached --stat >actual &&
853 cat <<-EOF >expect &&
854 x => z | 0
855 1 file changed, 0 insertions(+), 0 deletions(-)
856 EOF
857 test_cmp expect actual
858 '
859
860 test_expect_success 'whitespace-only changes reported across renames' '
861 git reset --hard HEAD~1 &&
862 for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i" || return 1; done >x &&
863 git add x &&
864 hash_x=$(git hash-object x) &&
865 before=$(git rev-parse --short "$hash_x") &&
866 git commit -m "base" &&
867 sed -e "5s/^/ /" x >z &&
868 git rm x &&
869 git add z &&
870 hash_z=$(git hash-object z) &&
871 after=$(git rev-parse --short "$hash_z") &&
872 git diff -w -M --cached >actual.raw &&
873 sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" actual.raw >actual &&
874 cat <<-EOF >expect &&
875 diff --git a/x b/z
876 similarity index NUM%
877 rename from x
878 rename to z
879 index $before..$after 100644
880 EOF
881 test_cmp expect actual
882 '
883
884 cat >expected <<\EOF
885 diff --git a/empty b/void
886 similarity index 100%
887 rename from empty
888 rename to void
889 EOF
890
891 test_expect_success 'rename empty' '
892 git reset --hard &&
893 >empty &&
894 git add empty &&
895 git commit -m empty &&
896 git mv empty void &&
897 git diff -w --cached -M >current &&
898 test_cmp expected current
899 '
900
901 test_expect_success 'combined diff with autocrlf conversion' '
902
903 git reset --hard &&
904 test_commit "one side" x hello one-side &&
905 git checkout HEAD^ &&
906 echo >x goodbye &&
907 git commit -m "the other side" x &&
908 git config core.autocrlf true &&
909 test_must_fail git merge one-side >actual &&
910 test_i18ngrep "Automatic merge failed" actual &&
911
912 git diff >actual.raw &&
913 sed -e "1,/^@@@/d" actual.raw >actual &&
914 ! grep "^-" actual
915
916 '
917
918 # Start testing the colored format for whitespace checks
919
920 test_expect_success 'setup diff colors' '
921 git config color.diff.plain normal &&
922 git config color.diff.meta bold &&
923 git config color.diff.frag cyan &&
924 git config color.diff.func normal &&
925 git config color.diff.old red &&
926 git config color.diff.new green &&
927 git config color.diff.commit yellow &&
928 git config color.diff.whitespace blue &&
929
930 git config core.autocrlf false
931 '
932
933 test_expect_success 'diff that introduces a line with only tabs' '
934 git config core.whitespace blank-at-eol &&
935 git reset --hard &&
936 echo "test" >x &&
937 old_hash_x=$(git hash-object x) &&
938 before=$(git rev-parse --short "$old_hash_x") &&
939 git commit -m "initial" x &&
940 echo "{NTN}" | tr "NT" "\n\t" >>x &&
941 new_hash_x=$(git hash-object x) &&
942 after=$(git rev-parse --short "$new_hash_x") &&
943 git diff --color >current.raw &&
944 test_decode_color <current.raw >current &&
945
946 cat >expected <<-EOF &&
947 <BOLD>diff --git a/x b/x<RESET>
948 <BOLD>index $before..$after 100644<RESET>
949 <BOLD>--- a/x<RESET>
950 <BOLD>+++ b/x<RESET>
951 <CYAN>@@ -1 +1,4 @@<RESET>
952 test<RESET>
953 <GREEN>+<RESET><GREEN>{<RESET>
954 <GREEN>+<RESET><BLUE> <RESET>
955 <GREEN>+<RESET><GREEN>}<RESET>
956 EOF
957
958 test_cmp expected current
959 '
960
961 test_expect_success 'diff that introduces and removes ws breakages' '
962 git reset --hard &&
963 {
964 echo "0. blank-at-eol " &&
965 echo "1. blank-at-eol "
966 } >x &&
967 old_hash_x=$(git hash-object x) &&
968 before=$(git rev-parse --short "$old_hash_x") &&
969 git commit -a --allow-empty -m preimage &&
970 {
971 echo "0. blank-at-eol " &&
972 echo "1. still-blank-at-eol " &&
973 echo "2. and a new line "
974 } >x &&
975 new_hash_x=$(git hash-object x) &&
976 after=$(git rev-parse --short "$new_hash_x") &&
977
978 git diff --color >current.raw &&
979 test_decode_color <current.raw >current &&
980
981 cat >expected <<-EOF &&
982 <BOLD>diff --git a/x b/x<RESET>
983 <BOLD>index $before..$after 100644<RESET>
984 <BOLD>--- a/x<RESET>
985 <BOLD>+++ b/x<RESET>
986 <CYAN>@@ -1,2 +1,3 @@<RESET>
987 0. blank-at-eol <RESET>
988 <RED>-1. blank-at-eol <RESET>
989 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
990 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
991 EOF
992
993 test_cmp expected current
994 '
995
996 test_expect_success 'ws-error-highlight test setup' '
997
998 git reset --hard &&
999 {
1000 echo "0. blank-at-eol " &&
1001 echo "1. blank-at-eol "
1002 } >x &&
1003 old_hash_x=$(git hash-object x) &&
1004 before=$(git rev-parse --short "$old_hash_x") &&
1005 git commit -a --allow-empty -m preimage &&
1006 {
1007 echo "0. blank-at-eol " &&
1008 echo "1. still-blank-at-eol " &&
1009 echo "2. and a new line "
1010 } >x &&
1011 new_hash_x=$(git hash-object x) &&
1012 after=$(git rev-parse --short "$new_hash_x") &&
1013
1014 cat >expect.default-old <<-EOF &&
1015 <BOLD>diff --git a/x b/x<RESET>
1016 <BOLD>index $before..$after 100644<RESET>
1017 <BOLD>--- a/x<RESET>
1018 <BOLD>+++ b/x<RESET>
1019 <CYAN>@@ -1,2 +1,3 @@<RESET>
1020 0. blank-at-eol <RESET>
1021 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1022 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1023 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1024 EOF
1025
1026 cat >expect.all <<-EOF &&
1027 <BOLD>diff --git a/x b/x<RESET>
1028 <BOLD>index $before..$after 100644<RESET>
1029 <BOLD>--- a/x<RESET>
1030 <BOLD>+++ b/x<RESET>
1031 <CYAN>@@ -1,2 +1,3 @@<RESET>
1032 <RESET>0. blank-at-eol<RESET><BLUE> <RESET>
1033 <RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
1034 <GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
1035 <GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
1036 EOF
1037
1038 cat >expect.none <<-EOF
1039 <BOLD>diff --git a/x b/x<RESET>
1040 <BOLD>index $before..$after 100644<RESET>
1041 <BOLD>--- a/x<RESET>
1042 <BOLD>+++ b/x<RESET>
1043 <CYAN>@@ -1,2 +1,3 @@<RESET>
1044 0. blank-at-eol <RESET>
1045 <RED>-1. blank-at-eol <RESET>
1046 <GREEN>+1. still-blank-at-eol <RESET>
1047 <GREEN>+2. and a new line <RESET>
1048 EOF
1049
1050 '
1051
1052 test_expect_success 'test --ws-error-highlight option' '
1053
1054 git diff --color --ws-error-highlight=default,old >current.raw &&
1055 test_decode_color <current.raw >current &&
1056 test_cmp expect.default-old current &&
1057
1058 git diff --color --ws-error-highlight=all >current.raw &&
1059 test_decode_color <current.raw >current &&
1060 test_cmp expect.all current &&
1061
1062 git diff --color --ws-error-highlight=none >current.raw &&
1063 test_decode_color <current.raw >current &&
1064 test_cmp expect.none current
1065
1066 '
1067
1068 test_expect_success 'test diff.wsErrorHighlight config' '
1069
1070 git -c diff.wsErrorHighlight=default,old diff --color >current.raw &&
1071 test_decode_color <current.raw >current &&
1072 test_cmp expect.default-old current &&
1073
1074 git -c diff.wsErrorHighlight=all diff --color >current.raw &&
1075 test_decode_color <current.raw >current &&
1076 test_cmp expect.all current &&
1077
1078 git -c diff.wsErrorHighlight=none diff --color >current.raw &&
1079 test_decode_color <current.raw >current &&
1080 test_cmp expect.none current
1081
1082 '
1083
1084 test_expect_success 'option overrides diff.wsErrorHighlight' '
1085
1086 git -c diff.wsErrorHighlight=none \
1087 diff --color --ws-error-highlight=default,old >current.raw &&
1088 test_decode_color <current.raw >current &&
1089 test_cmp expect.default-old current &&
1090
1091 git -c diff.wsErrorHighlight=default \
1092 diff --color --ws-error-highlight=all >current.raw &&
1093 test_decode_color <current.raw >current &&
1094 test_cmp expect.all current &&
1095
1096 git -c diff.wsErrorHighlight=all \
1097 diff --color --ws-error-highlight=none >current.raw &&
1098 test_decode_color <current.raw >current &&
1099 test_cmp expect.none current
1100
1101 '
1102
1103 test_expect_success 'detect moved code, complete file' '
1104 git reset --hard &&
1105 cat <<-\EOF >test.c &&
1106 #include<stdio.h>
1107 main()
1108 {
1109 printf("Hello World");
1110 }
1111 EOF
1112 git add test.c &&
1113 git commit -m "add main function" &&
1114 file=$(git rev-parse --short HEAD:test.c) &&
1115 git mv test.c main.c &&
1116 test_config color.diff.oldMoved "normal red" &&
1117 test_config color.diff.newMoved "normal green" &&
1118 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1119 test_decode_color <actual.raw >actual &&
1120 cat >expected <<-EOF &&
1121 <BOLD>diff --git a/main.c b/main.c<RESET>
1122 <BOLD>new file mode 100644<RESET>
1123 <BOLD>index 0000000..$file<RESET>
1124 <BOLD>--- /dev/null<RESET>
1125 <BOLD>+++ b/main.c<RESET>
1126 <CYAN>@@ -0,0 +1,5 @@<RESET>
1127 <BGREEN>+<RESET><BGREEN>#include<stdio.h><RESET>
1128 <BGREEN>+<RESET><BGREEN>main()<RESET>
1129 <BGREEN>+<RESET><BGREEN>{<RESET>
1130 <BGREEN>+<RESET><BGREEN>printf("Hello World");<RESET>
1131 <BGREEN>+<RESET><BGREEN>}<RESET>
1132 <BOLD>diff --git a/test.c b/test.c<RESET>
1133 <BOLD>deleted file mode 100644<RESET>
1134 <BOLD>index $file..0000000<RESET>
1135 <BOLD>--- a/test.c<RESET>
1136 <BOLD>+++ /dev/null<RESET>
1137 <CYAN>@@ -1,5 +0,0 @@<RESET>
1138 <BRED>-#include<stdio.h><RESET>
1139 <BRED>-main()<RESET>
1140 <BRED>-{<RESET>
1141 <BRED>-printf("Hello World");<RESET>
1142 <BRED>-}<RESET>
1143 EOF
1144
1145 test_cmp expected actual
1146 '
1147
1148 test_expect_success 'detect malicious moved code, inside file' '
1149 test_config color.diff.oldMoved "normal red" &&
1150 test_config color.diff.newMoved "normal green" &&
1151 test_config color.diff.oldMovedAlternative "blue" &&
1152 test_config color.diff.newMovedAlternative "yellow" &&
1153 git reset --hard &&
1154 cat <<-\EOF >main.c &&
1155 #include<stdio.h>
1156 int stuff()
1157 {
1158 printf("Hello ");
1159 printf("World\n");
1160 }
1161
1162 int secure_foo(struct user *u)
1163 {
1164 if (!u->is_allowed_foo)
1165 return;
1166 foo(u);
1167 }
1168
1169 int main()
1170 {
1171 foo();
1172 }
1173 EOF
1174 cat <<-\EOF >test.c &&
1175 #include<stdio.h>
1176 int bar()
1177 {
1178 printf("Hello World, but different\n");
1179 }
1180
1181 int another_function()
1182 {
1183 bar();
1184 }
1185 EOF
1186 git add main.c test.c &&
1187 git commit -m "add main and test file" &&
1188 before_main=$(git rev-parse --short HEAD:main.c) &&
1189 before_test=$(git rev-parse --short HEAD:test.c) &&
1190 cat <<-\EOF >main.c &&
1191 #include<stdio.h>
1192 int stuff()
1193 {
1194 printf("Hello ");
1195 printf("World\n");
1196 }
1197
1198 int main()
1199 {
1200 foo();
1201 }
1202 EOF
1203 cat <<-\EOF >test.c &&
1204 #include<stdio.h>
1205 int bar()
1206 {
1207 printf("Hello World, but different\n");
1208 }
1209
1210 int secure_foo(struct user *u)
1211 {
1212 foo(u);
1213 if (!u->is_allowed_foo)
1214 return;
1215 }
1216
1217 int another_function()
1218 {
1219 bar();
1220 }
1221 EOF
1222 hash_main=$(git hash-object main.c) &&
1223 after_main=$(git rev-parse --short "$hash_main") &&
1224 hash_test=$(git hash-object test.c) &&
1225 after_test=$(git rev-parse --short "$hash_test") &&
1226 git diff HEAD --no-renames --color-moved=zebra --color >actual.raw &&
1227 test_decode_color <actual.raw >actual &&
1228 cat <<-EOF >expected &&
1229 <BOLD>diff --git a/main.c b/main.c<RESET>
1230 <BOLD>index $before_main..$after_main 100644<RESET>
1231 <BOLD>--- a/main.c<RESET>
1232 <BOLD>+++ b/main.c<RESET>
1233 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1234 printf("World\n");<RESET>
1235 }<RESET>
1236 <RESET>
1237 <BRED>-int secure_foo(struct user *u)<RESET>
1238 <BRED>-{<RESET>
1239 <BLUE>-if (!u->is_allowed_foo)<RESET>
1240 <BLUE>-return;<RESET>
1241 <RED>-foo(u);<RESET>
1242 <RED>-}<RESET>
1243 <RED>-<RESET>
1244 int main()<RESET>
1245 {<RESET>
1246 foo();<RESET>
1247 <BOLD>diff --git a/test.c b/test.c<RESET>
1248 <BOLD>index $before_test..$after_test 100644<RESET>
1249 <BOLD>--- a/test.c<RESET>
1250 <BOLD>+++ b/test.c<RESET>
1251 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1252 printf("Hello World, but different\n");<RESET>
1253 }<RESET>
1254 <RESET>
1255 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1256 <BGREEN>+<RESET><BGREEN>{<RESET>
1257 <GREEN>+<RESET><GREEN>foo(u);<RESET>
1258 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1259 <BGREEN>+<RESET><BGREEN>return;<RESET>
1260 <GREEN>+<RESET><GREEN>}<RESET>
1261 <GREEN>+<RESET>
1262 int another_function()<RESET>
1263 {<RESET>
1264 bar();<RESET>
1265 EOF
1266
1267 test_cmp expected actual
1268 '
1269
1270 test_expect_success 'plain moved code, inside file' '
1271 test_config color.diff.oldMoved "normal red" &&
1272 test_config color.diff.newMoved "normal green" &&
1273 test_config color.diff.oldMovedAlternative "blue" &&
1274 test_config color.diff.newMovedAlternative "yellow" &&
1275 # needs previous test as setup
1276 git diff HEAD --no-renames --color-moved=plain --color >actual.raw &&
1277 test_decode_color <actual.raw >actual &&
1278 cat <<-EOF >expected &&
1279 <BOLD>diff --git a/main.c b/main.c<RESET>
1280 <BOLD>index $before_main..$after_main 100644<RESET>
1281 <BOLD>--- a/main.c<RESET>
1282 <BOLD>+++ b/main.c<RESET>
1283 <CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
1284 printf("World\n");<RESET>
1285 }<RESET>
1286 <RESET>
1287 <BRED>-int secure_foo(struct user *u)<RESET>
1288 <BRED>-{<RESET>
1289 <BRED>-if (!u->is_allowed_foo)<RESET>
1290 <BRED>-return;<RESET>
1291 <BRED>-foo(u);<RESET>
1292 <BRED>-}<RESET>
1293 <BRED>-<RESET>
1294 int main()<RESET>
1295 {<RESET>
1296 foo();<RESET>
1297 <BOLD>diff --git a/test.c b/test.c<RESET>
1298 <BOLD>index $before_test..$after_test 100644<RESET>
1299 <BOLD>--- a/test.c<RESET>
1300 <BOLD>+++ b/test.c<RESET>
1301 <CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
1302 printf("Hello World, but different\n");<RESET>
1303 }<RESET>
1304 <RESET>
1305 <BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
1306 <BGREEN>+<RESET><BGREEN>{<RESET>
1307 <BGREEN>+<RESET><BGREEN>foo(u);<RESET>
1308 <BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
1309 <BGREEN>+<RESET><BGREEN>return;<RESET>
1310 <BGREEN>+<RESET><BGREEN>}<RESET>
1311 <BGREEN>+<RESET>
1312 int another_function()<RESET>
1313 {<RESET>
1314 bar();<RESET>
1315 EOF
1316
1317 test_cmp expected actual
1318 '
1319
1320 test_expect_success 'detect blocks of moved code' '
1321 git reset --hard &&
1322 cat <<-\EOF >lines.txt &&
1323 long line 1
1324 long line 2
1325 long line 3
1326 line 4
1327 line 5
1328 line 6
1329 line 7
1330 line 8
1331 line 9
1332 line 10
1333 line 11
1334 line 12
1335 line 13
1336 long line 14
1337 long line 15
1338 long line 16
1339 EOF
1340 git add lines.txt &&
1341 git commit -m "add poetry" &&
1342 cat <<-\EOF >lines.txt &&
1343 line 4
1344 line 5
1345 line 6
1346 line 7
1347 line 8
1348 line 9
1349 long line 1
1350 long line 2
1351 long line 3
1352 long line 14
1353 long line 15
1354 long line 16
1355 line 10
1356 line 11
1357 line 12
1358 line 13
1359 EOF
1360 test_config color.diff.oldMoved "magenta" &&
1361 test_config color.diff.newMoved "cyan" &&
1362 test_config color.diff.oldMovedAlternative "blue" &&
1363 test_config color.diff.newMovedAlternative "yellow" &&
1364 test_config color.diff.oldMovedDimmed "normal magenta" &&
1365 test_config color.diff.newMovedDimmed "normal cyan" &&
1366 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1367 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1368 git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1369 grep -v "index" actual.raw | test_decode_color >actual &&
1370 cat <<-\EOF >expected &&
1371 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1372 <BOLD>--- a/lines.txt<RESET>
1373 <BOLD>+++ b/lines.txt<RESET>
1374 <CYAN>@@ -1,16 +1,16 @@<RESET>
1375 <MAGENTA>-long line 1<RESET>
1376 <MAGENTA>-long line 2<RESET>
1377 <MAGENTA>-long line 3<RESET>
1378 line 4<RESET>
1379 line 5<RESET>
1380 line 6<RESET>
1381 line 7<RESET>
1382 line 8<RESET>
1383 line 9<RESET>
1384 <CYAN>+<RESET><CYAN>long line 1<RESET>
1385 <CYAN>+<RESET><CYAN>long line 2<RESET>
1386 <CYAN>+<RESET><CYAN>long line 3<RESET>
1387 <CYAN>+<RESET><CYAN>long line 14<RESET>
1388 <CYAN>+<RESET><CYAN>long line 15<RESET>
1389 <CYAN>+<RESET><CYAN>long line 16<RESET>
1390 line 10<RESET>
1391 line 11<RESET>
1392 line 12<RESET>
1393 line 13<RESET>
1394 <MAGENTA>-long line 14<RESET>
1395 <MAGENTA>-long line 15<RESET>
1396 <MAGENTA>-long line 16<RESET>
1397 EOF
1398 test_cmp expected actual
1399
1400 '
1401
1402 test_expect_success 'detect permutations inside moved code -- dimmed-zebra' '
1403 # reuse setup from test before!
1404 test_config color.diff.oldMoved "magenta" &&
1405 test_config color.diff.newMoved "cyan" &&
1406 test_config color.diff.oldMovedAlternative "blue" &&
1407 test_config color.diff.newMovedAlternative "yellow" &&
1408 test_config color.diff.oldMovedDimmed "normal magenta" &&
1409 test_config color.diff.newMovedDimmed "normal cyan" &&
1410 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1411 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1412 git diff HEAD --no-renames --color-moved=dimmed-zebra --color >actual.raw &&
1413 grep -v "index" actual.raw | test_decode_color >actual &&
1414 cat <<-\EOF >expected &&
1415 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1416 <BOLD>--- a/lines.txt<RESET>
1417 <BOLD>+++ b/lines.txt<RESET>
1418 <CYAN>@@ -1,16 +1,16 @@<RESET>
1419 <BMAGENTA>-long line 1<RESET>
1420 <BMAGENTA>-long line 2<RESET>
1421 <BMAGENTA>-long line 3<RESET>
1422 line 4<RESET>
1423 line 5<RESET>
1424 line 6<RESET>
1425 line 7<RESET>
1426 line 8<RESET>
1427 line 9<RESET>
1428 <BCYAN>+<RESET><BCYAN>long line 1<RESET>
1429 <BCYAN>+<RESET><BCYAN>long line 2<RESET>
1430 <CYAN>+<RESET><CYAN>long line 3<RESET>
1431 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1432 <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
1433 <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
1434 line 10<RESET>
1435 line 11<RESET>
1436 line 12<RESET>
1437 line 13<RESET>
1438 <BMAGENTA>-long line 14<RESET>
1439 <BMAGENTA>-long line 15<RESET>
1440 <BMAGENTA>-long line 16<RESET>
1441 EOF
1442 test_cmp expected actual
1443 '
1444
1445 test_expect_success 'zebra alternate color is only used when necessary' '
1446 cat >old.txt <<-\EOF &&
1447 line 1A should be marked as oldMoved newMovedAlternate
1448 line 1B should be marked as oldMoved newMovedAlternate
1449 unchanged
1450 line 2A should be marked as oldMoved newMovedAlternate
1451 line 2B should be marked as oldMoved newMovedAlternate
1452 line 3A should be marked as oldMovedAlternate newMoved
1453 line 3B should be marked as oldMovedAlternate newMoved
1454 unchanged
1455 line 4A should be marked as oldMoved newMovedAlternate
1456 line 4B should be marked as oldMoved newMovedAlternate
1457 line 5A should be marked as oldMovedAlternate newMoved
1458 line 5B should be marked as oldMovedAlternate newMoved
1459 line 6A should be marked as oldMoved newMoved
1460 line 6B should be marked as oldMoved newMoved
1461 EOF
1462 cat >new.txt <<-\EOF &&
1463 line 1A should be marked as oldMoved newMovedAlternate
1464 line 1B should be marked as oldMoved newMovedAlternate
1465 unchanged
1466 line 3A should be marked as oldMovedAlternate newMoved
1467 line 3B should be marked as oldMovedAlternate newMoved
1468 line 2A should be marked as oldMoved newMovedAlternate
1469 line 2B should be marked as oldMoved newMovedAlternate
1470 unchanged
1471 line 6A should be marked as oldMoved newMoved
1472 line 6B should be marked as oldMoved newMoved
1473 line 4A should be marked as oldMoved newMovedAlternate
1474 line 4B should be marked as oldMoved newMovedAlternate
1475 line 5A should be marked as oldMovedAlternate newMoved
1476 line 5B should be marked as oldMovedAlternate newMoved
1477 EOF
1478 test_expect_code 1 git diff --no-index --color --color-moved=zebra \
1479 --color-moved-ws=allow-indentation-change \
1480 old.txt new.txt >output &&
1481 grep -v index output | test_decode_color >actual &&
1482 cat >expected <<-\EOF &&
1483 <BOLD>diff --git a/old.txt b/new.txt<RESET>
1484 <BOLD>--- a/old.txt<RESET>
1485 <BOLD>+++ b/new.txt<RESET>
1486 <CYAN>@@ -1,14 +1,14 @@<RESET>
1487 <BOLD;MAGENTA>-line 1A should be marked as oldMoved newMovedAlternate<RESET>
1488 <BOLD;MAGENTA>-line 1B should be marked as oldMoved newMovedAlternate<RESET>
1489 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 1A should be marked as oldMoved newMovedAlternate<RESET>
1490 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 1B should be marked as oldMoved newMovedAlternate<RESET>
1491 unchanged<RESET>
1492 <BOLD;MAGENTA>-line 2A should be marked as oldMoved newMovedAlternate<RESET>
1493 <BOLD;MAGENTA>-line 2B should be marked as oldMoved newMovedAlternate<RESET>
1494 <BOLD;BLUE>-line 3A should be marked as oldMovedAlternate newMoved<RESET>
1495 <BOLD;BLUE>-line 3B should be marked as oldMovedAlternate newMoved<RESET>
1496 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 3A should be marked as oldMovedAlternate newMoved<RESET>
1497 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 3B should be marked as oldMovedAlternate newMoved<RESET>
1498 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 2A should be marked as oldMoved newMovedAlternate<RESET>
1499 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 2B should be marked as oldMoved newMovedAlternate<RESET>
1500 unchanged<RESET>
1501 <BOLD;MAGENTA>-line 4A should be marked as oldMoved newMovedAlternate<RESET>
1502 <BOLD;MAGENTA>-line 4B should be marked as oldMoved newMovedAlternate<RESET>
1503 <BOLD;BLUE>-line 5A should be marked as oldMovedAlternate newMoved<RESET>
1504 <BOLD;BLUE>-line 5B should be marked as oldMovedAlternate newMoved<RESET>
1505 <BOLD;MAGENTA>-line 6A should be marked as oldMoved newMoved<RESET>
1506 <BOLD;MAGENTA>-line 6B should be marked as oldMoved newMoved<RESET>
1507 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 6A should be marked as oldMoved newMoved<RESET>
1508 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 6B should be marked as oldMoved newMoved<RESET>
1509 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 4A should be marked as oldMoved newMovedAlternate<RESET>
1510 <BOLD;YELLOW>+<RESET><BOLD;YELLOW> line 4B should be marked as oldMoved newMovedAlternate<RESET>
1511 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 5A should be marked as oldMovedAlternate newMoved<RESET>
1512 <BOLD;CYAN>+<RESET><BOLD;CYAN> line 5B should be marked as oldMovedAlternate newMoved<RESET>
1513 EOF
1514 test_cmp expected actual
1515 '
1516
1517 test_expect_success 'short lines of opposite sign do not get marked as moved' '
1518 cat >old.txt <<-\EOF &&
1519 this line should be marked as moved
1520 unchanged
1521 unchanged
1522 unchanged
1523 unchanged
1524 too short
1525 this line should be marked as oldMoved newMoved
1526 this line should be marked as oldMovedAlternate newMoved
1527 unchanged 1
1528 unchanged 2
1529 unchanged 3
1530 unchanged 4
1531 this line should be marked as oldMoved newMoved/newMovedAlternate
1532 EOF
1533 cat >new.txt <<-\EOF &&
1534 too short
1535 unchanged
1536 unchanged
1537 this line should be marked as moved
1538 too short
1539 unchanged
1540 unchanged
1541 this line should be marked as oldMoved newMoved/newMovedAlternate
1542 unchanged 1
1543 unchanged 2
1544 this line should be marked as oldMovedAlternate newMoved
1545 this line should be marked as oldMoved newMoved/newMovedAlternate
1546 unchanged 3
1547 this line should be marked as oldMoved newMoved
1548 unchanged 4
1549 EOF
1550 test_expect_code 1 git diff --no-index --color --color-moved=zebra \
1551 old.txt new.txt >output && cat output &&
1552 grep -v index output | test_decode_color >actual &&
1553 cat >expect <<-\EOF &&
1554 <BOLD>diff --git a/old.txt b/new.txt<RESET>
1555 <BOLD>--- a/old.txt<RESET>
1556 <BOLD>+++ b/new.txt<RESET>
1557 <CYAN>@@ -1,13 +1,15 @@<RESET>
1558 <BOLD;MAGENTA>-this line should be marked as moved<RESET>
1559 <GREEN>+<RESET><GREEN>too short<RESET>
1560 unchanged<RESET>
1561 unchanged<RESET>
1562 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as moved<RESET>
1563 <GREEN>+<RESET><GREEN>too short<RESET>
1564 unchanged<RESET>
1565 unchanged<RESET>
1566 <RED>-too short<RESET>
1567 <BOLD;MAGENTA>-this line should be marked as oldMoved newMoved<RESET>
1568 <BOLD;BLUE>-this line should be marked as oldMovedAlternate newMoved<RESET>
1569 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as oldMoved newMoved/newMovedAlternate<RESET>
1570 unchanged 1<RESET>
1571 unchanged 2<RESET>
1572 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as oldMovedAlternate newMoved<RESET>
1573 <BOLD;YELLOW>+<RESET><BOLD;YELLOW>this line should be marked as oldMoved newMoved/newMovedAlternate<RESET>
1574 unchanged 3<RESET>
1575 <BOLD;CYAN>+<RESET><BOLD;CYAN>this line should be marked as oldMoved newMoved<RESET>
1576 unchanged 4<RESET>
1577 <BOLD;MAGENTA>-this line should be marked as oldMoved newMoved/newMovedAlternate<RESET>
1578 EOF
1579 test_cmp expect actual
1580 '
1581
1582 test_expect_success 'cmd option assumes configured colored-moved' '
1583 test_config color.diff.oldMoved "magenta" &&
1584 test_config color.diff.newMoved "cyan" &&
1585 test_config color.diff.oldMovedAlternative "blue" &&
1586 test_config color.diff.newMovedAlternative "yellow" &&
1587 test_config color.diff.oldMovedDimmed "normal magenta" &&
1588 test_config color.diff.newMovedDimmed "normal cyan" &&
1589 test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1590 test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1591 test_config diff.colorMoved zebra &&
1592 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1593 grep -v "index" actual.raw | test_decode_color >actual &&
1594 cat <<-\EOF >expected &&
1595 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1596 <BOLD>--- a/lines.txt<RESET>
1597 <BOLD>+++ b/lines.txt<RESET>
1598 <CYAN>@@ -1,16 +1,16 @@<RESET>
1599 <MAGENTA>-long line 1<RESET>
1600 <MAGENTA>-long line 2<RESET>
1601 <MAGENTA>-long line 3<RESET>
1602 line 4<RESET>
1603 line 5<RESET>
1604 line 6<RESET>
1605 line 7<RESET>
1606 line 8<RESET>
1607 line 9<RESET>
1608 <CYAN>+<RESET><CYAN>long line 1<RESET>
1609 <CYAN>+<RESET><CYAN>long line 2<RESET>
1610 <CYAN>+<RESET><CYAN>long line 3<RESET>
1611 <YELLOW>+<RESET><YELLOW>long line 14<RESET>
1612 <YELLOW>+<RESET><YELLOW>long line 15<RESET>
1613 <YELLOW>+<RESET><YELLOW>long line 16<RESET>
1614 line 10<RESET>
1615 line 11<RESET>
1616 line 12<RESET>
1617 line 13<RESET>
1618 <MAGENTA>-long line 14<RESET>
1619 <MAGENTA>-long line 15<RESET>
1620 <MAGENTA>-long line 16<RESET>
1621 EOF
1622 test_cmp expected actual
1623 '
1624
1625 test_expect_success 'no effect from --color-moved with --word-diff' '
1626 cat <<-\EOF >text.txt &&
1627 Lorem Ipsum is simply dummy text of the printing and typesetting industry.
1628 EOF
1629 git add text.txt &&
1630 git commit -a -m "clean state" &&
1631 cat <<-\EOF >text.txt &&
1632 simply Lorem Ipsum dummy is text of the typesetting and printing industry.
1633 EOF
1634 git diff --color-moved --word-diff >actual &&
1635 git diff --word-diff >expect &&
1636 test_cmp expect actual
1637 '
1638
1639 test_expect_success 'set up whitespace tests' '
1640 git reset --hard &&
1641 # Note that these lines have no leading or trailing whitespace.
1642 cat <<-\EOF >lines.txt &&
1643 line 1
1644 line 2
1645 line 3
1646 line 4
1647 line 5
1648 long line 6
1649 long line 7
1650 long line 8
1651 long line 9
1652 EOF
1653 git add lines.txt &&
1654 git commit -m "add poetry" &&
1655 git config color.diff.oldMoved "magenta" &&
1656 git config color.diff.newMoved "cyan"
1657 '
1658
1659 test_expect_success 'move detection ignoring whitespace ' '
1660 q_to_tab <<-\EOF >lines.txt &&
1661 Qlong line 6
1662 Qlong line 7
1663 Qlong line 8
1664 Qchanged long line 9
1665 line 1
1666 line 2
1667 line 3
1668 line 4
1669 line 5
1670 EOF
1671 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1672 grep -v "index" actual.raw | test_decode_color >actual &&
1673 cat <<-\EOF >expected &&
1674 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1675 <BOLD>--- a/lines.txt<RESET>
1676 <BOLD>+++ b/lines.txt<RESET>
1677 <CYAN>@@ -1,9 +1,9 @@<RESET>
1678 <GREEN>+<RESET> <GREEN>long line 6<RESET>
1679 <GREEN>+<RESET> <GREEN>long line 7<RESET>
1680 <GREEN>+<RESET> <GREEN>long line 8<RESET>
1681 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1682 line 1<RESET>
1683 line 2<RESET>
1684 line 3<RESET>
1685 line 4<RESET>
1686 line 5<RESET>
1687 <RED>-long line 6<RESET>
1688 <RED>-long line 7<RESET>
1689 <RED>-long line 8<RESET>
1690 <RED>-long line 9<RESET>
1691 EOF
1692 test_cmp expected actual &&
1693
1694 git diff HEAD --no-renames --color-moved --color \
1695 --color-moved-ws=ignore-all-space >actual.raw &&
1696 grep -v "index" actual.raw | test_decode_color >actual &&
1697 cat <<-\EOF >expected &&
1698 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1699 <BOLD>--- a/lines.txt<RESET>
1700 <BOLD>+++ b/lines.txt<RESET>
1701 <CYAN>@@ -1,9 +1,9 @@<RESET>
1702 <CYAN>+<RESET> <CYAN>long line 6<RESET>
1703 <CYAN>+<RESET> <CYAN>long line 7<RESET>
1704 <CYAN>+<RESET> <CYAN>long line 8<RESET>
1705 <GREEN>+<RESET> <GREEN>changed long line 9<RESET>
1706 line 1<RESET>
1707 line 2<RESET>
1708 line 3<RESET>
1709 line 4<RESET>
1710 line 5<RESET>
1711 <MAGENTA>-long line 6<RESET>
1712 <MAGENTA>-long line 7<RESET>
1713 <MAGENTA>-long line 8<RESET>
1714 <RED>-long line 9<RESET>
1715 EOF
1716 test_cmp expected actual
1717 '
1718
1719 test_expect_success 'move detection ignoring whitespace changes' '
1720 git reset --hard &&
1721 # Lines 6-8 have a space change, but 9 is new whitespace
1722 q_to_tab <<-\EOF >lines.txt &&
1723 longQline 6
1724 longQline 7
1725 longQline 8
1726 long liQne 9
1727 line 1
1728 line 2
1729 line 3
1730 line 4
1731 line 5
1732 EOF
1733
1734 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1735 grep -v "index" actual.raw | test_decode_color >actual &&
1736 cat <<-\EOF >expected &&
1737 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1738 <BOLD>--- a/lines.txt<RESET>
1739 <BOLD>+++ b/lines.txt<RESET>
1740 <CYAN>@@ -1,9 +1,9 @@<RESET>
1741 <GREEN>+<RESET><GREEN>long line 6<RESET>
1742 <GREEN>+<RESET><GREEN>long line 7<RESET>
1743 <GREEN>+<RESET><GREEN>long line 8<RESET>
1744 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1745 line 1<RESET>
1746 line 2<RESET>
1747 line 3<RESET>
1748 line 4<RESET>
1749 line 5<RESET>
1750 <RED>-long line 6<RESET>
1751 <RED>-long line 7<RESET>
1752 <RED>-long line 8<RESET>
1753 <RED>-long line 9<RESET>
1754 EOF
1755 test_cmp expected actual &&
1756
1757 git diff HEAD --no-renames --color-moved --color \
1758 --color-moved-ws=ignore-space-change >actual.raw &&
1759 grep -v "index" actual.raw | test_decode_color >actual &&
1760 cat <<-\EOF >expected &&
1761 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1762 <BOLD>--- a/lines.txt<RESET>
1763 <BOLD>+++ b/lines.txt<RESET>
1764 <CYAN>@@ -1,9 +1,9 @@<RESET>
1765 <CYAN>+<RESET><CYAN>long line 6<RESET>
1766 <CYAN>+<RESET><CYAN>long line 7<RESET>
1767 <CYAN>+<RESET><CYAN>long line 8<RESET>
1768 <GREEN>+<RESET><GREEN>long li ne 9<RESET>
1769 line 1<RESET>
1770 line 2<RESET>
1771 line 3<RESET>
1772 line 4<RESET>
1773 line 5<RESET>
1774 <MAGENTA>-long line 6<RESET>
1775 <MAGENTA>-long line 7<RESET>
1776 <MAGENTA>-long line 8<RESET>
1777 <RED>-long line 9<RESET>
1778 EOF
1779 test_cmp expected actual
1780 '
1781
1782 test_expect_success 'move detection ignoring whitespace at eol' '
1783 git reset --hard &&
1784 # Lines 6-9 have new eol whitespace, but 9 also has it in the middle
1785 q_to_tab <<-\EOF >lines.txt &&
1786 long line 6Q
1787 long line 7Q
1788 long line 8Q
1789 longQline 9Q
1790 line 1
1791 line 2
1792 line 3
1793 line 4
1794 line 5
1795 EOF
1796
1797 # avoid cluttering the output with complaints about our eol whitespace
1798 test_config core.whitespace -blank-at-eol &&
1799
1800 git diff HEAD --no-renames --color-moved --color >actual.raw &&
1801 grep -v "index" actual.raw | test_decode_color >actual &&
1802 cat <<-\EOF >expected &&
1803 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1804 <BOLD>--- a/lines.txt<RESET>
1805 <BOLD>+++ b/lines.txt<RESET>
1806 <CYAN>@@ -1,9 +1,9 @@<RESET>
1807 <GREEN>+<RESET><GREEN>long line 6 <RESET>
1808 <GREEN>+<RESET><GREEN>long line 7 <RESET>
1809 <GREEN>+<RESET><GREEN>long line 8 <RESET>
1810 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1811 line 1<RESET>
1812 line 2<RESET>
1813 line 3<RESET>
1814 line 4<RESET>
1815 line 5<RESET>
1816 <RED>-long line 6<RESET>
1817 <RED>-long line 7<RESET>
1818 <RED>-long line 8<RESET>
1819 <RED>-long line 9<RESET>
1820 EOF
1821 test_cmp expected actual &&
1822
1823 git diff HEAD --no-renames --color-moved --color \
1824 --color-moved-ws=ignore-space-at-eol >actual.raw &&
1825 grep -v "index" actual.raw | test_decode_color >actual &&
1826 cat <<-\EOF >expected &&
1827 <BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1828 <BOLD>--- a/lines.txt<RESET>
1829 <BOLD>+++ b/lines.txt<RESET>
1830 <CYAN>@@ -1,9 +1,9 @@<RESET>
1831 <CYAN>+<RESET><CYAN>long line 6 <RESET>
1832 <CYAN>+<RESET><CYAN>long line 7 <RESET>
1833 <CYAN>+<RESET><CYAN>long line 8 <RESET>
1834 <GREEN>+<RESET><GREEN>long line 9 <RESET>
1835 line 1<RESET>
1836 line 2<RESET>
1837 line 3<RESET>
1838 line 4<RESET>
1839 line 5<RESET>
1840 <MAGENTA>-long line 6<RESET>
1841 <MAGENTA>-long line 7<RESET>
1842 <MAGENTA>-long line 8<RESET>
1843 <RED>-long line 9<RESET>
1844 EOF
1845 test_cmp expected actual
1846 '
1847
1848 test_expect_success 'clean up whitespace-test colors' '
1849 git config --unset color.diff.oldMoved &&
1850 git config --unset color.diff.newMoved
1851 '
1852
1853 test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
1854 git reset --hard &&
1855 >bar &&
1856 cat <<-\EOF >foo &&
1857 irrelevant_line
1858 line1
1859 EOF
1860 git add foo bar &&
1861 git commit -m x &&
1862
1863 cat <<-\EOF >bar &&
1864 line1
1865 EOF
1866 cat <<-\EOF >foo &&
1867 irrelevant_line
1868 EOF
1869
1870 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1871 grep -v "index" actual.raw | test_decode_color >actual &&
1872 cat >expected <<-\EOF &&
1873 <BOLD>diff --git a/bar b/bar<RESET>
1874 <BOLD>--- a/bar<RESET>
1875 <BOLD>+++ b/bar<RESET>
1876 <CYAN>@@ -0,0 +1 @@<RESET>
1877 <GREEN>+<RESET><GREEN>line1<RESET>
1878 <BOLD>diff --git a/foo b/foo<RESET>
1879 <BOLD>--- a/foo<RESET>
1880 <BOLD>+++ b/foo<RESET>
1881 <CYAN>@@ -1,2 +1 @@<RESET>
1882 irrelevant_line<RESET>
1883 <RED>-line1<RESET>
1884 EOF
1885
1886 test_cmp expected actual
1887 '
1888
1889 test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
1890 git reset --hard &&
1891 cat <<-\EOF >foo &&
1892 nineteen chars 456789
1893 irrelevant_line
1894 twenty chars 234567890
1895 EOF
1896 >bar &&
1897 git add foo bar &&
1898 git commit -m x &&
1899
1900 cat <<-\EOF >foo &&
1901 irrelevant_line
1902 EOF
1903 cat <<-\EOF >bar &&
1904 twenty chars 234567890
1905 nineteen chars 456789
1906 EOF
1907
1908 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1909 grep -v "index" actual.raw | test_decode_color >actual &&
1910 cat >expected <<-\EOF &&
1911 <BOLD>diff --git a/bar b/bar<RESET>
1912 <BOLD>--- a/bar<RESET>
1913 <BOLD>+++ b/bar<RESET>
1914 <CYAN>@@ -0,0 +1,2 @@<RESET>
1915 <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
1916 <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
1917 <BOLD>diff --git a/foo b/foo<RESET>
1918 <BOLD>--- a/foo<RESET>
1919 <BOLD>+++ b/foo<RESET>
1920 <CYAN>@@ -1,3 +1 @@<RESET>
1921 <RED>-nineteen chars 456789<RESET>
1922 irrelevant_line<RESET>
1923 <BOLD;MAGENTA>-twenty chars 234567890<RESET>
1924 EOF
1925
1926 test_cmp expected actual
1927 '
1928
1929 test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
1930 git reset --hard &&
1931 cat <<-\EOF >foo &&
1932 7charsA
1933 irrelevant_line
1934 7charsB
1935 7charsC
1936 EOF
1937 >bar &&
1938 git add foo bar &&
1939 git commit -m x &&
1940
1941 cat <<-\EOF >foo &&
1942 irrelevant_line
1943 EOF
1944 cat <<-\EOF >bar &&
1945 7charsB
1946 7charsC
1947 7charsA
1948 EOF
1949
1950 git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1951 grep -v "index" actual.raw | test_decode_color >actual &&
1952 cat >expected <<-\EOF &&
1953 <BOLD>diff --git a/bar b/bar<RESET>
1954 <BOLD>--- a/bar<RESET>
1955 <BOLD>+++ b/bar<RESET>
1956 <CYAN>@@ -0,0 +1,3 @@<RESET>
1957 <GREEN>+<RESET><GREEN>7charsB<RESET>
1958 <GREEN>+<RESET><GREEN>7charsC<RESET>
1959 <GREEN>+<RESET><GREEN>7charsA<RESET>
1960 <BOLD>diff --git a/foo b/foo<RESET>
1961 <BOLD>--- a/foo<RESET>
1962 <BOLD>+++ b/foo<RESET>
1963 <CYAN>@@ -1,4 +1 @@<RESET>
1964 <RED>-7charsA<RESET>
1965 irrelevant_line<RESET>
1966 <RED>-7charsB<RESET>
1967 <RED>-7charsC<RESET>
1968 EOF
1969
1970 test_cmp expected actual
1971 '
1972
1973 test_expect_success '--color-moved rewinds for MIN_ALNUM_COUNT' '
1974 git reset --hard &&
1975 test_write_lines >file \
1976 A B C one two three four five six seven D E F G H I J &&
1977 git add file &&
1978 test_write_lines >file \
1979 one two A B C D E F G H I J two three four five six seven &&
1980 git diff --color-moved=zebra -- file &&
1981
1982 git diff --color-moved=zebra --color -- file >actual.raw &&
1983 grep -v "index" actual.raw | test_decode_color >actual &&
1984 cat >expected <<-\EOF &&
1985 <BOLD>diff --git a/file b/file<RESET>
1986 <BOLD>--- a/file<RESET>
1987 <BOLD>+++ b/file<RESET>
1988 <CYAN>@@ -1,13 +1,8 @@<RESET>
1989 <GREEN>+<RESET><GREEN>one<RESET>
1990 <GREEN>+<RESET><GREEN>two<RESET>
1991 A<RESET>
1992 B<RESET>
1993 C<RESET>
1994 <RED>-one<RESET>
1995 <BOLD;MAGENTA>-two<RESET>
1996 <BOLD;MAGENTA>-three<RESET>
1997 <BOLD;MAGENTA>-four<RESET>
1998 <BOLD;MAGENTA>-five<RESET>
1999 <BOLD;MAGENTA>-six<RESET>
2000 <BOLD;MAGENTA>-seven<RESET>
2001 D<RESET>
2002 E<RESET>
2003 F<RESET>
2004 <CYAN>@@ -15,3 +10,9 @@<RESET> <RESET>G<RESET>
2005 H<RESET>
2006 I<RESET>
2007 J<RESET>
2008 <BOLD;CYAN>+<RESET><BOLD;CYAN>two<RESET>
2009 <BOLD;CYAN>+<RESET><BOLD;CYAN>three<RESET>
2010 <BOLD;CYAN>+<RESET><BOLD;CYAN>four<RESET>
2011 <BOLD;CYAN>+<RESET><BOLD;CYAN>five<RESET>
2012 <BOLD;CYAN>+<RESET><BOLD;CYAN>six<RESET>
2013 <BOLD;CYAN>+<RESET><BOLD;CYAN>seven<RESET>
2014 EOF
2015
2016 test_cmp expected actual
2017 '
2018
2019 test_expect_success 'move detection with submodules' '
2020 test_create_repo bananas &&
2021 echo ripe >bananas/recipe &&
2022 git -C bananas add recipe &&
2023 test_commit fruit &&
2024 test_commit -C bananas recipe &&
2025 git submodule add ./bananas &&
2026 git add bananas &&
2027 git commit -a -m "bananas are like a heavy library?" &&
2028 echo foul >bananas/recipe &&
2029 echo ripe >fruit.t &&
2030
2031 git diff --submodule=diff --color-moved --color >actual &&
2032
2033 # no move detection as the moved line is across repository boundaries.
2034 test_decode_color <actual >decoded_actual &&
2035 ! grep BGREEN decoded_actual &&
2036 ! grep BRED decoded_actual &&
2037
2038 # nor did we mess with it another way
2039 git diff --submodule=diff --color >expect.raw &&
2040 test_decode_color <expect.raw >expect &&
2041 test_cmp expect decoded_actual &&
2042 rm -rf bananas &&
2043 git submodule deinit bananas
2044 '
2045
2046 test_expect_success 'only move detection ignores white spaces' '
2047 git reset --hard &&
2048 q_to_tab <<-\EOF >text.txt &&
2049 a long line to exceed per-line minimum
2050 another long line to exceed per-line minimum
2051 original file
2052 EOF
2053 git add text.txt &&
2054 git commit -m "add text" &&
2055 q_to_tab <<-\EOF >text.txt &&
2056 Qa long line to exceed per-line minimum
2057 Qanother long line to exceed per-line minimum
2058 new file
2059 EOF
2060
2061 # Make sure we get a different diff using -w
2062 git diff --color --color-moved -w >actual.raw &&
2063 grep -v "index" actual.raw | test_decode_color >actual &&
2064 q_to_tab <<-\EOF >expected &&
2065 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2066 <BOLD>--- a/text.txt<RESET>
2067 <BOLD>+++ b/text.txt<RESET>
2068 <CYAN>@@ -1,3 +1,3 @@<RESET>
2069 Qa long line to exceed per-line minimum<RESET>
2070 Qanother long line to exceed per-line minimum<RESET>
2071 <RED>-original file<RESET>
2072 <GREEN>+<RESET><GREEN>new file<RESET>
2073 EOF
2074 test_cmp expected actual &&
2075
2076 # And now ignoring white space only in the move detection
2077 git diff --color --color-moved \
2078 --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw &&
2079 grep -v "index" actual.raw | test_decode_color >actual &&
2080 q_to_tab <<-\EOF >expected &&
2081 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2082 <BOLD>--- a/text.txt<RESET>
2083 <BOLD>+++ b/text.txt<RESET>
2084 <CYAN>@@ -1,3 +1,3 @@<RESET>
2085 <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET>
2086 <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET>
2087 <RED>-original file<RESET>
2088 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>a long line to exceed per-line minimum<RESET>
2089 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>another long line to exceed per-line minimum<RESET>
2090 <GREEN>+<RESET><GREEN>new file<RESET>
2091 EOF
2092 test_cmp expected actual
2093 '
2094
2095 test_expect_success 'compare whitespace delta across moved blocks' '
2096
2097 git reset --hard &&
2098 q_to_tab <<-\EOF >text.txt &&
2099 QIndented
2100 QText across
2101 Qsome lines
2102 QBut! <- this stands out
2103 QAdjusting with
2104 QQdifferent starting
2105 Qwhite spaces
2106 QAnother outlier
2107 QQQIndented
2108 QQQText across
2109 QQQfive lines
2110 QQQthat has similar lines
2111 QQQto previous blocks, but with different indent
2112 QQQYetQAnotherQoutlierQ
2113 QLine with internal w h i t e s p a c e change
2114 EOF
2115
2116 git add text.txt &&
2117 git commit -m "add text.txt" &&
2118
2119 q_to_tab <<-\EOF >text.txt &&
2120 QQIndented
2121 QQText across
2122 QQsome lines
2123 QQQBut! <- this stands out
2124 Adjusting with
2125 Qdifferent starting
2126 white spaces
2127 AnotherQoutlier
2128 QQIndented
2129 QQText across
2130 QQfive lines
2131 QQthat has similar lines
2132 QQto previous blocks, but with different indent
2133 QQYetQAnotherQoutlier
2134 QLine with internal whitespace change
2135 EOF
2136
2137 git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw &&
2138 grep -v "index" actual.raw | test_decode_color >actual &&
2139
2140 q_to_tab <<-\EOF >expected &&
2141 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2142 <BOLD>--- a/text.txt<RESET>
2143 <BOLD>+++ b/text.txt<RESET>
2144 <CYAN>@@ -1,15 +1,15 @@<RESET>
2145 <BOLD;MAGENTA>-QIndented<RESET>
2146 <BOLD;MAGENTA>-QText across<RESET>
2147 <BOLD;MAGENTA>-Qsome lines<RESET>
2148 <RED>-QBut! <- this stands out<RESET>
2149 <BOLD;MAGENTA>-QAdjusting with<RESET>
2150 <BOLD;MAGENTA>-QQdifferent starting<RESET>
2151 <BOLD;MAGENTA>-Qwhite spaces<RESET>
2152 <RED>-QAnother outlier<RESET>
2153 <BOLD;MAGENTA>-QQQIndented<RESET>
2154 <BOLD;MAGENTA>-QQQText across<RESET>
2155 <BOLD;MAGENTA>-QQQfive lines<RESET>
2156 <BOLD;MAGENTA>-QQQthat has similar lines<RESET>
2157 <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET>
2158 <RED>-QQQYetQAnotherQoutlierQ<RESET>
2159 <RED>-QLine with internal w h i t e s p a c e change<RESET>
2160 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
2161 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
2162 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET>
2163 <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET>
2164 <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET>
2165 <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET>
2166 <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET>
2167 <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET>
2168 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET>
2169 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET>
2170 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET>
2171 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET>
2172 <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET>
2173 <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET>
2174 <GREEN>+<RESET>Q<GREEN>Line with internal whitespace change<RESET>
2175 EOF
2176
2177 test_cmp expected actual
2178 '
2179
2180 test_expect_success 'bogus settings in move detection erroring out' '
2181 test_must_fail git diff --color-moved=bogus 2>err &&
2182 test_i18ngrep "must be one of" err &&
2183 test_i18ngrep bogus err &&
2184
2185 test_must_fail git -c diff.colormoved=bogus diff 2>err &&
2186 test_i18ngrep "must be one of" err &&
2187 test_i18ngrep "from command-line config" err &&
2188
2189 test_must_fail git diff --color-moved-ws=bogus 2>err &&
2190 test_i18ngrep "possible values" err &&
2191 test_i18ngrep bogus err &&
2192
2193 test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
2194 test_i18ngrep "possible values" err &&
2195 test_i18ngrep "from command-line config" err
2196 '
2197
2198 test_expect_success 'compare whitespace delta incompatible with other space options' '
2199 test_must_fail git diff \
2200 --color-moved-ws=allow-indentation-change,ignore-all-space \
2201 2>err &&
2202 test_i18ngrep allow-indentation-change err
2203 '
2204
2205 EMPTY=''
2206 test_expect_success 'compare mixed whitespace delta across moved blocks' '
2207
2208 git reset --hard &&
2209 tr "^|Q_" "\f\v\t " <<-EOF >text.txt &&
2210 ^__
2211 |____too short without
2212 ^
2213 ___being grouped across blank line
2214 ${EMPTY}
2215 context
2216 lines
2217 to
2218 anchor
2219 ____Indented text to
2220 _Q____be further indented by four spaces across
2221 ____Qseveral lines
2222 QQ____These two lines have had their
2223 ____indentation reduced by four spaces
2224 Qdifferent indentation change
2225 ____too short
2226 EOF
2227
2228 git add text.txt &&
2229 git commit -m "add text.txt" &&
2230
2231 tr "^|Q_" "\f\v\t " <<-EOF >text.txt &&
2232 context
2233 lines
2234 to
2235 anchor
2236 QIndented text to
2237 QQbe further indented by four spaces across
2238 Q____several lines
2239 ${EMPTY}
2240 QQtoo short without
2241 ${EMPTY}
2242 ^Q_______being grouped across blank line
2243 ${EMPTY}
2244 Q_QThese two lines have had their
2245 indentation reduced by four spaces
2246 QQdifferent indentation change
2247 __Qtoo short
2248 EOF
2249
2250 git -c color.diff.whitespace="normal red" \
2251 -c core.whitespace=space-before-tab \
2252 diff --color --color-moved --ws-error-highlight=all \
2253 --color-moved-ws=allow-indentation-change >actual.raw &&
2254 grep -v "index" actual.raw | tr "\f\v" "^|" | test_decode_color >actual &&
2255
2256 cat <<-\EOF >expected &&
2257 <BOLD>diff --git a/text.txt b/text.txt<RESET>
2258 <BOLD>--- a/text.txt<RESET>
2259 <BOLD>+++ b/text.txt<RESET>
2260 <CYAN>@@ -1,16 +1,16 @@<RESET>
2261 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA>^<RESET><BRED> <RESET>
2262 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA>| too short without<RESET>
2263 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA>^<RESET>
2264 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
2265 <BOLD;MAGENTA>-<RESET>
2266 <RESET>context<RESET>
2267 <RESET>lines<RESET>
2268 <RESET>to<RESET>
2269 <RESET>anchor<RESET>
2270 <BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
2271 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
2272 <BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
2273 <BOLD;BLUE>-<RESET> <BOLD;BLUE> These two lines have had their<RESET>
2274 <BOLD;BLUE>-<RESET><BOLD;BLUE> indentation reduced by four spaces<RESET>
2275 <BOLD;MAGENTA>-<RESET> <BOLD;MAGENTA>different indentation change<RESET>
2276 <RED>-<RESET><RED> too short<RESET>
2277 <BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
2278 <BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
2279 <BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
2280 <BOLD;YELLOW>+<RESET>
2281 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
2282 <BOLD;YELLOW>+<RESET>
2283 <BOLD;YELLOW>+<RESET><BOLD;YELLOW>^ being grouped across blank line<RESET>
2284 <BOLD;YELLOW>+<RESET>
2285 <BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
2286 <BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
2287 <BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
2288 <GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
2289 EOF
2290
2291 test_cmp expected actual
2292 '
2293
2294 test_expect_success 'combine --ignore-blank-lines with --function-context' '
2295 test_write_lines 1 "" 2 3 4 5 >a &&
2296 test_write_lines 1 2 3 4 >b &&
2297 test_must_fail git diff --no-index \
2298 --ignore-blank-lines --function-context a b >actual.raw &&
2299 sed -n "/@@/,\$p" <actual.raw >actual &&
2300 cat <<-\EOF >expect &&
2301 @@ -1,6 +1,4 @@
2302 1
2303 -
2304 2
2305 3
2306 4
2307 -5
2308 EOF
2309 test_cmp expect actual
2310 '
2311
2312 test_expect_success 'combine --ignore-blank-lines with --function-context 2' '
2313 test_write_lines a b c "" function 1 2 3 4 5 "" 6 7 8 9 >a &&
2314 test_write_lines "" a b c "" function 1 2 3 4 5 6 7 8 >b &&
2315 test_must_fail git diff --no-index \
2316 --ignore-blank-lines --function-context a b >actual.raw &&
2317 sed -n "/@@/,\$p" <actual.raw >actual &&
2318 cat <<-\EOF >expect &&
2319 @@ -5,11 +6,9 @@ c
2320 function
2321 1
2322 2
2323 3
2324 4
2325 5
2326 -
2327 6
2328 7
2329 8
2330 -9
2331 EOF
2332 test_cmp expect actual
2333 '
2334
2335 test_done