Hakim
Hakim

Reputation: 3437

Difference between git reset and git rm --cached when removing from staging index

I have a problem: when I haven't yet commited, and I have added a file to the index (stage) the command

git rm --cached <file>  

is unstaging it perfectly. Here It's clear that I cant use git reset because there is not yet a HEAD commit.

But when I commit some files. and I try to execute git rm --cached to unstage a modified file (previously added to index), here when execute git status -s, I see this file appearing twice (filename = index.php):

D index.php file has been deleted, so that's normal.
?? index.php but why it's appearing twice and as if it's untracked?

PS: git reset is unstaging files after the commit.

Upvotes: 0

Views: 428

Answers (1)

CB Bailey
CB Bailey

Reputation: 792847

git rm --cached <file> removes a file from the index in its entirety. Always. If there is no version of the file in the HEAD commit then that effectively means that the index for this path matches HEAD (nothing there; no change) but if there is a version of the file in the HEAD commit then that is effectively staging a deletion of the file.

Either way, there is no version of the file in the index so the file is becoming "untracked". (You might not consider it untracked until the commit which commits this deletion is actually made, but it counts as untracked when git status compares the working tree against the index to see unstaged changes.)

If the file does not match a .gitignore pattern then it will appear as an untracked file. This is because if you specify --cached, git rm only operates on the index and not on your working copy as it would without --cached so the file still exists in the working tree.

git reset <file> doesn't unstage files; it unstages changes to files by restoring the HEAD version into the index. git rm --cached <file> simply removes files from the index, i.e. stages deletions of files.

Upvotes: 2

Related Questions