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