t / t4015-diff-whitespace.shon commit Merge branch 'jc/add-2.0-ignore-removal' (160c4b1)
   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
  12# Ray Lehtiniemi's example
  13
  14cat << EOF > x
  15do {
  16   nothing;
  17} while (0);
  18EOF
  19
  20git update-index --add x
  21
  22cat << EOF > x
  23do
  24{
  25   nothing;
  26}
  27while (0);
  28EOF
  29
  30cat << EOF > expect
  31diff --git a/x b/x
  32index adf3937..6edc172 100644
  33--- a/x
  34+++ b/x
  35@@ -1,3 +1,5 @@
  36-do {
  37+do
  38+{
  39    nothing;
  40-} while (0);
  41+}
  42+while (0);
  43EOF
  44
  45git diff > out
  46test_expect_success "Ray's example without options" 'test_cmp expect out'
  47
  48git diff -w > out
  49test_expect_success "Ray's example with -w" 'test_cmp expect out'
  50
  51git diff -b > out
  52test_expect_success "Ray's example with -b" 'test_cmp expect out'
  53
  54tr 'Q' '\015' << EOF > x
  55whitespace at beginning
  56whitespace change
  57whitespace in the middle
  58whitespace at end
  59unchanged line
  60CR at endQ
  61EOF
  62
  63git update-index x
  64
  65tr '_' ' ' << EOF > x
  66        whitespace at beginning
  67whitespace       change
  68white space in the middle
  69whitespace at end__
  70unchanged line
  71CR at end
  72EOF
  73
  74tr 'Q_' '\015 ' << EOF > expect
  75diff --git a/x b/x
  76index d99af23..8b32fb5 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
  91EOF
  92git diff > out
  93test_expect_success 'another test, without options' 'test_cmp expect out'
  94
  95cat << EOF > expect
  96EOF
  97git diff -w > out
  98test_expect_success 'another test, with -w' 'test_cmp expect out'
  99git diff -w -b > out
 100test_expect_success 'another test, with -w -b' 'test_cmp expect out'
 101git diff -w --ignore-space-at-eol > out
 102test_expect_success 'another test, with -w --ignore-space-at-eol' 'test_cmp expect out'
 103git diff -w -b --ignore-space-at-eol > out
 104test_expect_success 'another test, with -w -b --ignore-space-at-eol' 'test_cmp expect out'
 105
 106tr 'Q_' '\015 ' << EOF > expect
 107diff --git a/x b/x
 108index d99af23..8b32fb5 100644
 109--- a/x
 110+++ b/x
 111@@ -1,6 +1,6 @@
 112-whitespace at beginning
 113+       whitespace at beginning
 114 whitespace      change
 115-whitespace in the middle
 116+white space in the middle
 117 whitespace at end__
 118 unchanged line
 119 CR at end
 120EOF
 121git diff -b > out
 122test_expect_success 'another test, with -b' 'test_cmp expect out'
 123git diff -b --ignore-space-at-eol > out
 124test_expect_success 'another test, with -b --ignore-space-at-eol' 'test_cmp expect out'
 125
 126tr 'Q_' '\015 ' << EOF > expect
 127diff --git a/x b/x
 128index d99af23..8b32fb5 100644
 129--- a/x
 130+++ b/x
 131@@ -1,6 +1,6 @@
 132-whitespace at beginning
 133-whitespace change
 134-whitespace in the middle
 135+       whitespace at beginning
 136+whitespace      change
 137+white space in the middle
 138 whitespace at end__
 139 unchanged line
 140 CR at end
 141EOF
 142git diff --ignore-space-at-eol > out
 143test_expect_success 'another test, with --ignore-space-at-eol' 'test_cmp expect out'
 144
 145test_expect_success 'ignore-blank-lines: only new lines' '
 146        test_seq 5 >x &&
 147        git update-index x &&
 148        test_seq 5 | sed "/3/i\\
 149" >x &&
 150        git diff --ignore-blank-lines >out &&
 151        >expect &&
 152        test_cmp out expect
 153'
 154
 155test_expect_success 'ignore-blank-lines: only new lines with space' '
 156        test_seq 5 >x &&
 157        git update-index x &&
 158        test_seq 5 | sed "/3/i\\
 159 " >x &&
 160        git diff -w --ignore-blank-lines >out &&
 161        >expect &&
 162        test_cmp out expect
 163'
 164
 165test_expect_success 'ignore-blank-lines: after change' '
 166        cat <<-\EOF >x &&
 167        1
 168        2
 169
 170        3
 171        4
 172        5
 173
 174        6
 175        7
 176        EOF
 177        git update-index x &&
 178        cat <<-\EOF >x &&
 179        change
 180
 181        1
 182        2
 183        3
 184        4
 185        5
 186        6
 187
 188        7
 189        EOF
 190        git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
 191        cat <<-\EOF >expected &&
 192        diff --git a/x b/x
 193        --- a/x
 194        +++ b/x
 195        @@ -1,6 +1,7 @@
 196        +change
 197        +
 198         1
 199         2
 200        -
 201         3
 202         4
 203         5
 204        EOF
 205        compare_diff_patch expected out.tmp
 206'
 207
 208test_expect_success 'ignore-blank-lines: before change' '
 209        cat <<-\EOF >x &&
 210        1
 211        2
 212
 213        3
 214        4
 215        5
 216        6
 217        7
 218        EOF
 219        git update-index x &&
 220        cat <<-\EOF >x &&
 221
 222        1
 223        2
 224        3
 225        4
 226        5
 227
 228        6
 229        7
 230        change
 231        EOF
 232        git diff --inter-hunk-context=100 --ignore-blank-lines >out.tmp &&
 233        cat <<-\EOF >expected &&
 234        diff --git a/x b/x
 235        --- a/x
 236        +++ b/x
 237        @@ -4,5 +4,7 @@
 238         3
 239         4
 240         5
 241        +
 242         6
 243         7
 244        +change
 245        EOF
 246        compare_diff_patch expected out.tmp
 247'
 248
 249test_expect_success 'ignore-blank-lines: between changes' '
 250        cat <<-\EOF >x &&
 251        1
 252        2
 253        3
 254        4
 255        5
 256
 257
 258        6
 259        7
 260        8
 261        9
 262        10
 263        EOF
 264        git update-index x &&
 265        cat <<-\EOF >x &&
 266        change
 267        1
 268        2
 269
 270        3
 271        4
 272        5
 273        6
 274        7
 275        8
 276
 277        9
 278        10
 279        change
 280        EOF
 281        git diff --ignore-blank-lines >out.tmp &&
 282        cat <<-\EOF >expected &&
 283        diff --git a/x b/x
 284        --- a/x
 285        +++ b/x
 286        @@ -1,5 +1,7 @@
 287        +change
 288         1
 289         2
 290        +
 291         3
 292         4
 293         5
 294        @@ -8,5 +8,7 @@
 295         6
 296         7
 297         8
 298        +
 299         9
 300         10
 301        +change
 302        EOF
 303        compare_diff_patch expected out.tmp
 304'
 305
 306test_expect_success 'ignore-blank-lines: between changes (with interhunkctx)' '
 307        test_seq 10 >x &&
 308        git update-index x &&
 309        cat <<-\EOF >x &&
 310        change
 311        1
 312        2
 313
 314        3
 315        4
 316        5
 317
 318        6
 319        7
 320        8
 321        9
 322
 323        10
 324        change
 325        EOF
 326        git diff --inter-hunk-context=2 --ignore-blank-lines >out.tmp &&
 327        cat <<-\EOF >expected &&
 328        diff --git a/x b/x
 329        --- a/x
 330        +++ b/x
 331        @@ -1,10 +1,15 @@
 332        +change
 333         1
 334         2
 335        +
 336         3
 337         4
 338         5
 339        +
 340         6
 341         7
 342         8
 343         9
 344        +
 345         10
 346        +change
 347        EOF
 348        compare_diff_patch expected out.tmp
 349'
 350
 351test_expect_success 'ignore-blank-lines: scattered spaces' '
 352        test_seq 10 >x &&
 353        git update-index x &&
 354        cat <<-\EOF >x &&
 355        change
 356        1
 357        2
 358        3
 359
 360        4
 361
 362        5
 363
 364        6
 365
 366
 367        7
 368
 369        8
 370        9
 371        10
 372        change
 373        EOF
 374        git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
 375        cat <<-\EOF >expected &&
 376        diff --git a/x b/x
 377        --- a/x
 378        +++ b/x
 379        @@ -1,3 +1,4 @@
 380        +change
 381         1
 382         2
 383         3
 384        @@ -8,3 +15,4 @@
 385         8
 386         9
 387         10
 388        +change
 389        EOF
 390        compare_diff_patch expected out.tmp
 391'
 392
 393test_expect_success 'ignore-blank-lines: spaces coalesce' '
 394        test_seq 6 >x &&
 395        git update-index x &&
 396        cat <<-\EOF >x &&
 397        change
 398        1
 399        2
 400        3
 401
 402        4
 403
 404        5
 405
 406        6
 407        change
 408        EOF
 409        git diff --inter-hunk-context=4 --ignore-blank-lines >out.tmp &&
 410        cat <<-\EOF >expected &&
 411        diff --git a/x b/x
 412        --- a/x
 413        +++ b/x
 414        @@ -1,6 +1,11 @@
 415        +change
 416         1
 417         2
 418         3
 419        +
 420         4
 421        +
 422         5
 423        +
 424         6
 425        +change
 426        EOF
 427        compare_diff_patch expected out.tmp
 428'
 429
 430test_expect_success 'ignore-blank-lines: mix changes and blank lines' '
 431        test_seq 16 >x &&
 432        git update-index x &&
 433        cat <<-\EOF >x &&
 434        change
 435        1
 436        2
 437
 438        3
 439        4
 440        5
 441        change
 442        6
 443        7
 444        8
 445
 446        9
 447        10
 448        11
 449        change
 450        12
 451        13
 452        14
 453
 454        15
 455        16
 456        change
 457        EOF
 458        git diff --ignore-blank-lines >out.tmp &&
 459        cat <<-\EOF >expected &&
 460        diff --git a/x b/x
 461        --- a/x
 462        +++ b/x
 463        @@ -1,8 +1,11 @@
 464        +change
 465         1
 466         2
 467        +
 468         3
 469         4
 470         5
 471        +change
 472         6
 473         7
 474         8
 475        @@ -9,8 +13,11 @@
 476         9
 477         10
 478         11
 479        +change
 480         12
 481         13
 482         14
 483        +
 484         15
 485         16
 486        +change
 487        EOF
 488        compare_diff_patch expected out.tmp
 489'
 490
 491test_expect_success 'check mixed spaces and tabs in indent' '
 492
 493        # This is indented with SP HT SP.
 494        echo "   foo();" > x &&
 495        git diff --check | grep "space before tab in indent"
 496
 497'
 498
 499test_expect_success 'check mixed tabs and spaces in indent' '
 500
 501        # This is indented with HT SP HT.
 502        echo "          foo();" > x &&
 503        git diff --check | grep "space before tab in indent"
 504
 505'
 506
 507test_expect_success 'check with no whitespace errors' '
 508
 509        git commit -m "snapshot" &&
 510        echo "foo();" > x &&
 511        git diff --check
 512
 513'
 514
 515test_expect_success 'check with trailing whitespace' '
 516
 517        echo "foo(); " > x &&
 518        test_must_fail git diff --check
 519
 520'
 521
 522test_expect_success 'check with space before tab in indent' '
 523
 524        # indent has space followed by hard tab
 525        echo "  foo();" > x &&
 526        test_must_fail git diff --check
 527
 528'
 529
 530test_expect_success '--check and --exit-code are not exclusive' '
 531
 532        git checkout x &&
 533        git diff --check --exit-code
 534
 535'
 536
 537test_expect_success '--check and --quiet are not exclusive' '
 538
 539        git diff --check --quiet
 540
 541'
 542
 543test_expect_success 'check staged with no whitespace errors' '
 544
 545        echo "foo();" > x &&
 546        git add x &&
 547        git diff --cached --check
 548
 549'
 550
 551test_expect_success 'check staged with trailing whitespace' '
 552
 553        echo "foo(); " > x &&
 554        git add x &&
 555        test_must_fail git diff --cached --check
 556
 557'
 558
 559test_expect_success 'check staged with space before tab in indent' '
 560
 561        # indent has space followed by hard tab
 562        echo "  foo();" > x &&
 563        git add x &&
 564        test_must_fail git diff --cached --check
 565
 566'
 567
 568test_expect_success 'check with no whitespace errors (diff-index)' '
 569
 570        echo "foo();" > x &&
 571        git add x &&
 572        git diff-index --check HEAD
 573
 574'
 575
 576test_expect_success 'check with trailing whitespace (diff-index)' '
 577
 578        echo "foo(); " > x &&
 579        git add x &&
 580        test_must_fail git diff-index --check HEAD
 581
 582'
 583
 584test_expect_success 'check with space before tab in indent (diff-index)' '
 585
 586        # indent has space followed by hard tab
 587        echo "  foo();" > x &&
 588        git add x &&
 589        test_must_fail git diff-index --check HEAD
 590
 591'
 592
 593test_expect_success 'check staged with no whitespace errors (diff-index)' '
 594
 595        echo "foo();" > x &&
 596        git add x &&
 597        git diff-index --cached --check HEAD
 598
 599'
 600
 601test_expect_success 'check staged with trailing whitespace (diff-index)' '
 602
 603        echo "foo(); " > x &&
 604        git add x &&
 605        test_must_fail git diff-index --cached --check HEAD
 606
 607'
 608
 609test_expect_success 'check staged with space before tab in indent (diff-index)' '
 610
 611        # indent has space followed by hard tab
 612        echo "  foo();" > x &&
 613        git add x &&
 614        test_must_fail git diff-index --cached --check HEAD
 615
 616'
 617
 618test_expect_success 'check with no whitespace errors (diff-tree)' '
 619
 620        echo "foo();" > x &&
 621        git commit -m "new commit" x &&
 622        git diff-tree --check HEAD^ HEAD
 623
 624'
 625
 626test_expect_success 'check with trailing whitespace (diff-tree)' '
 627
 628        echo "foo(); " > x &&
 629        git commit -m "another commit" x &&
 630        test_must_fail git diff-tree --check HEAD^ HEAD
 631
 632'
 633
 634test_expect_success 'check with space before tab in indent (diff-tree)' '
 635
 636        # indent has space followed by hard tab
 637        echo "  foo();" > x &&
 638        git commit -m "yet another" x &&
 639        test_must_fail git diff-tree --check HEAD^ HEAD
 640
 641'
 642
 643test_expect_success 'check trailing whitespace (trailing-space: off)' '
 644
 645        git config core.whitespace "-trailing-space" &&
 646        echo "foo ();   " > x &&
 647        git diff --check
 648
 649'
 650
 651test_expect_success 'check trailing whitespace (trailing-space: on)' '
 652
 653        git config core.whitespace "trailing-space" &&
 654        echo "foo ();   " > x &&
 655        test_must_fail git diff --check
 656
 657'
 658
 659test_expect_success 'check space before tab in indent (space-before-tab: off)' '
 660
 661        # indent contains space followed by HT
 662        git config core.whitespace "-space-before-tab" &&
 663        echo "  foo ();" > x &&
 664        git diff --check
 665
 666'
 667
 668test_expect_success 'check space before tab in indent (space-before-tab: on)' '
 669
 670        # indent contains space followed by HT
 671        git config core.whitespace "space-before-tab" &&
 672        echo "  foo ();   " > x &&
 673        test_must_fail git diff --check
 674
 675'
 676
 677test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
 678
 679        git config core.whitespace "-indent-with-non-tab" &&
 680        echo "        foo ();" > x &&
 681        git diff --check
 682
 683'
 684
 685test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
 686
 687        git config core.whitespace "indent-with-non-tab" &&
 688        echo "        foo ();" > x &&
 689        test_must_fail git diff --check
 690
 691'
 692
 693test_expect_success 'ditto, but tabwidth=9' '
 694
 695        git config core.whitespace "indent-with-non-tab,tabwidth=9" &&
 696        git diff --check
 697
 698'
 699
 700test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
 701
 702        git config core.whitespace "indent-with-non-tab" &&
 703        echo "                  foo ();" > x &&
 704        test_must_fail git diff --check
 705
 706'
 707
 708test_expect_success 'ditto, but tabwidth=10' '
 709
 710        git config core.whitespace "indent-with-non-tab,tabwidth=10" &&
 711        test_must_fail git diff --check
 712
 713'
 714
 715test_expect_success 'ditto, but tabwidth=20' '
 716
 717        git config core.whitespace "indent-with-non-tab,tabwidth=20" &&
 718        git diff --check
 719
 720'
 721
 722test_expect_success 'check tabs as indentation (tab-in-indent: off)' '
 723
 724        git config core.whitespace "-tab-in-indent" &&
 725        echo "  foo ();" > x &&
 726        git diff --check
 727
 728'
 729
 730test_expect_success 'check tabs as indentation (tab-in-indent: on)' '
 731
 732        git config core.whitespace "tab-in-indent" &&
 733        echo "  foo ();" > x &&
 734        test_must_fail git diff --check
 735
 736'
 737
 738test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' '
 739
 740        git config core.whitespace "tab-in-indent" &&
 741        echo "                  foo ();" > x &&
 742        test_must_fail git diff --check
 743
 744'
 745
 746test_expect_success 'ditto, but tabwidth=1 (must be irrelevant)' '
 747
 748        git config core.whitespace "tab-in-indent,tabwidth=1" &&
 749        test_must_fail git diff --check
 750
 751'
 752
 753test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' '
 754
 755        git config core.whitespace "tab-in-indent,indent-with-non-tab" &&
 756        echo "foo ();" > x &&
 757        test_must_fail git diff --check
 758
 759'
 760
 761test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' '
 762
 763        git config --unset core.whitespace &&
 764        echo "x whitespace" > .gitattributes &&
 765        echo "    foo ();" > x &&
 766        git diff --check &&
 767        rm -f .gitattributes
 768
 769'
 770
 771test_expect_success 'line numbers in --check output are correct' '
 772
 773        echo "" > x &&
 774        echo "foo(); " >> x &&
 775        git diff --check | grep "x:2:"
 776
 777'
 778
 779test_expect_success 'checkdiff detects new trailing blank lines (1)' '
 780        echo "foo();" >x &&
 781        echo "" >>x &&
 782        git diff --check | grep "new blank line"
 783'
 784
 785test_expect_success 'checkdiff detects new trailing blank lines (2)' '
 786        { echo a; echo b; echo; echo; } >x &&
 787        git add x &&
 788        { echo a; echo; echo; echo; echo; } >x &&
 789        git diff --check | grep "new blank line"
 790'
 791
 792test_expect_success 'checkdiff allows new blank lines' '
 793        git checkout x &&
 794        mv x y &&
 795        (
 796                echo "/* This is new */" &&
 797                echo "" &&
 798                cat y
 799        ) >x &&
 800        git diff --check
 801'
 802
 803cat <<EOF >expect
 804EOF
 805test_expect_success 'whitespace-only changes not reported' '
 806        git reset --hard &&
 807        echo >x "hello world" &&
 808        git add x &&
 809        git commit -m "hello 1" &&
 810        echo >x "hello  world" &&
 811        git diff -b >actual &&
 812        test_cmp expect actual
 813'
 814
 815cat <<EOF >expect
 816diff --git a/x b/z
 817similarity index NUM%
 818rename from x
 819rename to z
 820index 380c32a..a97b785 100644
 821EOF
 822test_expect_success 'whitespace-only changes reported across renames' '
 823        git reset --hard &&
 824        for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
 825        git add x &&
 826        git commit -m "base" &&
 827        sed -e "5s/^/ /" x >z &&
 828        git rm x &&
 829        git add z &&
 830        git diff -w -M --cached |
 831        sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual &&
 832        test_cmp expect actual
 833'
 834
 835cat >expected <<\EOF
 836diff --git a/empty b/void
 837similarity index 100%
 838rename from empty
 839rename to void
 840EOF
 841
 842test_expect_success 'rename empty' '
 843        git reset --hard &&
 844        >empty &&
 845        git add empty &&
 846        git commit -m empty &&
 847        git mv empty void &&
 848        git diff -w --cached -M >current &&
 849        test_cmp expected current
 850'
 851
 852test_expect_success 'combined diff with autocrlf conversion' '
 853
 854        git reset --hard &&
 855        echo >x hello &&
 856        git commit -m "one side" x &&
 857        git checkout HEAD^ &&
 858        echo >x goodbye &&
 859        git commit -m "the other side" x &&
 860        git config core.autocrlf true &&
 861        test_must_fail git merge master &&
 862
 863        git diff | sed -e "1,/^@@@/d" >actual &&
 864        ! grep "^-" actual
 865
 866'
 867
 868# Start testing the colored format for whitespace checks
 869
 870test_expect_success 'setup diff colors' '
 871        git config color.diff always &&
 872        git config color.diff.plain normal &&
 873        git config color.diff.meta bold &&
 874        git config color.diff.frag cyan &&
 875        git config color.diff.func normal &&
 876        git config color.diff.old red &&
 877        git config color.diff.new green &&
 878        git config color.diff.commit yellow &&
 879        git config color.diff.whitespace "normal red" &&
 880
 881        git config core.autocrlf false
 882'
 883cat >expected <<\EOF
 884<BOLD>diff --git a/x b/x<RESET>
 885<BOLD>index 9daeafb..2874b91 100644<RESET>
 886<BOLD>--- a/x<RESET>
 887<BOLD>+++ b/x<RESET>
 888<CYAN>@@ -1 +1,4 @@<RESET>
 889 test<RESET>
 890<GREEN>+<RESET><GREEN>{<RESET>
 891<GREEN>+<RESET><BRED>   <RESET>
 892<GREEN>+<RESET><GREEN>}<RESET>
 893EOF
 894
 895test_expect_success 'diff that introduces a line with only tabs' '
 896        git config core.whitespace blank-at-eol &&
 897        git reset --hard &&
 898        echo "test" > x &&
 899        git commit -m "initial" x &&
 900        echo "{NTN}" | tr "NT" "\n\t" >> x &&
 901        git -c color.diff=always diff | test_decode_color >current &&
 902        test_cmp expected current
 903'
 904
 905test_done