git rm
On this page, you can find useful information about git rm command, learn how to use and undo it and see the difference of the shell rm and git rm command.
The git rm command removes one or more files from a Git repository. This page explains what git rm does, the options it accepts, how it differs from the shell's rm, how to undo a removal, and a few practical recipes.
What git rm does
git rm removes tracked files — files that Git already knows about. By default it deletes the file from both the working directory (the files on your disk) and the staging index (the snapshot Git will record in the next commit), then stages that deletion so it lands in your next commit.
A few facts worth knowing up front:
git rmonly works on tracked files. It fails withfatal: pathspec '...' did not match any filesif you try to remove an untracked file — Git wasn't following that file, so there is nothing to record.- It can remove a file from the staging index alone (with
--cached), but it cannot remove a file only from the working directory — that is just a plain delete, which is what the shellrmdoes. - It does not remove branches, tags, or commits. It only touches files.
- The removal is not permanent until you commit. Before that, it is easy to undo (see Undoing git rm).

A typical workflow looks like this:
git rm notes.txt # deletes notes.txt and stages the deletion
git commit -m "Remove notes.txt"Options of git rm command
| Option | What it does |
|---|---|
<file>… | The path(s) to remove. Accepts file globs such as *.txt. |
-f, --force | Overrides the safety check that compares the file in HEAD with the staging index and working directory. Needed when the file has uncommitted changes. |
-n, --dry-run | Runs the command without removing anything. It only lists the files it would have removed. |
-r | Recursive. Required to remove a directory together with all of its contents. |
-- | Separates options from file names. Use it when a file name could be mistaken for an option (for example a file literally named -f). |
--cached | Removes the file from the staging index only. The working-directory copy is left untouched. |
--ignore-unmatch | Exits with status 0 even when no files matched. Useful in scripts that should not fail on a missing path. |
-q, --quiet | Suppresses the per-file output that git rm normally prints. |
Undoing git rm
git rm updates the staging index and the working directory, but the change is not permanent until you commit. Until then you can recover the file with ordinary Git commands. Which one you need depends on how far you want to roll back.
Before you commit the removal
To unstage the removal but keep the file deleted on disk, reset the index entry back to HEAD:
git reset HEAD <file>To bring the file back completely — both in the staging index and in the working directory — use the modern git restore command:
git restore --staged --worktree <file>The older equivalents git reset HEAD <file> followed by git checkout -- <file> still work, but git restore is the recommended way in current Git.
After you commit the removal
If you already created a commit that records the deletion, the file lives only in history. Find a safe point with git reflog and restore the file from a commit where it still existed:
git restore --source=HEAD~1 <file>Git rm vs rm
The shell's rm and git rm both delete files from disk, but Git treats them very differently.
When you run the plain shell rm on a tracked file, the Git repository notices the file is gone and shows the deletion as an unstaged change. You still have to run git add (or git add -u) to record it in the staging index before committing.
git rm does both steps at once: it deletes the file and stages the deletion, so it is ready for the next commit immediately.
# Shell rm — deletion is unstaged, needs git add afterwards
rm notes.txt
git add notes.txt
# git rm — deletion is staged in one step
git rm notes.txtRemoving files from the index only
A common case is keeping a file on disk but stopping Git from tracking it — for example a config file or build artifact you accidentally committed and now want to ignore. Use --cached:
git rm --cached secrets.envThe file stays in your working directory; only the tracked copy is removed. Add the path to .gitignore afterwards so it is not re-added.
Examples
Remove every .txt file in a folder (wildcard):
git rm folder/\*.txtThe backslash before * stops your shell from expanding the glob, so Git itself expands it across the tracked files under folder/. This matches paths in subdirectories too, not only direct children.
Force-remove files that have uncommitted changes:
git rm -f git-*.shWithout -f, git rm refuses to delete a file whose working-directory or staged content differs from HEAD, to protect you from losing work. The force flag overrides that check.
Preview a removal without deleting anything:
git rm -r --dry-run logs/This lists the files that would be removed under logs/, letting you confirm the set before running the command for real.
Removing files already deleted with shell rm
If you have deleted several tracked files with the shell rm and want to record all of them in your next commit, stage every deletion at once:
git add -u
git commit -m "Remove obsolete files"git add -u stages updates to already-tracked files, including deletions. Alternatively, build a list of the deleted paths and pipe them to git rm --cached:
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached--diff-filter=D selects only deleted paths, and the -z / -0 pair uses NUL separators so file names with spaces are handled safely.