I have updated the original version of this patch to encompass the
feedback comments obtained. Updates include:
1) Rename option to --no-index for consistency with other commands
2) Improved Documentation text
3) Extension to test scripts to include this option

Regarding test scripts I have scoped coverage to ensure correct
behaviour with the new option in all standard cases but without
duplicating every single corner case.

The original patch is at $gmane/233381.



check-ignore currently shows how .gitignore rules would treat untracked
paths. Tracked paths do not generate useful output.  This prevents
debugging of why a path became tracked unexpectedly unless that path is
first removed from the index with `git rm --cached <path>`.

This option (-i, --no-index) simply by-passes the check for the path
being in the index and hence allows tracked paths to be checked too.

Whilst this behaviour deviates from the characteristics of `git add` and
`git status` its use case is unlikely to cause any user confusion.

Test scripts are augmented to check this option against the standard
ignores to ensure correct behaviour.

Signed-off-by: Dave Williams <d...@opensourcesolutions.co.uk>
---
 Documentation/git-check-ignore.txt |  7 ++++
 builtin/check-ignore.c             | 14 ++++---
 t/t0008-ignores.sh                 | 77 +++++++++++++++++++++++++++++++++-----
 3 files changed, 83 insertions(+), 15 deletions(-)

diff --git a/Documentation/git-check-ignore.txt 
b/Documentation/git-check-ignore.txt
index d2df487..96c591f 100644
--- a/Documentation/git-check-ignore.txt
+++ b/Documentation/git-check-ignore.txt
@@ -45,6 +45,13 @@ OPTIONS
        not be possible to distinguish between paths which match a
        pattern and those which don't.
 
+-i, --no-index::
+       Don't look in the index when undertaking the checks. This can
+       be used to debug why a path became tracked by e.g. `git add .`
+       and was not ignored by the rules as expected by the user or when
+       developing patterns including negation to match a path previously
+       added with `git add -f`.
+
 OUTPUT
 ------
 
diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c
index 4a8fc70..2b0c8a6 100644
--- a/builtin/check-ignore.c
+++ b/builtin/check-ignore.c
@@ -5,7 +5,7 @@
 #include "pathspec.h"
 #include "parse-options.h"
 
-static int quiet, verbose, stdin_paths, show_non_matching;
+static int quiet, verbose, stdin_paths, show_non_matching, no_index;
 static const char * const check_ignore_usage[] = {
 "git check-ignore [options] pathname...",
 "git check-ignore [options] --stdin < <list-of-paths>",
@@ -24,6 +24,8 @@ static const struct option check_ignore_options[] = {
                    N_("input paths are terminated by a null character")),
        OPT_BOOLEAN('n', "non-matching", &show_non_matching,
                    N_("show non-matching input paths")),
+       OPT_BOOLEAN('i', "no-index", &no_index,
+                   N_("ignore index when checking")),
        OPT_END()
 };
 
@@ -67,7 +69,7 @@ static int check_ignore(struct dir_struct *dir,
                        const char *prefix, const char **pathspec)
 {
        const char *path, *full_path;
-       char *seen;
+       char *seen = NULL;
        int num_ignored = 0, dtype = DT_UNKNOWN, i;
        struct exclude *exclude;
 
@@ -82,7 +84,9 @@ static int check_ignore(struct dir_struct *dir,
         * should not be ignored, in order to be consistent with
         * 'git status', 'git add' etc.
         */
-       seen = find_pathspecs_matching_against_index(pathspec);
+       if (!no_index) {
+               seen = find_pathspecs_matching_against_index(pathspec);
+       }
        for (i = 0; pathspec[i]; i++) {
                path = pathspec[i];
                full_path = prefix_path(prefix, prefix
@@ -90,7 +94,7 @@ static int check_ignore(struct dir_struct *dir,
                full_path = check_path_for_gitlink(full_path);
                die_if_path_beyond_symlink(full_path, prefix);
                exclude = NULL;
-               if (!seen[i]) {
+               if (no_index || !seen[i]) {
                        exclude = last_exclude_matching(dir, full_path, &dtype);
                }
                if (!quiet && (exclude || show_non_matching))
@@ -157,7 +161,7 @@ int cmd_check_ignore(int argc, const char **argv, const 
char *prefix)
                die(_("--non-matching is only valid with --verbose"));
 
        /* read_cache() is only necessary so we can watch out for submodules. */
-       if (read_cache() < 0)
+       if (!no_index && read_cache() < 0)
                die(_("index file corrupt"));
 
        memset(&dir, 0, sizeof(dir));
diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh
index c29342d..0ad0534 100755
--- a/t/t0008-ignores.sh
+++ b/t/t0008-ignores.sh
@@ -66,11 +66,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 +87,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 -i or --no_index option.
+#
 # Arguments:
 #   - (optional) prereqs for this test, e.g. 'SYMLINKS'
 #   - test name
@@ -94,19 +97,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, -i or --no-index
+test_expect_success_multitude () {
        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"
        '
@@ -114,9 +124,10 @@ test_expect_success_multi () {
        # --quiet is only valid when a single pattern is passed
        if test $( echo "$expect_all" | wc -l ) = 1
        then
-               for quiet_opt in '-q' '--quiet'
+               for quiet_opt in ' -q' ' --quiet'
                do
-                       test_expect_success $prereq "$testname${quiet_opt:+ 
with $quiet_opt}" "
+                       opts="$no_index_opt$quiet_opt"
+                       test_expect_success $prereq "$testname${opts:+ with 
$opts}" "
                        expect '' &&
                        $code
                "
@@ -124,7 +135,7 @@ test_expect_success_multi () {
                quiet_opt=
        fi
 
-       for verbose_opt in '-v' '--verbose'
+       for verbose_opt in ' -v' ' --verbose'
        do
                for non_matching_opt in '' ' -n' ' --non-matching'
                do
@@ -139,12 +150,24 @@ test_expect_success_multi () {
                                expect '$my_expect' &&
                                $code
                        "
-                       opts="$verbose_opt$non_matching_opt"
+                       opts="$no_index_opt$verbose_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_multitude "$@" "--index"
+}
+
+test_expect_success_no_index_multi () {
+       for ni in '-i' '--no-index'
+       do
+               test_expect_success_multitude "$@" "$ni"
+       done
 }
 
 test_expect_success 'setup' '
@@ -288,7 +311,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
@@ -303,22 +326,42 @@ 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
@@ -332,6 +375,20 @@ do
                        ${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
+                       ${subdir}one
+                       ${subdir}not-ignored
+                       ${subdir}ignored-but-in-index
+                       ${subdir}ignored-and-untracked'
+               "
 done
 
 # Having established the above, from now on we mostly test against
-- 
1.8.4.rc3

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to