Removing Files (git rm)
git rm removes a file from your project and stages that removal so the next commit reflects it. It is a single command that does two things at once: delete from the working directory and record the deletion in Git’s index. You can also use it to stop tracking a file without deleting it from disk.
Three common scenarios
Delete a file from your project and commit the removal.
Stop tracking a file but keep it on disk (e.g., when you realise you should not have committed
.env).Remove a folder and all its contents.
1. Delete a tracked file
Delete from disk AND stage the removal
git rm old-file.txt # rm 'old-file.txt' git status # Changes to be committed: # deleted: old-file.txt git commit -m "Remove old-file.txt"
2. Stop tracking a file but keep it locally
Did you accidentally commit a .env file or a build artifact that should have been ignored? Use --cached:
--cached keeps the file on disk
git rm --cached .env # rm '.env' (the index entry) # .env is still on disk; Git has just stopped tracking it git status # deleted: .env ← staged removal from history # Untracked files: ← but still here on disk # .env # Add the file to .gitignore so it never gets re-added echo ".env" >> .gitignore git commit -m "Stop tracking .env"
3. Recursive removal
Whole folders
git rm -r old-folder/ git commit -m "Remove old-folder" # --cached + -r for entire folder, keep files on disk git rm -r --cached node_modules echo "node_modules/" >> .gitignore git commit -m "Stop tracking node_modules"
Forced removal
Git refuses to delete a file that has uncommitted changes — it does not want to lose your work. -f overrides the safety check.
git rm -f some-file.txt # Use only when you're sure you don't need the local edits
git rm vs rm
rm file.txt— removes the file from disk. Git sees a deletion but does not auto-stage it; you would still needgit add file.txtto record the deletion.git rm file.txt— does both at once: removes the file and stages the deletion.Either way you can commit the result.
git rmis just less typing.
Dry run — see what would happen
git rm -r --cached -n logs/ # Would remove logs/access.log # Would remove logs/error.log
Undoing git rm
Restore a file you just removed (before committing)
git restore --staged removed-file.txt # unstage the removal git restore removed-file.txt # put the file back from HEAD
Restore a file you removed AND committed
# Find the commit that still has it git log --all -- removed-file.txt # Bring back the version from that commit git checkout <commit-hash>~1 -- removed-file.txt git commit -m "Restore removed-file.txt"
Globs and patterns
Quoted patterns let Git do the expansion
git rm "logs/*.log" git rm "**/*.tmp"
Common mistakes
Running
rminstead ofgit rmand forgetting to stage —git statuswill show "deleted" but the change is not staged.git add -Aorgit add <file>fixes it.Using
git rmon a file with unsaved changes — Git stops you. Use-fonly if you truly want to discard those changes.Thinking
git rm --cacheddeletes from history — it does not. Old commits still contain the file. Usegit filter-repoto scrub historical content.Forgetting to update
.gitignoreafter--cached— the next time someone runsgit add ., the file comes right back into the index.
git rm -r --cached folder/ → echo 'folder/' >> .gitignore → git commit. Old commits still have it; new commits and clones will not.