From: Junio C Hamano Date: Fri, 20 Sep 2013 19:37:32 +0000 (-0700) Subject: Merge branch 'dw/check-ignore-sans-index' X-Git-Tag: v1.8.5-rc0~92 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/005a1de380733477382c50e2e44ed8042c401fed?ds=inline;hp=-c 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 --- 005a1de380733477382c50e2e44ed8042c401fed diff --combined builtin/check-ignore.c index e2a1cef684,8b3c2e3e27..594463a11b --- a/builtin/check-ignore.c +++ b/builtin/check-ignore.c @@@ -5,7 -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 < ", @@@ -24,6 -24,8 +24,8 @@@ static const struct option check_ignore 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() }; @@@ -64,45 -66,37 +66,45 @@@ static void output_exclude(const char * } static int check_ignore(struct dir_struct *dir, - const char *prefix, const char **pathspec) + const char *prefix, int argc, const char **argv) { - const char *path, *full_path; + const char *full_path; char *seen; int num_ignored = 0, dtype = DT_UNKNOWN, i; struct exclude *exclude; + struct pathspec pathspec; - if (!pathspec || !*pathspec) { + if (!argc) { if (!quiet) fprintf(stderr, "no pathspec given.\n"); return 0; } + /* + * check-ignore just needs paths. Magic beyond :/ is really + * irrelevant. + */ + parse_pathspec(&pathspec, + PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP, + PATHSPEC_SYMLINK_LEADING_PATH | + PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE | + PATHSPEC_KEEP_ORDER, + prefix, argv); + /* * look for pathspecs matching entries in the index, since these * should not be ignored, in order to be consistent with * 'git status', 'git add' etc. */ - seen = find_pathspecs_matching_against_index(pathspec); - for (i = 0; pathspec[i]; i++) { - path = pathspec[i]; - full_path = prefix_path(prefix, prefix - ? strlen(prefix) : 0, path); - full_path = check_path_for_gitlink(full_path); - die_if_path_beyond_symlink(full_path, prefix); + seen = find_pathspecs_matching_against_index(&pathspec); + for (i = 0; i < pathspec.nr; i++) { + full_path = pathspec.items[i].match; exclude = NULL; if (!seen[i]) { exclude = last_exclude_matching(dir, full_path, &dtype); } if (!quiet && (exclude || show_non_matching)) - output_exclude(path, exclude); + output_exclude(pathspec.items[i].original, exclude); if (exclude) num_ignored++; } @@@ -128,8 -122,7 +130,8 @@@ static int check_ignore_stdin_paths(str strbuf_swap(&buf, &nbuf); } pathspec[0] = buf.buf; - num_ignored += check_ignore(dir, prefix, (const char **)pathspec); + num_ignored += check_ignore(dir, prefix, + 1, (const char **)pathspec); maybe_flush_or_die(stdout, "check-ignore to stdout"); } strbuf_release(&buf); @@@ -166,7 -159,7 +168,7 @@@ int cmd_check_ignore(int argc, const ch 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)); @@@ -175,7 -168,7 +177,7 @@@ if (stdin_paths) { num_ignored = check_ignore_stdin_paths(&dir, prefix); } else { - num_ignored = check_ignore(&dir, prefix, argv); + num_ignored = check_ignore(&dir, prefix, argc, argv); maybe_flush_or_die(stdout, "ignore to stdout"); } diff --combined t/t0008-ignores.sh index 96f40fedfb,d0826139a5..181513ab4f --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@@ -66,11 -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 +87,9 @@@ # 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 +97,26 @@@ # 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 +126,8 @@@ 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 -137,7 +137,7 @@@ 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 -150,21 +150,21 @@@ 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 +308,7 @@@ test_expect_success_multi 'needs work t # 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 +323,61 @@@ ":: ${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 @@@ -432,7 -486,7 +486,7 @@@ test_expect_success_multi SYMLINKS 'sym 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' '' ' @@@ -440,7 -494,7 +494,7 @@@ 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" ' ############################################################################ @@@ -449,7 -503,7 +503,7 @@@ 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' '' ' @@@ -457,7 -511,7 +511,7 @@@ 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'\''" ' ############################################################################