The command git rm is, naturally, the converse of git add. It removes a file from both the repository and the working directory. However, because removing a file tends to be more problematic (if something goes wrong) than adding a file, Git treats the removal of a file with a bit more care.
Git will remove a file only from the index or from the index and working directory simultaneously. Git will not remove a file from just the working directory; the regular rm command may be used for that purpose.
Removing a file from your directory and the index does not remove the file’s history from the repository. Any versions of the file that are part of history already committed in the repository remain in the object store and retain that history.
Continuing the example, let’s introduce an “accidental” additional file that shouldn’t be staged and see how to remove it:
$echo "Random stuff" > oops
# Can't "git rm" files Git considers "other" # This should be just "rm oops" $git rm oops
fatal: pathspec 'oops' did not match any files
Since git rm is also an operation on the index, the command won’t work on a file that hasn’t been previously added to the repository or index; Git must first be aware of a file. So let’s accidentally stage the oops file:
# Accidentally stage "oops" file $git add oops
$git status
# On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: .gitignore # new file: data # new file: oops #
To convert a file from staged to unstaged, use git rm --cached:
$git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0 .gitignore 100644 e476983f39f6e4f453f0fe4a859410f63b58b500 0 data 100644 fcd87b055f261557434fa9956e6ce29433a5cd1c 0 oops $git rm --cached oops
rm 'oops' $git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0 .gitignore 100644 e476983f39f6e4f453f0fe4a859410f63b58b500 0 data
Whereas git rm --cached removes the file from the index and leaves it in the working directory, git rm removes the file from both the index and the working directory.
Using git rm --cached to make a file untracked while leaving a copy in the working directory is dangerous as you may forget that it is no longer being tracked. Using this approach also overrides Git’s check that the working file’s contents are current. Be careful.
If you want to remove a file once it’s been committed, just stage
the request through a simple git rm
filename
:
$git commit -m "Add some files"
Created initial commit 5b22108: Add some files 2 files changed, 3 insertions(+), 0 deletions(-) create mode 100644 .gitignore create mode 100644 data $git rm data
rm 'data' $git status
# On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: data #
Before Git removes a file, it checks to make sure the version of
the file in the working directory matches the latest version in the
current branch (the version that Git commands call the
HEAD
). This verification precludes the accidental
loss of any changes (due to your editing) that may have been made to the
file. For git rm to work, the file in the working
directory must match either the HEAD
or the contents
of the index.
Use git rm -f to force the removal of your file. Force is an explicit mandate and removes the file even if you have altered it since your last commit.
And in case you really meant to keep a file that you accidentally removed, simply add it back:
$ git add data
fatal: pathspec 'data' did not match any files
Darn! Git removed the working copy, too! But don’t worry. Version control systems are good at recovering old versions of files:
$git checkout HEAD -- data
$cat data
New data And some more data now $git status
# On branch master nothing to commit (working directory clean)
3.136.87.35