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