.gitignore not working? Here's the fix

Most “gitignore is broken” reports have one cause: ignore rules do not apply to files Git already tracks. Untrack the file without deleting your local copy, commit that change, and the rule starts working.

🎙️ Published & recorded: ·

Fix an already-tracked file, then verify it

Gitignore decides which untracked files stay invisible. It does not retroactively remove a path from the repository. Add the rule first, remove only the index copy with the cached flag, then commit. The local file remains on disk. Before doing this to a folder, check the path carefully; the recursive command changes tracking for everything below it.

# .env was committed before the ignore rule existed:
git rm --cached .env

git commit -m "Stop tracking .env"

# Whole folder version; local files remain:
git rm -r --cached node_modules/
git commit -m "Stop tracking node_modules"

# Show the matching ignore file, line, and pattern:
git check-ignore -v .env
git status --ignored
Real error: Git is not tracking that pathfatal: pathspec '.env' did not match any files

First confirm the spelling and current directory. Run git ls-files -- .env. No output means there is no tracked index entry to remove, so skip the cached removal. Then run git check-ignore -v .env. If that also prints nothing, fix the ignore rule or the location of the gitignore file. If the file itself does not exist, create it only when your application needs it.

Use the patterns that actually matter

A bare filename or wildcard can match at more than one depth. A leading slash anchors the rule to the repository root. A trailing slash means directory only. Double star crosses directory levels, and an exclamation mark re-includes a path. Read rules from top to bottom because a later matching rule can change the earlier decision.

*.log             # every .log file, anywhere
build/            # directories named build
/config.json      # config.json only at repository root
docs/*.pdf        # PDFs directly inside docs
docs/**/*.pdf     # PDFs at any depth below docs
!keep.log         # exception to an earlier *.log rule

# Keep one file inside an otherwise ignored directory:
!logs/
logs/*
!logs/keep.txt
Why the obvious exception fails

If logs/ is ignored, Git stops walking into that directory, so a lone !logs/keep.txt cannot rescue the file. Re-include the directory, ignore its contents, then re-include the one file, in that order. Use git check-ignore -v logs/keep.txt after each edit instead of guessing which rule won.

Starter templates and committed-secret first aid

Start with generated files, dependency directories, local environments, and operating-system litter. Do not blindly ignore every editor directory; teams sometimes share useful workspace settings. For a real stack, compare your short list with the maintained templates in GitHub’s gitignore repository, then keep only rules you understand.

# Python
__pycache__/
*.pyc
.venv/
venv/
.env
dist/
*.egg-info/

# Node
node_modules/
dist/
build/
.env
.env.*
npm-debug.log*

# Common local litter
.DS_Store
Thumbs.db
*.swp
.idea/
.vscode/

If the tracked file contained a key, untracking is not incident response. The old value remains in earlier commits, forks, caches, and somebody else’s clone. Revoke or rotate the credential at the provider first. Then remove it from current tracking, update the application to use the replacement securely, and clean history with git filter-repo only if the repository policy requires it. Rotation makes the leaked value useless; rewriting history does not.

The order after a pushed secretOne: revoke or rotate the key now. Two: check access logs if the provider offers them. Three: replace the key in the deployment secret store. Four: remove the file from tracking and commit. Five: coordinate any history rewrite with every collaborator. Do not force-push cleaned history before the credential is dead.
This is one page of our Git series. For the repository model and the full audio guide, read Git in 10 Minutes →

Tell me what missed

A correction is more useful than a compliment. This goes straight to the person who writes SwiftGrasp.

Was this page useful?
0/1000

Please do not include passwords, private keys, or personal information.