If Git on your Mac is ignoring a file, run git check-ignore -v -- 'path/to/file' from the repository in Terminal. The output identifies the ignore source, line number, matching pattern and path, so you can find the rule and decide whether to change it. If the file is already tracked, repeat the check with --no-index.
Run the check from the repository
Open Terminal and move to the repository’s top-level directory. You can type cd with a trailing space, drag the project folder from Finder into the Terminal window to insert its path, then press Return. Confirm you are in a Git working tree with git status; if Git reports that the directory is not a repository, move into the project’s actual repository folder first.
Use the path to the file relative to the repository root. For example, to diagnose build/cache.json, run:
git check-ignore -v -- 'build/cache.json'
The single quotes make the path literal to the default macOS shell, zsh. They are especially useful when a name contains spaces or characters such as * that the shell would otherwise interpret. The -- marks the end of options, which also prevents a path beginning with a hyphen from being treated as a flag.
Read the output to locate the rule
A verbose match looks like this:
.gitignore:12:build/ build/cache.json
The fields mean: .gitignore is the source file, 12 is its line number, build/ is the pattern, and build/cache.json is the path you queried. Open that source file in your preferred text editor and inspect the reported line. The source may instead be a nested .gitignore, .git/info/exclude, or a global excludes file configured for your Git account. Git documents the verbose output fields and these ignore sources.
A source path under .git/info/exclude applies to this repository but is not normally shared with other clones. A global excludes file applies to your own repositories. A .gitignore pattern is generally the right place for a rule the project should share. Git checks ignore sources by precedence: lower-level .gitignore files can override parent rules, and the last matching pattern at the same precedence level determines the result. The gitignore manual explains the precedence and intended use of each source.
If Git prints nothing
No output usually means no ignore pattern matched that path. The command’s normal output lists ignored paths; use -v to see the deciding pattern. Check that you are in the correct repository and that the spelling and capitalization of the path are exact.
Tracked files are a common source of confusion: by default, git check-ignore does not report them because ignore rules apply to files that are not already tracked. Add --no-index to ask Git to check the rules anyway:
git check-ignore -v --no-index -- 'build/cache.json'
This option diagnoses the rule; it does not untrack the file or remove it from a commit. Git’s documented method for stopping tracking is git rm --cached, followed by an appropriate ignore rule. That changes the index, so inspect the status and understand the effect before running it. Git explains the tracked-file limitation and --no-index option.
Check negations and pattern scope
A matching line beginning with ! is a negation: it can bring a path back into view after an earlier ignore pattern, so a verbose match to such a line does not mean the file remains ignored. Git also cannot re-include a file if a parent directory is excluded; the parent directory must first be made traversable through matching rules. Git’s pattern documentation describes negation and this parent-directory limitation.
Patterns are interpreted relative to the .gitignore file that contains them. A pattern with a slash is scoped to that file’s directory level; a simple name pattern can match at that level and below. This matters when a rule comes from a nested .gitignore: the printed pattern may look right while applying to a different subtree than expected. Check the source file’s location as well as the pattern text.
For one file, git check-ignore -v is usually enough to identify where to look. For a tracked file, include --no-index; after that, use the reported source, line, and pattern to determine whether the rule should be changed, narrowed, or left in place.