GitRemoving Files (git rm)

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

Bash
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

Bash
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"
Warning
Removing a file with `--cached` only removes it from *future* commits. The previous commits still contain the file — anyone who has cloned the repo can still see its old contents in history. If it was a secret, rotate it.
3. Recursive removal

Whole folders

Bash
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.

Bash
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 need git add file.txt to 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 rm is just less typing.

Dry run — see what would happen

Bash
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)

Bash
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

Bash
# 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

Bash
git rm "logs/*.log"
git rm "**/*.tmp"
Why the quotes?
Without quotes, your shell expands the glob *before* Git sees it. Quoting lets Git handle the expansion, which works better across directories and files Git knows about.
Common mistakes
  • Running rm instead of git rm and forgetting to stagegit status will show "deleted" but the change is not staged. git add -A or git add <file> fixes it.

  • Using git rm on a file with unsaved changes — Git stops you. Use -f only if you truly want to discard those changes.

  • Thinking git rm --cached deletes from history — it does not. Old commits still contain the file. Use git filter-repo to scrub historical content.

  • Forgetting to update .gitignore after --cached — the next time someone runs git add ., the file comes right back into the index.

Tip
For removing an entire folder from history (because you accidentally committed `dist/` or `.env`), the recipe is: git rm -r --cached folder/ echo 'folder/' >> .gitignore git commit. Old commits still have it; new commits and clones will not.