Merge branch 'lb/contrib-contacts-looser-diff-parsing'
[gitweb.git] / t / t0008-ignores.sh
index 7af93ba928ece85265509537b521764827194955..63beb99828cc17d2ec8218a6470b62c02a78806b 100755 (executable)
@@ -37,6 +37,14 @@ test_stderr () {
        test_cmp "$HOME/expected-stderr" "$HOME/stderr"
 }
 
+broken_c_unquote () {
+       "$PERL_PATH" -pe 's/^"//; s/\\//; s/"$//; tr/\n/\0/' "$@"
+}
+
+broken_c_unquote_verbose () {
+       "$PERL_PATH" -pe 's/    "/      /; s/\\//; s/"$//; tr/:\t\n/\0/' "$@"
+}
+
 stderr_contains () {
        regexp="$1"
        if grep "$regexp" "$HOME/stderr"
@@ -66,11 +74,11 @@ test_check_ignore () {
 
        init_vars &&
        rm -f "$HOME/stdout" "$HOME/stderr" "$HOME/cmd" &&
-       echo git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $args \
+       echo git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $no_index_opt $args \
                >"$HOME/cmd" &&
        echo "$expect_code" >"$HOME/expected-exit-code" &&
        test_expect_code "$expect_code" \
-               git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $args \
+               git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $no_index_opt $args \
                >"$HOME/stdout" 2>"$HOME/stderr" &&
        test_cmp "$HOME/expected-stdout" "$HOME/stdout" &&
        stderr_empty_on_success "$expect_code"
@@ -87,6 +95,9 @@ test_check_ignore () {
 # check-ignore --verbose output is the same as normal output except
 # for the extra first column.
 #
+# A parameter is used to determine if the tests are run with the
+# normal case (using the index), or with the --no-index option.
+#
 # Arguments:
 #   - (optional) prereqs for this test, e.g. 'SYMLINKS'
 #   - test name
@@ -94,19 +105,26 @@ test_check_ignore () {
 #     from the other verbosity modes is automatically inferred
 #     from this value)
 #   - code to run (should invoke test_check_ignore)
-test_expect_success_multi () {
+#   - index option: --index or --no-index
+test_expect_success_multiple () {
        prereq=
-       if test $# -eq 4
+       if test $# -eq 5
        then
                prereq=$1
                shift
        fi
+       if test "$4" = "--index"
+       then
+               no_index_opt=
+       else
+               no_index_opt=$4
+       fi
        testname="$1" expect_all="$2" code="$3"
 
        expect_verbose=$( echo "$expect_all" | grep -v '^::     ' )
        expect=$( echo "$expect_verbose" | sed -e 's/.* //' )
 
-       test_expect_success $prereq "$testname" '
+       test_expect_success $prereq "$testname${no_index_opt:+ with $no_index_opt}" '
                expect "$expect" &&
                eval "$code"
        '
@@ -116,7 +134,8 @@ test_expect_success_multi () {
        then
                for quiet_opt in '-q' '--quiet'
                do
-                       test_expect_success $prereq "$testname${quiet_opt:+ with $quiet_opt}" "
+                       opts="${no_index_opt:+$no_index_opt }$quiet_opt"
+                       test_expect_success $prereq "$testname${opts:+ with $opts}" "
                        expect '' &&
                        $code
                "
@@ -126,7 +145,7 @@ test_expect_success_multi () {
 
        for verbose_opt in '-v' '--verbose'
        do
-               for non_matching_opt in '' ' -n' ' --non-matching'
+               for non_matching_opt in '' '-n' '--non-matching'
                do
                        if test -n "$non_matching_opt"
                        then
@@ -139,12 +158,21 @@ test_expect_success_multi () {
                                expect '$my_expect' &&
                                $code
                        "
-                       opts="$verbose_opt$non_matching_opt"
+                       opts="${no_index_opt:+$no_index_opt }$verbose_opt${non_matching_opt:+ $non_matching_opt}"
                        test_expect_success $prereq "$testname${opts:+ with $opts}" "$test_code"
                done
        done
        verbose_opt=
        non_matching_opt=
+       no_index_opt=
+}
+
+test_expect_success_multi () {
+       test_expect_success_multiple "$@" "--index"
+}
+
+test_expect_success_no_index_multi () {
+       test_expect_success_multiple "$@" "--no-index"
 }
 
 test_expect_success 'setup' '
@@ -216,11 +244,7 @@ test_expect_success_multi 'empty command line' '' '
 
 test_expect_success_multi '--stdin with empty STDIN' '' '
        test_check_ignore "--stdin" 1 </dev/null &&
-       if test -n "$quiet_opt"; then
-               test_stderr ""
-       else
-               test_stderr "no pathspec given."
-       fi
+       test_stderr ""
 '
 
 test_expect_success '-q with multiple args' '
@@ -292,7 +316,7 @@ test_expect_success_multi 'needs work tree' '' '
 
 # First make sure that the presence of a file in the working tree
 # does not impact results, but that the presence of a file in the
-# index does.
+# index does unless the --no-index option is used.
 
 for subdir in '' 'a/'
 do
@@ -307,27 +331,61 @@ do
                "::     ${subdir}non-existent" \
                "test_check_ignore '${subdir}non-existent' 1"
 
+       test_expect_success_no_index_multi "non-existent file $where not ignored" \
+               "::     ${subdir}non-existent" \
+               "test_check_ignore '${subdir}non-existent' 1"
+
        test_expect_success_multi "non-existent file $where ignored" \
                ".gitignore:1:one       ${subdir}one" \
                "test_check_ignore '${subdir}one'"
 
+       test_expect_success_no_index_multi "non-existent file $where ignored" \
+               ".gitignore:1:one       ${subdir}one" \
+               "test_check_ignore '${subdir}one'"
+
        test_expect_success_multi "existing untracked file $where not ignored" \
                "::     ${subdir}not-ignored" \
                "test_check_ignore '${subdir}not-ignored' 1"
 
+       test_expect_success_no_index_multi "existing untracked file $where not ignored" \
+               "::     ${subdir}not-ignored" \
+               "test_check_ignore '${subdir}not-ignored' 1"
+
        test_expect_success_multi "existing tracked file $where not ignored" \
                "::     ${subdir}ignored-but-in-index" \
                "test_check_ignore '${subdir}ignored-but-in-index' 1"
 
+       test_expect_success_no_index_multi "existing tracked file $where shown as ignored" \
+               ".gitignore:2:ignored-* ${subdir}ignored-but-in-index" \
+               "test_check_ignore '${subdir}ignored-but-in-index'"
+
        test_expect_success_multi "existing untracked file $where ignored" \
                ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" \
                "test_check_ignore '${subdir}ignored-and-untracked'"
 
+       test_expect_success_no_index_multi "existing untracked file $where ignored" \
+               ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" \
+               "test_check_ignore '${subdir}ignored-and-untracked'"
+
        test_expect_success_multi "mix of file types $where" \
 "::    ${subdir}non-existent
 .gitignore:1:one       ${subdir}one
 ::     ${subdir}not-ignored
 ::     ${subdir}ignored-but-in-index
+.gitignore:2:ignored-* ${subdir}ignored-and-untracked" \
+               "test_check_ignore '
+                       ${subdir}non-existent
+                       ${subdir}one
+                       ${subdir}not-ignored
+                       ${subdir}ignored-but-in-index
+                       ${subdir}ignored-and-untracked'
+               "
+
+       test_expect_success_no_index_multi "mix of file types $where" \
+"::    ${subdir}non-existent
+.gitignore:1:one       ${subdir}one
+::     ${subdir}not-ignored
+.gitignore:2:ignored-* ${subdir}ignored-but-in-index
 .gitignore:2:ignored-* ${subdir}ignored-and-untracked" \
                "test_check_ignore '
                        ${subdir}non-existent
@@ -436,7 +494,7 @@ test_expect_success_multi SYMLINKS 'symlink' '::    a/symlink' '
 
 test_expect_success_multi SYMLINKS 'beyond a symlink' '' '
        test_check_ignore "a/symlink/foo" 128 &&
-       test_stderr "fatal: '\''a/symlink/foo'\'' is beyond a symbolic link"
+       test_stderr "fatal: pathspec '\''a/symlink/foo'\'' is beyond a symbolic link"
 '
 
 test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
@@ -444,7 +502,7 @@ test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
                cd a &&
                test_check_ignore "symlink/foo" 128
        ) &&
-       test_stderr "fatal: '\''symlink/foo'\'' is beyond a symbolic link"
+       test_stderr "fatal: pathspec '\''symlink/foo'\'' is beyond a symbolic link"
 '
 
 ############################################################################
@@ -453,7 +511,7 @@ test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
 
 test_expect_success_multi 'submodule' '' '
        test_check_ignore "a/submodule/one" 128 &&
-       test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
+       test_stderr "fatal: Pathspec '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
 '
 
 test_expect_success_multi 'submodule from subdirectory' '' '
@@ -461,7 +519,7 @@ test_expect_success_multi 'submodule from subdirectory' '' '
                cd a &&
                test_check_ignore "submodule/one" 128
        ) &&
-       test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
+       test_stderr "fatal: Pathspec '\''submodule/one'\'' is in submodule '\''a/submodule'\''"
 '
 
 ############################################################################
@@ -556,12 +614,11 @@ cat <<-EOF >expected-verbose
        $global_excludes:2:!globaltwo   b/globaltwo
 EOF
 
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
-       tr "\n" "\0" >stdin0
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
-       tr "\n" "\0" >expected-default0
-sed -e 's/     "/      /' -e 's/\\//' -e 's/"$//' expected-verbose | \
-       tr ":\t\n" "\0" >expected-verbose0
+broken_c_unquote stdin >stdin0
+
+broken_c_unquote expected-default >expected-default0
+
+broken_c_unquote_verbose expected-verbose >expected-verbose0
 
 test_expect_success '--stdin' '
        expect_from_stdin <expected-default &&
@@ -642,12 +699,11 @@ EOF
 grep -v '^::   ' expected-all >expected-verbose
 sed -e 's/.*   //' expected-verbose >expected-default
 
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
-       tr "\n" "\0" >stdin0
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
-       tr "\n" "\0" >expected-default0
-sed -e 's/     "/      /' -e 's/\\//' -e 's/"$//' expected-verbose | \
-       tr ":\t\n" "\0" >expected-verbose0
+broken_c_unquote stdin >stdin0
+
+broken_c_unquote expected-default >expected-default0
+
+broken_c_unquote_verbose expected-verbose >expected-verbose0
 
 test_expect_success '--stdin from subdirectory' '
        expect_from_stdin <expected-default &&
@@ -692,5 +748,62 @@ do
        '
 done
 
+test_expect_success PIPE 'streaming support for --stdin' '
+       mkfifo in out &&
+       (git check-ignore -n -v --stdin <in >out &) &&
+
+       # We cannot just "echo >in" because check-ignore would get EOF
+       # after echo exited; instead we open the descriptor in our
+       # shell, and then echo to the fd. We make sure to close it at
+       # the end, so that the subprocess does get EOF and dies
+       # properly.
+       #
+       # Similarly, we must keep "out" open so that check-ignore does
+       # not ever get SIGPIPE trying to write to us. Not only would that
+       # produce incorrect results, but then there would be no writer on the
+       # other end of the pipe, and we would potentially block forever trying
+       # to open it.
+       exec 9>in &&
+       exec 8<out &&
+       test_when_finished "exec 9>&-" &&
+       test_when_finished "exec 8<&-" &&
+       echo >&9 one &&
+       read response <&8 &&
+       echo "$response" | grep "^\.gitignore:1:one     one" &&
+       echo >&9 two &&
+       read response <&8 &&
+       echo "$response" | grep "^::    two"
+'
+
+############################################################################
+#
+# test whitespace handling
+
+test_expect_success 'trailing whitespace is ignored' '
+       mkdir whitespace &&
+       >whitespace/trailing &&
+       >whitespace/untracked &&
+       echo "whitespace/trailing   " >ignore &&
+       cat >expect <<EOF &&
+whitespace/untracked
+EOF
+       : >err.expect &&
+       git ls-files -o -X ignore whitespace >actual 2>err &&
+       test_cmp expect actual &&
+       test_cmp err.expect err
+'
+
+test_expect_success !MINGW 'quoting allows trailing whitespace' '
+       rm -rf whitespace &&
+       mkdir whitespace &&
+       >"whitespace/trailing  " &&
+       >whitespace/untracked &&
+       echo "whitespace/trailing\\ \\ " >ignore &&
+       echo whitespace/untracked >expect &&
+       : >err.expect &&
+       git ls-files -o -X ignore whitespace >actual 2>err &&
+       test_cmp expect actual &&
+       test_cmp err.expect err
+'
 
 test_done