Posted By: Anonymous
git rmwill remove entries from the
staging area. This is a bit different
git reset HEADwhich “unstages”
files. By “unstage” I mean it reverts
the staging area to what was there
before we started modifying things.
git rmon the other hand just kicks
the file off the stage entirely, so
that it’s not included in the next
commit snapshot, thereby effectively
By default, a
git rm filewill remove the file from the staging area entirely and also off your disk > (the working directory). To leave the file in the working directory, you can use
git rm --cached.
But what exactly is the difference between
git rm --cached asd and
git reset head -- asd?
There are three places where a file, say, can be – the (committed) tree, the index and the working copy. When you just add a file to a folder, you are adding it to the working copy.
When you do something like
git add file you add it to the index. And when you commit it, you add it to the tree as well.
It will probably help you to know the three more common flags in
git reset [–
This form resets the current branch head to
updates the index (resetting it to the tree of
<commit>) and the
working tree depending on
<mode>, which must be one of the
Does not touch the index file nor the working tree at all (but resets
the head to
<commit>, just like all modes do). This leaves all your
changed files "Changes to be committed", as git status would put it.
Resets the index but not the working tree (i.e., the changed files
are preserved but not marked for commit) and reports what has not been
updated. This is the default action.
Resets the index and working tree. Any changes to tracked files in
the working tree since
Now, when you do something like
git reset HEAD, what you are actually doing is
git reset HEAD --mixed and it will "reset" the index to the state it was before you started adding files / adding modifications to the index (via
git add). In this case, no matter what the state of the working copy was, you didn’t change it a single bit, but you changed the index in such a way that is now in sync with the HEAD of the tree. Whether
git add was used to stage a previously committed but changed file, or to add a new (previously untracked) file,
git reset HEAD is the exact opposite of
git rm, on the other hand, removes a file from the working directory and the index, and when you commit, the file is removed from the tree as well.
git rm --cached, however, removes the file from the index alone and keeps it in your working copy. In this case, if the file was previously committed, then you made the index to be different from the HEAD of the tree and the working copy, so that the HEAD now has the previously committed version of the file, the index has no file at all, and the working copy has the last modification of it. A commit now will sync the index and the tree, and the file will be removed from the tree (leaving it untracked in the working copy). When
git add was used to add a new (previously untracked) file, then
git rm --cached is the exact opposite of
git add (and is pretty much identical to
git reset HEAD).
Git 2.25 introduced a new command for these cases,
git restore, but as of Git 2.28 it is described as “experimental” in the man page, in the sense that the behavior may change.