Home / Alt manpages / git-rm(1)

  • git-rm(1)
  • User command
  • linux

Remove tracked files safely with git rm

You will remove a tracked file from both your working tree and Git's index, or remove it from the index while leaving the file on disk. Allow about ten minutes for a single file and a little longer for a directory or a recovery check. These commands are ordinary user commands. You normally do not need sudo, and using it can leave the repository owned by root.

1. Check the repository and the target

Run this from the repository that contains the file. The installed command on this machine is Git 2.43.0, from the Ubuntu git-man package version 1:2.43.0-1ubuntu7.3. The guide follows that local manual page, including its index and sparse-checkout behaviour.

$ git --version
git version 2.43.0
$ git status --short
$ git ls-files -- path/to/old-config.ini
path/to/old-config.ini

The second command should show the path if Git tracks it. An empty result means that git rm is probably the wrong tool, because it removes paths known to Git. Read the status before acting so that an existing staged change or an unrelated dirty file does not surprise you.

Checkpoint

You have confirmed the repository, the exact tracked path and the change you intend to make.

2. Preview the removal

Use --dry-run before a removal that matters. It reports the paths that would be removed without changing the index or working tree.

$ git rm --dry-run -- path/to/old-config.ini
rm 'path/to/old-config.ini'

The -- separates options from pathspecs. Keep it when a filename could begin with a hyphen, or simply use it as a clear boundary in scripts. The output is a plan, not proof that the command will still succeed later: another process or an earlier command can change the repository between the preview and the real operation.

3. Remove one file from disk and the index

Once the preview is correct, run the same command without --dry-run:

$ git rm -- path/to/old-config.ini
rm 'path/to/old-config.ini'
$ git status --short
D  path/to/old-config.ini

This stages the deletion and removes the working-tree file. It is not a commit. The deletion remains local until you commit it, so check the staged diff before sharing or merging the change:

$ git diff --cached --stat
 path/to/old-config.ini | 12 ------------
 1 file changed, 12 deletions(-)
$ git diff --cached -- path/to/old-config.ini

Warning

Do not treat a successful git rm as a backup. A file removed from the working tree is not recoverable from an uncommitted working copy. If the content existed in a previous commit, Git can usually restore it, but verify that history contains the version you need before committing anything irreversible.

4. Keep the file locally but stop tracking it

For a local configuration file that should remain on this machine, use --cached:

$ git rm --cached -- config/local.ini
rm 'config/local.ini'
$ test -f config/local.ini && echo 'file remains on disk'
file remains on disk
$ git status --short
D  config/local.ini
?? config/local.ini

The staged deletion tells the next commit to remove the file from the repository. The untracked entry shows that the working copy still exists. Add a suitable pattern to .gitignore before committing if this is a generated or machine-specific file. Do not add real passwords, tokens or private keys to an ignore file as a substitute for rotating a secret that was already committed.

--cached can also remove a modified path from the index when the staged content matches either the branch tip or the working file. For other changes, Git refuses by default so that you do not silently discard staged work.

5. Remove a directory or a selected group

A leading directory name needs -r. Preview first, especially if the directory contains more than the files you meant to delete:

$ git rm -r --dry-run -- docs/generated
rm 'docs/generated/index.html'
rm 'docs/generated/version.txt'
$ git rm -r -- docs/generated

Pathspec matching is performed by Git when the pattern is quoted. This can include matching files below nested directories. For example, the quoted pattern below selects tracked text files below Documentation:

$ git rm --dry-run -- 'Documentation/*.txt'

Quoting is a useful distraction trap here. An unquoted * may be expanded by the shell first, changing what Git receives. A pattern such as 'd*' can also match a directory named d2, whereas 'd/*' describes paths below d. Use --pathspec-from-file for a long list, and add --pathspec-file-nul when the list is NUL-separated or contains newlines and quotes that must be treated literally.

6. Handle modified files deliberately

By default, git rm refuses a file whose working-tree or staged content has changed from the branch tip. That refusal protects edits:

$ git rm -- path/to/edited-file
error: the following file has local modifications:
    path/to/edited-file

First decide whether those edits are needed. Save them in a commit or a patch if they matter. If deletion is definitely intended, -f or --force overrides the up-to-date check and removes the file. Preview with the same force option first:

$ git rm --dry-run --force -- path/to/edited-file
rm 'path/to/edited-file'
$ git rm --force -- path/to/edited-file

Warning

Force is destructive to the uncommitted working copy. It is not an elevated-privilege operation, and it does not make the discarded content recoverable by itself.

7. Undo before committing

If you remove a file and change your mind before committing, restore both the index and working tree from the current HEAD:

$ git restore --source=HEAD --staged --worktree -- path/to/old-config.ini
$ git status --short
$ test -f path/to/old-config.ini && echo restored
restored

For a --cached removal where you want to keep the local file and only undo the staged deletion, restore the index without touching the working tree:

$ git restore --source=HEAD --staged -- config/local.ini
$ git status --short
 M config/local.ini

Check the output carefully. If the path was already modified before the removal, restoring from HEAD may replace that working copy. A committed deletion needs a different recovery step, such as restoring the path from the commit that still contains it, then reviewing and committing that restoration.

8. Deal with missing files and submodules

If a tracked file was already deleted with ordinary rm, git rm is not required. git add -u or git commit -a can record such removals in their broader workflows. If you want to remove only disappeared paths from the index while leaving other dirty work alone, inspect the deleted-path list first rather than applying a broad command.

A submodule has extra history and metadata. The manual distinguishes removing a submodule with git rm from removing only its local checkout with git submodule deinit. Use the latter when the repository should remain configured and only the checkout should disappear. Never delete a submodule's internal .git directory casually, because an older layout can contain the submodule's history.

Done means

  • The target path was confirmed with git ls-files and previewed with --dry-run.
  • You chose between deleting the working copy and using --cached to keep it.
  • Directory removals used -r, and pathspecs were quoted where Git should expand them.
  • Modified files were saved or explicitly reviewed before any use of --force.
  • git diff --cached shows only the intended deletion, and the change has not been committed until recovery is no longer needed.