t / t0008-ignores.shon commit t/chainlint.sed: drop extra spaces from regex character class (ace64e5)
   1#!/bin/sh
   2
   3test_description=check-ignore
   4
   5. ./test-lib.sh
   6
   7init_vars () {
   8        global_excludes="global-excludes"
   9}
  10
  11enable_global_excludes () {
  12        init_vars &&
  13        git config core.excludesfile "$global_excludes"
  14}
  15
  16expect_in () {
  17        dest="$HOME/expected-$1" text="$2"
  18        if test -z "$text"
  19        then
  20                >"$dest" # avoid newline
  21        else
  22                echo "$text" >"$dest"
  23        fi
  24}
  25
  26expect () {
  27        expect_in stdout "$1"
  28}
  29
  30expect_from_stdin () {
  31        cat >"$HOME/expected-stdout"
  32}
  33
  34test_stderr () {
  35        expected="$1"
  36        expect_in stderr "$1" &&
  37        test_i18ncmp "$HOME/expected-stderr" "$HOME/stderr"
  38}
  39
  40broken_c_unquote () {
  41        "$PERL_PATH" -pe 's/^"//; s/\\//; s/"$//; tr/\n/\0/' "$@"
  42}
  43
  44broken_c_unquote_verbose () {
  45        "$PERL_PATH" -pe 's/    "/      /; s/\\//; s/"$//; tr/:\t\n/\0/' "$@"
  46}
  47
  48stderr_contains () {
  49        regexp="$1"
  50        if test_i18ngrep "$regexp" "$HOME/stderr"
  51        then
  52                return 0
  53        else
  54                echo "didn't find /$regexp/ in $HOME/stderr"
  55                cat "$HOME/stderr"
  56                return 1
  57        fi
  58}
  59
  60stderr_empty_on_success () {
  61        expect_code="$1"
  62        if test $expect_code = 0
  63        then
  64                test_stderr ""
  65        else
  66                # If we expect failure then stderr might or might not be empty
  67                # due to --quiet - the caller can check its contents
  68                return 0
  69        fi
  70}
  71
  72test_check_ignore () {
  73        args="$1" expect_code="${2:-0}" global_args="$3"
  74
  75        init_vars &&
  76        rm -f "$HOME/stdout" "$HOME/stderr" "$HOME/cmd" &&
  77        echo git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $no_index_opt $args \
  78                >"$HOME/cmd" &&
  79        echo "$expect_code" >"$HOME/expected-exit-code" &&
  80        test_expect_code "$expect_code" \
  81                git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $no_index_opt $args \
  82                >"$HOME/stdout" 2>"$HOME/stderr" &&
  83        test_cmp "$HOME/expected-stdout" "$HOME/stdout" &&
  84        stderr_empty_on_success "$expect_code"
  85}
  86
  87# Runs the same code with 4 different levels of output verbosity:
  88#
  89#   1. with -q / --quiet
  90#   2. with default verbosity
  91#   3. with -v / --verbose
  92#   4. with -v / --verbose, *and* -n / --non-matching
  93#
  94# expecting success each time.  Takes advantage of the fact that
  95# check-ignore --verbose output is the same as normal output except
  96# for the extra first column.
  97#
  98# A parameter is used to determine if the tests are run with the
  99# normal case (using the index), or with the --no-index option.
 100#
 101# Arguments:
 102#   - (optional) prereqs for this test, e.g. 'SYMLINKS'
 103#   - test name
 104#   - output to expect from the fourth verbosity mode (the output
 105#     from the other verbosity modes is automatically inferred
 106#     from this value)
 107#   - code to run (should invoke test_check_ignore)
 108#   - index option: --index or --no-index
 109test_expect_success_multiple () {
 110        prereq=
 111        if test $# -eq 5
 112        then
 113                prereq=$1
 114                shift
 115        fi
 116        if test "$4" = "--index"
 117        then
 118                no_index_opt=
 119        else
 120                no_index_opt=$4
 121        fi
 122        testname="$1" expect_all="$2" code="$3"
 123
 124        expect_verbose=$( echo "$expect_all" | grep -v '^::     ' )
 125        expect=$( echo "$expect_verbose" | sed -e 's/.* //' )
 126
 127        test_expect_success $prereq "$testname${no_index_opt:+ with $no_index_opt}" '
 128                expect "$expect" &&
 129                eval "$code"
 130        '
 131
 132        # --quiet is only valid when a single pattern is passed
 133        if test $( echo "$expect_all" | wc -l ) = 1
 134        then
 135                for quiet_opt in '-q' '--quiet'
 136                do
 137                        opts="${no_index_opt:+$no_index_opt }$quiet_opt"
 138                        test_expect_success $prereq "$testname${opts:+ with $opts}" "
 139                        expect '' &&
 140                        $code
 141                "
 142                done
 143                quiet_opt=
 144        fi
 145
 146        for verbose_opt in '-v' '--verbose'
 147        do
 148                for non_matching_opt in '' '-n' '--non-matching'
 149                do
 150                        if test -n "$non_matching_opt"
 151                        then
 152                                my_expect="$expect_all"
 153                        else
 154                                my_expect="$expect_verbose"
 155                        fi
 156
 157                        test_code="
 158                                expect '$my_expect' &&
 159                                $code
 160                        "
 161                        opts="${no_index_opt:+$no_index_opt }$verbose_opt${non_matching_opt:+ $non_matching_opt}"
 162                        test_expect_success $prereq "$testname${opts:+ with $opts}" "$test_code"
 163                done
 164        done
 165        verbose_opt=
 166        non_matching_opt=
 167        no_index_opt=
 168}
 169
 170test_expect_success_multi () {
 171        test_expect_success_multiple "$@" "--index"
 172}
 173
 174test_expect_success_no_index_multi () {
 175        test_expect_success_multiple "$@" "--no-index"
 176}
 177
 178test_expect_success 'setup' '
 179        init_vars &&
 180        mkdir -p a/b/ignored-dir a/submodule b &&
 181        if test_have_prereq SYMLINKS
 182        then
 183                ln -s b a/symlink
 184        fi &&
 185        (
 186                cd a/submodule &&
 187                git init &&
 188                echo a >a &&
 189                git add a &&
 190                git commit -m"commit in submodule"
 191        ) &&
 192        git add a/submodule &&
 193        cat <<-\EOF >.gitignore &&
 194                one
 195                ignored-*
 196                top-level-dir/
 197        EOF
 198        for dir in . a
 199        do
 200                : >$dir/not-ignored &&
 201                : >$dir/ignored-and-untracked &&
 202                : >$dir/ignored-but-in-index
 203        done &&
 204        git add -f ignored-but-in-index a/ignored-but-in-index &&
 205        cat <<-\EOF >a/.gitignore &&
 206                two*
 207                *three
 208        EOF
 209        cat <<-\EOF >a/b/.gitignore &&
 210                four
 211                five
 212                # this comment should affect the line numbers
 213                six
 214                ignored-dir/
 215                # and so should this blank line:
 216
 217                !on*
 218                !two
 219        EOF
 220        echo "seven" >a/b/ignored-dir/.gitignore &&
 221        test -n "$HOME" &&
 222        cat <<-\EOF >"$global_excludes" &&
 223                globalone
 224                !globaltwo
 225                globalthree
 226        EOF
 227        cat <<-\EOF >>.git/info/exclude
 228                per-repo
 229        EOF
 230'
 231
 232############################################################################
 233#
 234# test invalid inputs
 235
 236test_expect_success_multi '. corner-case' '::   .' '
 237        test_check_ignore . 1
 238'
 239
 240test_expect_success_multi 'empty command line' '' '
 241        test_check_ignore "" 128 &&
 242        stderr_contains "fatal: no path specified"
 243'
 244
 245test_expect_success_multi '--stdin with empty STDIN' '' '
 246        test_check_ignore "--stdin" 1 </dev/null &&
 247        test_stderr ""
 248'
 249
 250test_expect_success '-q with multiple args' '
 251        expect "" &&
 252        test_check_ignore "-q one two" 128 &&
 253        stderr_contains "fatal: --quiet is only valid with a single pathname"
 254'
 255
 256test_expect_success '--quiet with multiple args' '
 257        expect "" &&
 258        test_check_ignore "--quiet one two" 128 &&
 259        stderr_contains "fatal: --quiet is only valid with a single pathname"
 260'
 261
 262for verbose_opt in '-v' '--verbose'
 263do
 264        for quiet_opt in '-q' '--quiet'
 265        do
 266                test_expect_success "$quiet_opt $verbose_opt" "
 267                        expect '' &&
 268                        test_check_ignore '$quiet_opt $verbose_opt foo' 128 &&
 269                        stderr_contains 'fatal: cannot have both --quiet and --verbose'
 270                "
 271        done
 272done
 273
 274test_expect_success '--quiet with multiple args' '
 275        expect "" &&
 276        test_check_ignore "--quiet one two" 128 &&
 277        stderr_contains "fatal: --quiet is only valid with a single pathname"
 278'
 279
 280test_expect_success_multi 'erroneous use of --' '' '
 281        test_check_ignore "--" 128 &&
 282        stderr_contains "fatal: no path specified"
 283'
 284
 285test_expect_success_multi '--stdin with superfluous arg' '' '
 286        test_check_ignore "--stdin foo" 128 &&
 287        stderr_contains "fatal: cannot specify pathnames with --stdin"
 288'
 289
 290test_expect_success_multi '--stdin -z with superfluous arg' '' '
 291        test_check_ignore "--stdin -z foo" 128 &&
 292        stderr_contains "fatal: cannot specify pathnames with --stdin"
 293'
 294
 295test_expect_success_multi '-z without --stdin' '' '
 296        test_check_ignore "-z" 128 &&
 297        stderr_contains "fatal: -z only makes sense with --stdin"
 298'
 299
 300test_expect_success_multi '-z without --stdin and superfluous arg' '' '
 301        test_check_ignore "-z foo" 128 &&
 302        stderr_contains "fatal: -z only makes sense with --stdin"
 303'
 304
 305test_expect_success_multi 'needs work tree' '' '
 306        (
 307                cd .git &&
 308                test_check_ignore "foo" 128
 309        ) &&
 310        stderr_contains "fatal: this operation must be run in a work tree"
 311'
 312
 313############################################################################
 314#
 315# test standard ignores
 316
 317# First make sure that the presence of a file in the working tree
 318# does not impact results, but that the presence of a file in the
 319# index does unless the --no-index option is used.
 320
 321for subdir in '' 'a/'
 322do
 323        if test -z "$subdir"
 324        then
 325                where="at top-level"
 326        else
 327                where="in subdir $subdir"
 328        fi
 329
 330        test_expect_success_multi "non-existent file $where not ignored" \
 331                "::     ${subdir}non-existent" \
 332                "test_check_ignore '${subdir}non-existent' 1"
 333
 334        test_expect_success_no_index_multi "non-existent file $where not ignored" \
 335                "::     ${subdir}non-existent" \
 336                "test_check_ignore '${subdir}non-existent' 1"
 337
 338        test_expect_success_multi "non-existent file $where ignored" \
 339                ".gitignore:1:one       ${subdir}one" \
 340                "test_check_ignore '${subdir}one'"
 341
 342        test_expect_success_no_index_multi "non-existent file $where ignored" \
 343                ".gitignore:1:one       ${subdir}one" \
 344                "test_check_ignore '${subdir}one'"
 345
 346        test_expect_success_multi "existing untracked file $where not ignored" \
 347                "::     ${subdir}not-ignored" \
 348                "test_check_ignore '${subdir}not-ignored' 1"
 349
 350        test_expect_success_no_index_multi "existing untracked file $where not ignored" \
 351                "::     ${subdir}not-ignored" \
 352                "test_check_ignore '${subdir}not-ignored' 1"
 353
 354        test_expect_success_multi "existing tracked file $where not ignored" \
 355                "::     ${subdir}ignored-but-in-index" \
 356                "test_check_ignore '${subdir}ignored-but-in-index' 1"
 357
 358        test_expect_success_no_index_multi "existing tracked file $where shown as ignored" \
 359                ".gitignore:2:ignored-* ${subdir}ignored-but-in-index" \
 360                "test_check_ignore '${subdir}ignored-but-in-index'"
 361
 362        test_expect_success_multi "existing untracked file $where ignored" \
 363                ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" \
 364                "test_check_ignore '${subdir}ignored-and-untracked'"
 365
 366        test_expect_success_no_index_multi "existing untracked file $where ignored" \
 367                ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" \
 368                "test_check_ignore '${subdir}ignored-and-untracked'"
 369
 370        test_expect_success_multi "mix of file types $where" \
 371"::     ${subdir}non-existent
 372.gitignore:1:one        ${subdir}one
 373::      ${subdir}not-ignored
 374::      ${subdir}ignored-but-in-index
 375.gitignore:2:ignored-*  ${subdir}ignored-and-untracked" \
 376                "test_check_ignore '
 377                        ${subdir}non-existent
 378                        ${subdir}one
 379                        ${subdir}not-ignored
 380                        ${subdir}ignored-but-in-index
 381                        ${subdir}ignored-and-untracked'
 382                "
 383
 384        test_expect_success_no_index_multi "mix of file types $where" \
 385"::     ${subdir}non-existent
 386.gitignore:1:one        ${subdir}one
 387::      ${subdir}not-ignored
 388.gitignore:2:ignored-*  ${subdir}ignored-but-in-index
 389.gitignore:2:ignored-*  ${subdir}ignored-and-untracked" \
 390                "test_check_ignore '
 391                        ${subdir}non-existent
 392                        ${subdir}one
 393                        ${subdir}not-ignored
 394                        ${subdir}ignored-but-in-index
 395                        ${subdir}ignored-and-untracked'
 396                "
 397done
 398
 399# Having established the above, from now on we mostly test against
 400# files which do not exist in the working tree or index.
 401
 402test_expect_success 'sub-directory local ignore' '
 403        expect "a/3-three" &&
 404        test_check_ignore "a/3-three a/three-not-this-one"
 405'
 406
 407test_expect_success 'sub-directory local ignore with --verbose'  '
 408        expect "a/.gitignore:2:*three   a/3-three" &&
 409        test_check_ignore "--verbose a/3-three a/three-not-this-one"
 410'
 411
 412test_expect_success 'local ignore inside a sub-directory' '
 413        expect "3-three" &&
 414        (
 415                cd a &&
 416                test_check_ignore "3-three three-not-this-one"
 417        )
 418'
 419test_expect_success 'local ignore inside a sub-directory with --verbose' '
 420        expect "a/.gitignore:2:*three   3-three" &&
 421        (
 422                cd a &&
 423                test_check_ignore "--verbose 3-three three-not-this-one"
 424        )
 425'
 426
 427test_expect_success_multi 'nested include' \
 428        'a/b/.gitignore:8:!on*  a/b/one' '
 429        test_check_ignore "a/b/one"
 430'
 431
 432############################################################################
 433#
 434# test ignored sub-directories
 435
 436test_expect_success_multi 'ignored sub-directory' \
 437        'a/b/.gitignore:5:ignored-dir/  a/b/ignored-dir' '
 438        test_check_ignore "a/b/ignored-dir"
 439'
 440
 441test_expect_success 'multiple files inside ignored sub-directory' '
 442        expect_from_stdin <<-\EOF &&
 443                a/b/ignored-dir/foo
 444                a/b/ignored-dir/twoooo
 445                a/b/ignored-dir/seven
 446        EOF
 447        test_check_ignore "a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
 448'
 449
 450test_expect_success 'multiple files inside ignored sub-directory with -v' '
 451        expect_from_stdin <<-\EOF &&
 452                a/b/.gitignore:5:ignored-dir/   a/b/ignored-dir/foo
 453                a/b/.gitignore:5:ignored-dir/   a/b/ignored-dir/twoooo
 454                a/b/.gitignore:5:ignored-dir/   a/b/ignored-dir/seven
 455        EOF
 456        test_check_ignore "-v a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
 457'
 458
 459test_expect_success 'cd to ignored sub-directory' '
 460        expect_from_stdin <<-\EOF &&
 461                foo
 462                twoooo
 463                ../one
 464                seven
 465                ../../one
 466        EOF
 467        (
 468                cd a/b/ignored-dir &&
 469                test_check_ignore "foo twoooo ../one seven ../../one"
 470        )
 471'
 472
 473test_expect_success 'cd to ignored sub-directory with -v' '
 474        expect_from_stdin <<-\EOF &&
 475                a/b/.gitignore:5:ignored-dir/   foo
 476                a/b/.gitignore:5:ignored-dir/   twoooo
 477                a/b/.gitignore:8:!on*   ../one
 478                a/b/.gitignore:5:ignored-dir/   seven
 479                .gitignore:1:one        ../../one
 480        EOF
 481        (
 482                cd a/b/ignored-dir &&
 483                test_check_ignore "-v foo twoooo ../one seven ../../one"
 484        )
 485'
 486
 487############################################################################
 488#
 489# test handling of symlinks
 490
 491test_expect_success_multi SYMLINKS 'symlink' '::        a/symlink' '
 492        test_check_ignore "a/symlink" 1
 493'
 494
 495test_expect_success_multi SYMLINKS 'beyond a symlink' '' '
 496        test_check_ignore "a/symlink/foo" 128 &&
 497        test_stderr "fatal: pathspec '\''a/symlink/foo'\'' is beyond a symbolic link"
 498'
 499
 500test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
 501        (
 502                cd a &&
 503                test_check_ignore "symlink/foo" 128
 504        ) &&
 505        test_stderr "fatal: pathspec '\''symlink/foo'\'' is beyond a symbolic link"
 506'
 507
 508############################################################################
 509#
 510# test handling of submodules
 511
 512test_expect_success_multi 'submodule' '' '
 513        test_check_ignore "a/submodule/one" 128 &&
 514        test_stderr "fatal: Pathspec '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
 515'
 516
 517test_expect_success_multi 'submodule from subdirectory' '' '
 518        (
 519                cd a &&
 520                test_check_ignore "submodule/one" 128
 521        ) &&
 522        test_stderr "fatal: Pathspec '\''submodule/one'\'' is in submodule '\''a/submodule'\''"
 523'
 524
 525############################################################################
 526#
 527# test handling of global ignore files
 528
 529test_expect_success 'global ignore not yet enabled' '
 530        expect_from_stdin <<-\EOF &&
 531                .git/info/exclude:7:per-repo    per-repo
 532                a/.gitignore:2:*three   a/globalthree
 533                .git/info/exclude:7:per-repo    a/per-repo
 534        EOF
 535        test_check_ignore "-v globalone per-repo a/globalthree a/per-repo not-ignored a/globaltwo"
 536'
 537
 538test_expect_success 'global ignore' '
 539        enable_global_excludes &&
 540        expect_from_stdin <<-\EOF &&
 541                globalone
 542                per-repo
 543                globalthree
 544                a/globalthree
 545                a/per-repo
 546                globaltwo
 547        EOF
 548        test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
 549'
 550
 551test_expect_success 'global ignore with -v' '
 552        enable_global_excludes &&
 553        expect_from_stdin <<-EOF &&
 554                $global_excludes:1:globalone    globalone
 555                .git/info/exclude:7:per-repo    per-repo
 556                $global_excludes:3:globalthree  globalthree
 557                a/.gitignore:2:*three   a/globalthree
 558                .git/info/exclude:7:per-repo    a/per-repo
 559                $global_excludes:2:!globaltwo   globaltwo
 560        EOF
 561        test_check_ignore "-v globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
 562'
 563
 564############################################################################
 565#
 566# test --stdin
 567
 568cat <<-\EOF >stdin
 569        one
 570        not-ignored
 571        a/one
 572        a/not-ignored
 573        a/b/on
 574        a/b/one
 575        a/b/one one
 576        "a/b/one two"
 577        "a/b/one\"three"
 578        a/b/not-ignored
 579        a/b/two
 580        a/b/twooo
 581        globaltwo
 582        a/globaltwo
 583        a/b/globaltwo
 584        b/globaltwo
 585EOF
 586cat <<-\EOF >expected-default
 587        one
 588        a/one
 589        a/b/on
 590        a/b/one
 591        a/b/one one
 592        a/b/one two
 593        "a/b/one\"three"
 594        a/b/two
 595        a/b/twooo
 596        globaltwo
 597        a/globaltwo
 598        a/b/globaltwo
 599        b/globaltwo
 600EOF
 601cat <<-EOF >expected-verbose
 602        .gitignore:1:one        one
 603        .gitignore:1:one        a/one
 604        a/b/.gitignore:8:!on*   a/b/on
 605        a/b/.gitignore:8:!on*   a/b/one
 606        a/b/.gitignore:8:!on*   a/b/one one
 607        a/b/.gitignore:8:!on*   a/b/one two
 608        a/b/.gitignore:8:!on*   "a/b/one\\"three"
 609        a/b/.gitignore:9:!two   a/b/two
 610        a/.gitignore:1:two*     a/b/twooo
 611        $global_excludes:2:!globaltwo   globaltwo
 612        $global_excludes:2:!globaltwo   a/globaltwo
 613        $global_excludes:2:!globaltwo   a/b/globaltwo
 614        $global_excludes:2:!globaltwo   b/globaltwo
 615EOF
 616
 617broken_c_unquote stdin >stdin0
 618
 619broken_c_unquote expected-default >expected-default0
 620
 621broken_c_unquote_verbose expected-verbose >expected-verbose0
 622
 623test_expect_success '--stdin' '
 624        expect_from_stdin <expected-default &&
 625        test_check_ignore "--stdin" <stdin
 626'
 627
 628test_expect_success '--stdin -q' '
 629        expect "" &&
 630        test_check_ignore "-q --stdin" <stdin
 631'
 632
 633test_expect_success '--stdin -v' '
 634        expect_from_stdin <expected-verbose &&
 635        test_check_ignore "-v --stdin" <stdin
 636'
 637
 638for opts in '--stdin -z' '-z --stdin'
 639do
 640        test_expect_success "$opts" "
 641                expect_from_stdin <expected-default0 &&
 642                test_check_ignore '$opts' <stdin0
 643        "
 644
 645        test_expect_success "$opts -q" "
 646                expect "" &&
 647                test_check_ignore '-q $opts' <stdin0
 648        "
 649
 650        test_expect_success "$opts -v" "
 651                expect_from_stdin <expected-verbose0 &&
 652                test_check_ignore '-v $opts' <stdin0
 653        "
 654done
 655
 656cat <<-\EOF >stdin
 657        ../one
 658        ../not-ignored
 659        one
 660        not-ignored
 661        b/on
 662        b/one
 663        b/one one
 664        "b/one two"
 665        "b/one\"three"
 666        b/two
 667        b/not-ignored
 668        b/twooo
 669        ../globaltwo
 670        globaltwo
 671        b/globaltwo
 672        ../b/globaltwo
 673        c/not-ignored
 674EOF
 675# N.B. we deliberately end STDIN with a non-matching pattern in order
 676# to test that the exit code indicates that one or more of the
 677# provided paths is ignored - in other words, that it represents an
 678# aggregation of all the results, not just the final result.
 679
 680cat <<-EOF >expected-all
 681        .gitignore:1:one        ../one
 682        ::      ../not-ignored
 683        .gitignore:1:one        one
 684        ::      not-ignored
 685        a/b/.gitignore:8:!on*   b/on
 686        a/b/.gitignore:8:!on*   b/one
 687        a/b/.gitignore:8:!on*   b/one one
 688        a/b/.gitignore:8:!on*   b/one two
 689        a/b/.gitignore:8:!on*   "b/one\\"three"
 690        a/b/.gitignore:9:!two   b/two
 691        ::      b/not-ignored
 692        a/.gitignore:1:two*     b/twooo
 693        $global_excludes:2:!globaltwo   ../globaltwo
 694        $global_excludes:2:!globaltwo   globaltwo
 695        $global_excludes:2:!globaltwo   b/globaltwo
 696        $global_excludes:2:!globaltwo   ../b/globaltwo
 697        ::      c/not-ignored
 698EOF
 699grep -v '^::    ' expected-all >expected-verbose
 700sed -e 's/.*    //' expected-verbose >expected-default
 701
 702broken_c_unquote stdin >stdin0
 703
 704broken_c_unquote expected-default >expected-default0
 705
 706broken_c_unquote_verbose expected-verbose >expected-verbose0
 707
 708test_expect_success '--stdin from subdirectory' '
 709        expect_from_stdin <expected-default &&
 710        (
 711                cd a &&
 712                test_check_ignore "--stdin" <../stdin
 713        )
 714'
 715
 716test_expect_success '--stdin from subdirectory with -v' '
 717        expect_from_stdin <expected-verbose &&
 718        (
 719                cd a &&
 720                test_check_ignore "--stdin -v" <../stdin
 721        )
 722'
 723
 724test_expect_success '--stdin from subdirectory with -v -n' '
 725        expect_from_stdin <expected-all &&
 726        (
 727                cd a &&
 728                test_check_ignore "--stdin -v -n" <../stdin
 729        )
 730'
 731
 732for opts in '--stdin -z' '-z --stdin'
 733do
 734        test_expect_success "$opts from subdirectory" '
 735                expect_from_stdin <expected-default0 &&
 736                (
 737                        cd a &&
 738                        test_check_ignore "'"$opts"'" <../stdin0
 739                )
 740        '
 741
 742        test_expect_success "$opts from subdirectory with -v" '
 743                expect_from_stdin <expected-verbose0 &&
 744                (
 745                        cd a &&
 746                        test_check_ignore "'"$opts"' -v" <../stdin0
 747                )
 748        '
 749done
 750
 751test_expect_success PIPE 'streaming support for --stdin' '
 752        mkfifo in out &&
 753        (git check-ignore -n -v --stdin <in >out &) &&
 754
 755        # We cannot just "echo >in" because check-ignore would get EOF
 756        # after echo exited; instead we open the descriptor in our
 757        # shell, and then echo to the fd. We make sure to close it at
 758        # the end, so that the subprocess does get EOF and dies
 759        # properly.
 760        #
 761        # Similarly, we must keep "out" open so that check-ignore does
 762        # not ever get SIGPIPE trying to write to us. Not only would that
 763        # produce incorrect results, but then there would be no writer on the
 764        # other end of the pipe, and we would potentially block forever trying
 765        # to open it.
 766        exec 9>in &&
 767        exec 8<out &&
 768        test_when_finished "exec 9>&-" &&
 769        test_when_finished "exec 8<&-" &&
 770        echo >&9 one &&
 771        read response <&8 &&
 772        echo "$response" | grep "^\.gitignore:1:one     one" &&
 773        echo >&9 two &&
 774        read response <&8 &&
 775        echo "$response" | grep "^::    two"
 776'
 777
 778test_expect_success 'existing file and directory' '
 779        test_when_finished "rm one" &&
 780        test_when_finished "rmdir top-level-dir" &&
 781        >one &&
 782        mkdir top-level-dir &&
 783        git check-ignore one top-level-dir >actual &&
 784        grep one actual &&
 785        grep top-level-dir actual
 786'
 787
 788test_expect_success 'existing directory and file' '
 789        test_when_finished "rm one" &&
 790        test_when_finished "rmdir top-level-dir" &&
 791        >one &&
 792        mkdir top-level-dir &&
 793        git check-ignore top-level-dir one >actual &&
 794        grep one actual &&
 795        grep top-level-dir actual
 796'
 797
 798############################################################################
 799#
 800# test whitespace handling
 801
 802test_expect_success 'trailing whitespace is ignored' '
 803        mkdir whitespace &&
 804        >whitespace/trailing &&
 805        >whitespace/untracked &&
 806        echo "whitespace/trailing   " >ignore &&
 807        cat >expect <<EOF &&
 808whitespace/untracked
 809EOF
 810        : >err.expect &&
 811        git ls-files -o -X ignore whitespace >actual 2>err &&
 812        test_cmp expect actual &&
 813        test_cmp err.expect err
 814'
 815
 816test_expect_success !MINGW 'quoting allows trailing whitespace' '
 817        rm -rf whitespace &&
 818        mkdir whitespace &&
 819        >"whitespace/trailing  " &&
 820        >whitespace/untracked &&
 821        echo "whitespace/trailing\\ \\ " >ignore &&
 822        echo whitespace/untracked >expect &&
 823        : >err.expect &&
 824        git ls-files -o -X ignore whitespace >actual 2>err &&
 825        test_cmp expect actual &&
 826        test_cmp err.expect err
 827'
 828
 829test_expect_success !MINGW,!CYGWIN 'correct handling of backslashes' '
 830        rm -rf whitespace &&
 831        mkdir whitespace &&
 832        >"whitespace/trailing 1  " &&
 833        >"whitespace/trailing 2 \\\\" &&
 834        >"whitespace/trailing 3 \\\\" &&
 835        >"whitespace/trailing 4   \\ " &&
 836        >"whitespace/trailing 5 \\ \\ " &&
 837        >"whitespace/trailing 6 \\a\\" &&
 838        >whitespace/untracked &&
 839        sed -e "s/Z$//" >ignore <<-\EOF &&
 840        whitespace/trailing 1 \    Z
 841        whitespace/trailing 2 \\\\Z
 842        whitespace/trailing 3 \\\\ Z
 843        whitespace/trailing 4   \\\    Z
 844        whitespace/trailing 5 \\ \\\   Z
 845        whitespace/trailing 6 \\a\\Z
 846        EOF
 847        echo whitespace/untracked >expect &&
 848        >err.expect &&
 849        git ls-files -o -X ignore whitespace >actual 2>err &&
 850        test_cmp expect actual &&
 851        test_cmp err.expect err
 852'
 853
 854test_expect_success 'info/exclude trumps core.excludesfile' '
 855        echo >>global-excludes usually-ignored &&
 856        echo >>.git/info/exclude "!usually-ignored" &&
 857        >usually-ignored &&
 858        echo "?? usually-ignored" >expect &&
 859
 860        git status --porcelain usually-ignored >actual &&
 861        test_cmp expect actual
 862'
 863
 864test_done