3 test_description=check-ignore
 
   8         global_excludes="global-excludes"
 
  11 enable_global_excludes () {
 
  13         git config core.excludesfile "$global_excludes"
 
  17         dest="$HOME/expected-$1" text="$2"
 
  20                 >"$dest" # avoid newline
 
  30 expect_from_stdin () {
 
  31         cat >"$HOME/expected-stdout"
 
  36         expect_in stderr "$1" &&
 
  37         test_i18ncmp "$HOME/expected-stderr" "$HOME/stderr"
 
  41         "$PERL_PATH" -pe 's/^"//; s/\\//; s/"$//; tr/\n/\0/' "$@"
 
  44 broken_c_unquote_verbose () {
 
  45         "$PERL_PATH" -pe 's/    "/      /; s/\\//; s/"$//; tr/:\t\n/\0/' "$@"
 
  50         if test_i18ngrep "$regexp" "$HOME/stderr"
 
  54                 echo "didn't find /$regexp/ in $HOME/stderr"
 
  60 stderr_empty_on_success () {
 
  62         if test $expect_code = 0
 
  66                 # If we expect failure then stderr might or might not be empty
 
  67                 # due to --quiet - the caller can check its contents
 
  72 test_check_ignore () {
 
  73         args="$1" expect_code="${2:-0}" global_args="$3"
 
  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 \
 
  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"
 
  87 # Runs the same code with 4 different levels of output verbosity:
 
  89 #   1. with -q / --quiet
 
  90 #   2. with default verbosity
 
  91 #   3. with -v / --verbose
 
  92 #   4. with -v / --verbose, *and* -n / --non-matching
 
  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.
 
  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.
 
 102 #   - (optional) prereqs for this test, e.g. 'SYMLINKS'
 
 104 #   - output to expect from the fourth verbosity mode (the output
 
 105 #     from the other verbosity modes is automatically inferred
 
 107 #   - code to run (should invoke test_check_ignore)
 
 108 #   - index option: --index or --no-index
 
 109 test_expect_success_multiple () {
 
 116         if test "$4" = "--index"
 
 122         testname="$1" expect_all="$2" code="$3"
 
 124         expect_verbose=$( echo "$expect_all" | grep -v '^::     ' )
 
 125         expect=$( echo "$expect_verbose" | sed -e 's/.* //' )
 
 127         test_expect_success $prereq "$testname${no_index_opt:+ with $no_index_opt}" '
 
 132         # --quiet is only valid when a single pattern is passed
 
 133         if test $( echo "$expect_all" | wc -l ) = 1
 
 135                 for quiet_opt in '-q' '--quiet'
 
 137                         opts="${no_index_opt:+$no_index_opt }$quiet_opt"
 
 138                         test_expect_success $prereq "$testname${opts:+ with $opts}" "
 
 146         for verbose_opt in '-v' '--verbose'
 
 148                 for non_matching_opt in '' '-n' '--non-matching'
 
 150                         if test -n "$non_matching_opt"
 
 152                                 my_expect="$expect_all"
 
 154                                 my_expect="$expect_verbose"
 
 158                                 expect '$my_expect' &&
 
 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"
 
 170 test_expect_success_multi () {
 
 171         test_expect_success_multiple "$@" "--index"
 
 174 test_expect_success_no_index_multi () {
 
 175         test_expect_success_multiple "$@" "--no-index"
 
 178 test_expect_success 'setup' '
 
 180         mkdir -p a/b/ignored-dir a/submodule b &&
 
 181         if test_have_prereq SYMLINKS
 
 190                 git commit -m"commit in submodule"
 
 192         git add a/submodule &&
 
 193         cat <<-\EOF >.gitignore &&
 
 200                 : >$dir/not-ignored &&
 
 201                 : >$dir/ignored-and-untracked &&
 
 202                 : >$dir/ignored-but-in-index
 
 204         git add -f ignored-but-in-index a/ignored-but-in-index &&
 
 205         cat <<-\EOF >a/.gitignore &&
 
 209         cat <<-\EOF >a/b/.gitignore &&
 
 212                 # this comment should affect the line numbers
 
 215                 # and so should this blank line:
 
 220         echo "seven" >a/b/ignored-dir/.gitignore &&
 
 222         cat <<-\EOF >"$global_excludes" &&
 
 227         cat <<-\EOF >>.git/info/exclude
 
 232 ############################################################################
 
 234 # test invalid inputs
 
 236 test_expect_success_multi '. corner-case' '::   .' '
 
 237         test_check_ignore . 1
 
 240 test_expect_success_multi 'empty command line' '' '
 
 241         test_check_ignore "" 128 &&
 
 242         stderr_contains "fatal: no path specified"
 
 245 test_expect_success_multi '--stdin with empty STDIN' '' '
 
 246         test_check_ignore "--stdin" 1 </dev/null &&
 
 250 test_expect_success '-q with multiple args' '
 
 252         test_check_ignore "-q one two" 128 &&
 
 253         stderr_contains "fatal: --quiet is only valid with a single pathname"
 
 256 test_expect_success '--quiet with multiple args' '
 
 258         test_check_ignore "--quiet one two" 128 &&
 
 259         stderr_contains "fatal: --quiet is only valid with a single pathname"
 
 262 for verbose_opt in '-v' '--verbose'
 
 264         for quiet_opt in '-q' '--quiet'
 
 266                 test_expect_success "$quiet_opt $verbose_opt" "
 
 268                         test_check_ignore '$quiet_opt $verbose_opt foo' 128 &&
 
 269                         stderr_contains 'fatal: cannot have both --quiet and --verbose'
 
 274 test_expect_success '--quiet with multiple args' '
 
 276         test_check_ignore "--quiet one two" 128 &&
 
 277         stderr_contains "fatal: --quiet is only valid with a single pathname"
 
 280 test_expect_success_multi 'erroneous use of --' '' '
 
 281         test_check_ignore "--" 128 &&
 
 282         stderr_contains "fatal: no path specified"
 
 285 test_expect_success_multi '--stdin with superfluous arg' '' '
 
 286         test_check_ignore "--stdin foo" 128 &&
 
 287         stderr_contains "fatal: cannot specify pathnames with --stdin"
 
 290 test_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"
 
 295 test_expect_success_multi '-z without --stdin' '' '
 
 296         test_check_ignore "-z" 128 &&
 
 297         stderr_contains "fatal: -z only makes sense with --stdin"
 
 300 test_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"
 
 305 test_expect_success_multi 'needs work tree' '' '
 
 308                 test_check_ignore "foo" 128
 
 310         stderr_contains "fatal: this operation must be run in a work tree"
 
 313 ############################################################################
 
 315 # test standard ignores
 
 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.
 
 321 for subdir in '' 'a/'
 
 327                 where="in subdir $subdir"
 
 330         test_expect_success_multi "non-existent file $where not ignored" \
 
 331                 "::     ${subdir}non-existent" \
 
 332                 "test_check_ignore '${subdir}non-existent' 1"
 
 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"
 
 338         test_expect_success_multi "non-existent file $where ignored" \
 
 339                 ".gitignore:1:one       ${subdir}one" \
 
 340                 "test_check_ignore '${subdir}one'"
 
 342         test_expect_success_no_index_multi "non-existent file $where ignored" \
 
 343                 ".gitignore:1:one       ${subdir}one" \
 
 344                 "test_check_ignore '${subdir}one'"
 
 346         test_expect_success_multi "existing untracked file $where not ignored" \
 
 347                 "::     ${subdir}not-ignored" \
 
 348                 "test_check_ignore '${subdir}not-ignored' 1"
 
 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"
 
 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"
 
 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'"
 
 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'"
 
 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'"
 
 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" \
 
 377                         ${subdir}non-existent
 
 380                         ${subdir}ignored-but-in-index
 
 381                         ${subdir}ignored-and-untracked'
 
 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" \
 
 391                         ${subdir}non-existent
 
 394                         ${subdir}ignored-but-in-index
 
 395                         ${subdir}ignored-and-untracked'
 
 399 # Having established the above, from now on we mostly test against
 
 400 # files which do not exist in the working tree or index.
 
 402 test_expect_success 'sub-directory local ignore' '
 
 403         expect "a/3-three" &&
 
 404         test_check_ignore "a/3-three a/three-not-this-one"
 
 407 test_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"
 
 412 test_expect_success 'local ignore inside a sub-directory' '
 
 416                 test_check_ignore "3-three three-not-this-one"
 
 419 test_expect_success 'local ignore inside a sub-directory with --verbose' '
 
 420         expect "a/.gitignore:2:*three   3-three" &&
 
 423                 test_check_ignore "--verbose 3-three three-not-this-one"
 
 427 test_expect_success_multi 'nested include' \
 
 428         'a/b/.gitignore:8:!on*  a/b/one' '
 
 429         test_check_ignore "a/b/one"
 
 432 ############################################################################
 
 434 # test ignored sub-directories
 
 436 test_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"
 
 441 test_expect_success 'multiple files inside ignored sub-directory' '
 
 442         expect_from_stdin <<-\EOF &&
 
 444                 a/b/ignored-dir/twoooo
 
 445                 a/b/ignored-dir/seven
 
 447         test_check_ignore "a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
 
 450 test_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
 
 456         test_check_ignore "-v a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
 
 459 test_expect_success 'cd to ignored sub-directory' '
 
 460         expect_from_stdin <<-\EOF &&
 
 468                 cd a/b/ignored-dir &&
 
 469                 test_check_ignore "foo twoooo ../one seven ../../one"
 
 473 test_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
 
 482                 cd a/b/ignored-dir &&
 
 483                 test_check_ignore "-v foo twoooo ../one seven ../../one"
 
 487 ############################################################################
 
 489 # test handling of symlinks
 
 491 test_expect_success_multi SYMLINKS 'symlink' '::        a/symlink' '
 
 492         test_check_ignore "a/symlink" 1
 
 495 test_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"
 
 500 test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
 
 503                 test_check_ignore "symlink/foo" 128
 
 505         test_stderr "fatal: pathspec '\''symlink/foo'\'' is beyond a symbolic link"
 
 508 ############################################################################
 
 510 # test handling of submodules
 
 512 test_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'\''"
 
 517 test_expect_success_multi 'submodule from subdirectory' '' '
 
 520                 test_check_ignore "submodule/one" 128
 
 522         test_stderr "fatal: Pathspec '\''submodule/one'\'' is in submodule '\''a/submodule'\''"
 
 525 ############################################################################
 
 527 # test handling of global ignore files
 
 529 test_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
 
 535         test_check_ignore "-v globalone per-repo a/globalthree a/per-repo not-ignored a/globaltwo"
 
 538 test_expect_success 'global ignore' '
 
 539         enable_global_excludes &&
 
 540         expect_from_stdin <<-\EOF &&
 
 548         test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
 
 551 test_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
 
 561         test_check_ignore "-v globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
 
 564 ############################################################################
 
 586 cat <<-\EOF >expected-default
 
 601 cat <<-EOF >expected-verbose
 
 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
 
 617 broken_c_unquote stdin >stdin0
 
 619 broken_c_unquote expected-default >expected-default0
 
 621 broken_c_unquote_verbose expected-verbose >expected-verbose0
 
 623 test_expect_success '--stdin' '
 
 624         expect_from_stdin <expected-default &&
 
 625         test_check_ignore "--stdin" <stdin
 
 628 test_expect_success '--stdin -q' '
 
 630         test_check_ignore "-q --stdin" <stdin
 
 633 test_expect_success '--stdin -v' '
 
 634         expect_from_stdin <expected-verbose &&
 
 635         test_check_ignore "-v --stdin" <stdin
 
 638 for opts in '--stdin -z' '-z --stdin'
 
 640         test_expect_success "$opts" "
 
 641                 expect_from_stdin <expected-default0 &&
 
 642                 test_check_ignore '$opts' <stdin0
 
 645         test_expect_success "$opts -q" "
 
 647                 test_check_ignore '-q $opts' <stdin0
 
 650         test_expect_success "$opts -v" "
 
 651                 expect_from_stdin <expected-verbose0 &&
 
 652                 test_check_ignore '-v $opts' <stdin0
 
 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.
 
 680 cat <<-EOF >expected-all
 
 681         .gitignore:1:one        ../one
 
 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
 
 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
 
 699 grep -v '^::    ' expected-all >expected-verbose
 
 700 sed -e 's/.*    //' expected-verbose >expected-default
 
 702 broken_c_unquote stdin >stdin0
 
 704 broken_c_unquote expected-default >expected-default0
 
 706 broken_c_unquote_verbose expected-verbose >expected-verbose0
 
 708 test_expect_success '--stdin from subdirectory' '
 
 709         expect_from_stdin <expected-default &&
 
 712                 test_check_ignore "--stdin" <../stdin
 
 716 test_expect_success '--stdin from subdirectory with -v' '
 
 717         expect_from_stdin <expected-verbose &&
 
 720                 test_check_ignore "--stdin -v" <../stdin
 
 724 test_expect_success '--stdin from subdirectory with -v -n' '
 
 725         expect_from_stdin <expected-all &&
 
 728                 test_check_ignore "--stdin -v -n" <../stdin
 
 732 for opts in '--stdin -z' '-z --stdin'
 
 734         test_expect_success "$opts from subdirectory" '
 
 735                 expect_from_stdin <expected-default0 &&
 
 738                         test_check_ignore "'"$opts"'" <../stdin0
 
 742         test_expect_success "$opts from subdirectory with -v" '
 
 743                 expect_from_stdin <expected-verbose0 &&
 
 746                         test_check_ignore "'"$opts"' -v" <../stdin0
 
 751 test_expect_success PIPE 'streaming support for --stdin' '
 
 753         (git check-ignore -n -v --stdin <in >out &) &&
 
 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
 
 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
 
 768         test_when_finished "exec 9>&-" &&
 
 769         test_when_finished "exec 8<&-" &&
 
 772         echo "$response" | grep "^\.gitignore:1:one     one" &&
 
 775         echo "$response" | grep "^::    two"
 
 778 test_expect_success 'existing file and directory' '
 
 779         test_when_finished "rm one" &&
 
 780         test_when_finished "rmdir top-level-dir" &&
 
 782         mkdir top-level-dir &&
 
 783         git check-ignore one top-level-dir >actual &&
 
 785         grep top-level-dir actual
 
 788 test_expect_success 'existing directory and file' '
 
 789         test_when_finished "rm one" &&
 
 790         test_when_finished "rmdir top-level-dir" &&
 
 792         mkdir top-level-dir &&
 
 793         git check-ignore top-level-dir one >actual &&
 
 795         grep top-level-dir actual
 
 798 ############################################################################
 
 800 # test whitespace handling
 
 802 test_expect_success 'trailing whitespace is ignored' '
 
 804         >whitespace/trailing &&
 
 805         >whitespace/untracked &&
 
 806         echo "whitespace/trailing   " >ignore &&
 
 810         git ls-files -o -X ignore whitespace >actual 2>err &&
 
 811         test_cmp expect actual &&
 
 812         test_must_be_empty err
 
 815 test_expect_success !MINGW 'quoting allows trailing whitespace' '
 
 818         >"whitespace/trailing  " &&
 
 819         >whitespace/untracked &&
 
 820         echo "whitespace/trailing\\ \\ " >ignore &&
 
 821         echo whitespace/untracked >expect &&
 
 822         git ls-files -o -X ignore whitespace >actual 2>err &&
 
 823         test_cmp expect actual &&
 
 824         test_must_be_empty err
 
 827 test_expect_success !MINGW,!CYGWIN 'correct handling of backslashes' '
 
 830         >"whitespace/trailing 1  " &&
 
 831         >"whitespace/trailing 2 \\\\" &&
 
 832         >"whitespace/trailing 3 \\\\" &&
 
 833         >"whitespace/trailing 4   \\ " &&
 
 834         >"whitespace/trailing 5 \\ \\ " &&
 
 835         >"whitespace/trailing 6 \\a\\" &&
 
 836         >whitespace/untracked &&
 
 837         sed -e "s/Z$//" >ignore <<-\EOF &&
 
 838         whitespace/trailing 1 \    Z
 
 839         whitespace/trailing 2 \\\\Z
 
 840         whitespace/trailing 3 \\\\ Z
 
 841         whitespace/trailing 4   \\\    Z
 
 842         whitespace/trailing 5 \\ \\\   Z
 
 843         whitespace/trailing 6 \\a\\Z
 
 845         echo whitespace/untracked >expect &&
 
 846         git ls-files -o -X ignore whitespace >actual 2>err &&
 
 847         test_cmp expect actual &&
 
 848         test_must_be_empty err
 
 851 test_expect_success 'info/exclude trumps core.excludesfile' '
 
 852         echo >>global-excludes usually-ignored &&
 
 853         echo >>.git/info/exclude "!usually-ignored" &&
 
 855         echo "?? usually-ignored" >expect &&
 
 857         git status --porcelain usually-ignored >actual &&
 
 858         test_cmp expect actual