Reputation: 5041
When I want to revert changes of a file I use
git checkout -- path/to/file.ext
. But somehow I have to execute the command twice now.
After the first checkout git diff
shows nothing but the file is still listed as modified on my stage.
Only after the second checkout the file is removed from the stage.
Is this intended behaviour?
Upvotes: 2
Views: 615
Reputation: 12465
You have to git reset the file.
git reset path/to/file.ext
This will unstage a file. git checkout
will discard the changes in working directory.
In your case if it's staged you can do a reset first to unstage it and then git checkout the file.
It's not the intended behavior of checkout to do it twice to unstage.
Upvotes: 1
Reputation: 487805
The command:
git checkout -- path/to/file.ext
copies the contents of path/to/file.ext
from the staging-area to the work-tree. It does not change the contents stored in the staging-area, and running it twice should make no difference at all: copying from staging-area to work-tree, then copying again from staging-area to work-tree, should result in the same work-tree contents on the second copy as on the first.
Note that there is a third version of the file—well, we should really call it the first one—which is the copy that is in the current commit. When you check out some commit, Git:
This means that there are three active versions of the file at all times:
HEAD:path/to/file.ext
: this one is read-only, permanently stored in the commit, in a special, compressed, Git-only form. Use git show HEAD:path/to/file.ext
to see it, for instance.
:path/to/file.ext
: this one is read/write, and not permanent. It is stored in the staging-area (also called the index, or sometimes the cache), also in a special compressed Git-only form. The difference between this and the first file is that this one, you can overwrite, and whatever is in the index/staging-area copy is what will go into the next commit you make. Use git show :path/to/file.ext
to see this copy.
Using git add path/to/file.ext
copies the work-tree version to the index / staging-area.
Using git checkout -- path/to/file.ext
copies the index / staging-area version to the work-tree.
Using git reset path/to/file.ext
copies the HEAD:path/to/file.ext
version from the commit to the index / staging-area, without affecting the work-tree version.
Last, there is the work-tree version, path/to/file.ext
. This file is stored in your computer's normal format, so that you and your computer can work with it.
(If you want to copy the HEAD
version of the file to both the index/staging-area and the work-tree, you can do that with git checkout HEAD path/to/file.ext
.)
Note that when you run git status
, this runs, in effect, two diffs:
HEAD
vs index: whatever is different here is "staged for commit".You never see the index / staging-area directly: you only see it in comparison to either the HEAD
commit, or in comparison to the work-tree. This makes sense because, in a large project, the index / staging-area has thousands of files all the time, but usually only a few are different from either the current commit, or the work-tree, or both.
Upvotes: 4