Why .gitignore is not ignoring a file

Check whether a file is already tracked, diagnose ignore-pattern precedence, and stop tracking generated files without deleting local copies.

Best practices
Illustration of Git branches and version history

First check whether the file is already tracked. .gitignore controls untracked paths; adding a rule does not remove a tracked file from the index. If the path is untracked, inspect the matching pattern and any later exceptions.

git ls-files -- path/to/file
git check-ignore -v -- path/to/file

The first command prints the tracked path when it is in the index. The second diagnoses ignore rules for untracked paths.

Stop tracking a file you want to ignore

Add the intended rule to .gitignore, then remove the file from the index while retaining the current local copy:

git rm --cached -- secret.env
git add .gitignore
git commit -m "Stop tracking local configuration"

For a tracked directory, use git rm -r --cached -- node_modules/. The ignore rule takes effect once the path is no longer tracked; committing records the removal for others. Collaborators receiving that removal may lose their previously tracked local copy, so preserve needed local configuration before updating.

If a real secret was committed, ignoring it does not remove it from history. Revoke or rotate it and evaluate a separate history cleanup.

Check pattern scope and syntax

With these examples in the root .gitignore:

# A file or directory named log at any depth.
log

# A root-level file or directory named log.
/log

# Directories named logs at any depth.
logs/

# Files or directories whose names end in .log.
*.log

# Direct children of the root logs directory.
logs/*.log

# Matching paths at any depth beneath root logs.
logs/**/*.log

These illustrate alternative scopes; you do not need all of them. Comments must be on their own lines. Text after a pattern is not an inline comment and can change what the rule matches.

Look for overriding exceptions

Within the same precedence level, the last matching pattern wins:

*.log
!important.log

An exception cannot re-include a file whose parent directory is excluded. Rules in a nearer subdirectory .gitignore can override broader rules, subject to that parent-directory limitation.

git check-ignore -v -- path/to/file
git check-ignore -v --no-index -- path/to/tracked-file
git status --ignored

Verbose output identifies the source file, line, and matching pattern. It can also display a negated pattern: read the leading ! before concluding that a file is excluded. No output for an already tracked file does not prove there is no matching rule.

FAQ

Why does a subdirectory's .gitignore not affect its siblings?

Its scope is that directory and its descendants. Put shared rules in an appropriate common ancestor, usually the repository root.

Why is my global ignore file unused?

Check the configuration and path:

git config --show-origin --get core.excludesFile
git config --global core.excludesFile ~/.gitignore_global

The same tracked-file limitation applies.

Can I temporarily ignore changes to an already tracked configuration file?

Git does not provide a reliable general-purpose switch for this. assume-unchanged and skip-worktree are not substitutes for an ignored local configuration file. Prefer a committed template or defaults file plus a separate ignored local override that the application loads.

See gitignore, git-check-ignore, git-rm, and Git's configuration-file FAQ.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting