Stop tracking a local config file—and treat any secret as exposed
Confirm why ignore rules appear ineffective, preserve the local file, remove it from the index, handle teammate impact and rotate credentials already committed.
You add config/local.env to .gitignore, but Git still reports modifications. That is expected: ignore rules describe intentionally untracked files. They do not retroactively remove a path already present in the index or erase it from previous commits.
Establish tracked and ignored state separately
git status --short
git ls-files --stage -- config/local.env
git check-ignore -v --no-index config/local.env
git ls-files proves whether the path is in the index. git check-ignore -v --no-index shows the matching ignore rule even for a tracked path. Without --no-index, tracked files are intentionally not reported as ignored.
Add a precise repository rule
# Local runtime configuration; never commit
/config/local.env
# Commit a safe schema/example instead
!/config/local.env.example
The leading slash anchors the first pattern to the repository root. Keep a reviewed example containing names and safe placeholders—not usable credentials. Verify:
git check-ignore -v --no-index config/local.env
git check-ignore -v config/local.env.example || true
Remove only the index entry
git rm --cached -- config/local.env
git status --short
test -f config/local.env && echo 'local file preserved'
Git’s official documentation defines --cached as removing the path from the index while leaving the working-tree file alone. Review the staged diff before committing:
git diff --cached -- .gitignore config/local.env
git commit -m 'chore: stop tracking local runtime configuration'
Understand the teammate and deployment effect
The commit records deletion of the tracked path. When another clone updates, Git can remove its tracked copy. The fact that your own working file survived git rm --cached does not mean every teammate keeps theirs after pulling the commit.
Coordinate the change: announce the path, provide the safe example, document how to generate local configuration, and instruct operators to back up their current file outside the working tree before updating. Deployment systems should materialize configuration from a secret manager or managed environment, not rely on a mutable file surviving Git operations.
If the file contained a secret, rotate first
git log --all -- config/local.env
git log -p --all -- config/local.env
Do not print secret history into shared terminals or CI logs. Use approved secret-scanning tooling and restricted evidence handling. Once a credential entered any commit or remote, assume it was copied:
- Revoke or disable the old credential.
- Create a replacement with least privilege and short lifetime.
- Update the secret manager and dependent services.
- Verify access with the new identity.
- Review audit logs for use of the old credential.
Adding .gitignore and committing a deletion do not invalidate the leaked value.
Decide whether history rewriting is warranted
Removing sensitive blobs from reachable history can reduce accidental rediscovery, but it is a coordinated repository rewrite: commit IDs change, open branches and forks may retain the old objects, clones must be replaced or carefully repaired, and caches/backups may still contain copies. Rotation remains mandatory.
If policy requires rewriting, use the organization’s approved history-rewrite procedure, make a recoverable mirror backup, enumerate all refs, coordinate a freeze, force-update intentionally, expire old objects where appropriate, and rescan the remote. Do not improvise destructive filter commands on the only repository copy.
Untrack a generated directory without touching local contents
git rm -r --cached -- build/
git diff --cached --stat
find build -maxdepth 2 -type f | head
Quote pathspecs and review the staged list. Avoid the popular broad recipe that removes the entire index and re-adds everything; it can stage unrelated deletions, permission changes and generated files across a dirty worktree.
Choose the correct ignore scope
| Pattern audience | Location |
|---|---|
| Everyone working on the project | Committed .gitignore |
| Only this clone | .git/info/exclude |
| All repositories for one user | core.excludesFile |
| Already tracked path | Remove from index first; ignore afterward |
Do not commit personal editor or operating-system patterns to every project unless the team wants them. Repository rules should describe project artifacts.
Verify from a clean clone
git status --short
git ls-files --error-unmatch config/local.env && exit 1 || true
git check-ignore -v config/local.env
git ls-files --error-unmatch config/local.env.example
Then test the onboarding and deployment path from a fresh clone: the application should fail with a clear missing-configuration message or generate safe local scaffolding. It must not silently fall back to production credentials.
Prevent recurrence
- Add secret scanning to pre-commit guidance and server-side CI.
- Use short-lived identities instead of long-lived static keys.
- Keep real configuration outside the release tree.
- Review archives, build contexts and container layers for accidental inclusion.
- Protect logs from dumping environment variables.
.gitignoreis an admission-control rule for future untracked files. It is neither an eraser nor a credential-revocation system.
Sources: the solved Stack Overflow question (question by Ivan; accepted answer by Lara Bailey, CC BY-SA), Git’s official gitignore, git-rm, and git-ls-files documentation.
Primary source: Review the official reference ↗