In Git, how do you find which ignore file and line is excluding a specific path?
answer
- Ask Git rather than reading files by hand
- One command reports the deciding rule
- Verbose mode names source, line and pattern
- A flag exists to skip the index lookup
basics
~20 sRun git check-ignore -v <path>. Git prints the source file, line number and pattern that excluded the path, and exits with status 1 when nothing matches it. Add --no-index to check a path that is already tracked.
solid answer
~50 s`git check-ignore -v <path>` is the built-in answer. For each path it prints the deciding rule in the form `source:line:pattern` followed by a tab and the path, so you learn not just *that* something matched but exactly which file and line did, whether that is a nested `.gitignore`, `.git/info/exclude` or your global excludes file. Its exit status is scriptable: 0 when at least one path is ignored, 1 when none are, 128 on a real error. Two options matter in practice. `--no-index` skips the index lookup, which is how you debug why a path got tracked despite a pattern that looks like it should have matched. `-n` (`--non-matching`) combined with `-v` also prints the paths that matched nothing, so you can feed in a list and see every verdict. For the wider picture, `git status --ignored` lists what is currently being hidden.
code
console · 5 lines$ git check-ignore -v src/debug.log
.gitignore:12:*.log src/debug.log
$ git check-ignore -v README.md
$ echo $?
1go deeper
Remember that Git can tell you why a path is hidden. Running the check command with the verbose flag and reading the source, line and pattern it prints is enough at this level.
Explain the output fields and the exit-status contract, and know that the check consults the index by default so tracked paths report as not ignored unless you skip it.
Show how you use it to diagnose environment differences: a rule sourced from a personal global excludes file explains why a file is missing on one machine or in a CI checkout but present elsewhere.
Own the guardrails: audit proposed ignore changes against a file list before merging them, and keep rules that affect everyone inside the repository rather than in personal configuration that no reviewer can see.
## The problem it solves A path can be excluded by a pattern in the directory next to it, in any parent directory up to the top of the work tree, in `.git/info/exclude`, or in the personal file named by `core.excludesFile`. Reading all of them by hand and applying "last match wins" mentally is slow and error prone. `git check-ignore` performs exactly the query Git performs and reports the verdict. ## Reading the verbose output With `-v`, each ignored path produces a line of four tab-separated fields: the source file, the line number within it, the pattern text, and the path itself. An output such as `.gitignore:12:*.log src/debug.log` tells you the decision came from line 12 of the root ignore file. When the source is reported as the global file or `.git/info/exclude`, you have just learned the rule is not in the repository at all, which is the usual explanation for "it works on my machine but not on the CI checkout", or the reverse. Without `-v`, the command simply echoes the paths that are ignored, which is what you want when scripting. ## Exit status `check-ignore` is a plumbing-flavoured command with meaningful exit codes: 0 if one or more of the given paths is ignored, 1 if none are, and 128 if a fatal error occurred. That makes a shell guard around `git check-ignore -q "$f"` clean to write, with `-q` suppressing output. ## The index interaction By default the command consults the index, matching Git's real behaviour that ignore rules do not apply to tracked paths. So a tracked file usually reports as not ignored even when a pattern matches its name. When you are investigating exactly that situation, for example a file that `git add .` picked up when you expected it to be skipped, pass `--no-index`: Git then answers the pure pattern question, ignoring whether the path is tracked. Comparing the two runs is the fastest way to distinguish "no rule matches" from "a rule matches but the file was already tracked". ## Companion commands - `git status --ignored` lists ignored paths alongside the normal status output, which answers "what is Git hiding from me in this tree". - `git ls-files --others --ignored --exclude-standard` enumerates untracked-but-ignored files, useful for auditing what a build leaves behind. - `git clean -Xn` previews removing only ignored files, a dry run worth doing before any `git clean` variant. - `git add -f <path>` force-adds a path despite the rules, which is the escape hatch when you genuinely want one exception without editing patterns. Note that `git add` on an ignored path otherwise refuses and prints a hint mentioning the force option. ## Multiple paths and stdin You can pass several paths at once, or feed them with `--stdin`, which pairs well with `-v -n` to produce a full verdict table for a generated list of files. That is how you audit whether a proposed ignore-file change would hide something it should not. ## Habits worth forming When a pattern "does not work", check three things in order: run `check-ignore -v` to see whether any rule matches at all; if a rule matches but the file is still showing up, suspect that the path is already tracked; if no rule matches, suspect anchoring, a trailing space, or a negation cancelled by a later broad pattern. Almost every ignore mystery falls into one of those three buckets, and the first command distinguishes them in a second.
- Why might git check-ignore report a path as not ignored even though a pattern clearly matches its name?Because by default the command consults the index, and ignore rules do not apply to tracked paths. If the file was added before the pattern existed, the honest answer is "not ignored". Re-run with `--no-index` to get the pure pattern verdict; if that reports a match, the fix is to untrack the file rather than to edit patterns.
- What does git status --ignored give you that git check-ignore does not?Direction. `check-ignore` answers a question about paths you name, while `status --ignored` enumerates what is currently being hidden in the working tree. Use the first to explain a specific surprise, and the second to review what a build has left behind or to spot a rule that is hiding more than intended.
saying these in an interview costs you the question
- Greps every .gitignore manually instead of asking Git
- Thinks the command edits or removes ignore rules
- Ignores that tracked paths report as not ignored
- Assumes the rule must live in the repository itself
- Confuses it with git status --ignored, which lists files