Max Herrmann Max Herrmann - 6 months ago 47
Git Question

Unexpected behavior of 'git rm'

Given a Git repository and a committed file


I remove the file with an O/S command:
$ rm a

git status

On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

deleted: a

no changes added to commit (use "git add" and/or "git commit -a")

Next, I'm calling
git rm
followed by
git status
which yields:

On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

deleted: a

Git's man pages description of the command
git rm

Remove files from the index, or from the working tree and the index.

From my understanding, what happened in the above command sequence is that
git rm
put the change of deleting the file into the staging area (which I'm using synonymously with index), instead of removing something from it.

What is my misconception here?

Answer Source

What git rm does is add the change to the index to remove a file from the working directory. So you are staging the removal of a file. This may sound a bit weird but this is the clearest way you can think of it.

A commit contains changes, changes you have previously staged. Usual changes include new files and file changes, but also file removals. So the removal of a file is considered a change, and by calling git rm you are adding that change to the index.

This is btw. the reason why you can use things like git add -u to add all pending changes and also have file removals included: The file removal is a pending change, so when you add it, you are adding the change to remove the file.

In addition, what git rm also does it physically remove the file from the working directory. So if you did not delete the file using rm first, Git would have deleted it from the working directory as well. If the file is already removed, then Git will only stage the removal change. Related to this is git rm --cached which will also stage the removal of the file but will not physically remove the file from the working directory. So this will only stage the change to remove the file (although that change hasn’t been physically executed).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download