Skip to content

Commit

Permalink
check-ignore: Add option to ignore index contents
Browse files Browse the repository at this point in the history
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>`.

The option --no-index tells the command to bypass 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 <dave@opensourcesolutions.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Dave Williams authored and Junio C Hamano committed Sep 12, 2013
1 parent 57e4c17 commit 8231fa6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 11 deletions.
7 changes: 7 additions & 0 deletions Documentation/git-check-ignore.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ OPTIONS
not be possible to distinguish between paths which match a
pattern and those which don't.

--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
------

Expand Down
6 changes: 4 additions & 2 deletions builtin/check-ignore.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>",
Expand All @@ -24,6 +24,8 @@ static const struct option check_ignore_options[] = {
N_("terminate input and output records by a NUL character")),
OPT_BOOL('n', "non-matching", &show_non_matching,
N_("show non-matching input paths")),
OPT_BOOL(0, "no-index", &no_index,
N_("ignore index when checking")),
OPT_END()
};

Expand Down Expand Up @@ -157,7 +159,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));
Expand Down
72 changes: 63 additions & 9 deletions t/t0008-ignores.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -87,26 +87,36 @@ 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
# - output to expect from the fourth verbosity mode (the output
# 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"
'
Expand All @@ -116,7 +126,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
"
Expand All @@ -126,7 +137,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
Expand All @@ -139,12 +150,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' '
Expand Down Expand Up @@ -288,7 +308,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
Expand All @@ -303,27 +323,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
Expand Down

0 comments on commit 8231fa6

Please sign in to comment.