Git & GitHub · 9 min · 110 XP
Committed something you shouldn't have
Stop tracking a file that shouldn't be in git, and what to do when a secret leaks.
Two different accidents. The first is a file that's tracked but shouldn't be, like node_modules/ committed before the .gitignore existed. Adding it to .gitignore now changes nothing, because .gitignore only affects files git isn't tracking yet. You have to untrack it: git rm --cached removes it from the repository and leaves it on your disk.
echo "node_modules/" >> .gitignore git rm -r --cached node_modules # untrack it; the folder stays on disk git commit -m "Stop tracking node_modules"
The second is a secret: an API key, a password, a .env file. If it was pushed, treat the key as stolen and replace it first. Revoke it wherever it was issued and make a new one. Automated scanners watch public GitHub for keys, and a leaked one can be in use within minutes, long before you've cleaned up history. Rotating the key is the fix. Removing it from git is tidying up.
Then take it out of the repository. If it's only in your latest commit and you haven't pushed, git rm --cached .env, add .env to .gitignore, and git commit --amend. If it's further back or already pushed, deleting the file in a new commit isn't enough, because earlier commits still hold it. Rewriting all of history takes a tool such as git filter-repo, and every collaborator has to re-clone afterwards. That's why rotating comes first.
GitHub's push protection may block a push that contains a key it recognises. If it does, it has done you a favour: fix the commit before pushing rather than bypassing the block.
$ cat .gitignore node_modules/ $ git status --short M node_modules/.package-lock.json
Try it on your machine: in your practice repository, commit a folder called build/ with a file in it. Add build/ to .gitignore and change the file: git status still shows it. Untrack it with git rm -r --cached build and commit, then change the file again and see git ignore it.
Loading your workspace…