Merge branch 'dw/check-ignore-sans-index'

"git check-ignore" follows the same rule as "git add" and "git
status" in that the ignore/exclude mechanism does not take effect
on paths that are already tracked.  With "--no-index" option, it
can be used to diagnose which paths that should have been ignored
have been mistakenly added to the index.

* dw/check-ignore-sans-index:
  check-ignore: Add option to ignore index contents
This commit is contained in:
Junio C Hamano 2013-09-20 12:37:32 -07:00
commit 005a1de380
3 changed files with 74 additions and 11 deletions

View File

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

View File

@ -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_("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()
};
@ -166,7 +168,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));

View File

@ -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 --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 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 +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
"
@ -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' '
@ -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
@ -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