Let's say foo.c
is staged and bar.c
has been modified but is not staged. Is there a way to get every non-staged file, which in this case is bar.c
, reset back to HEAD without foo.c
getting out of stage ?
I know that commiting won't write bar's changes in history I would just like to avoid commiting since I am building a script.
S. KUMAR's answer, which you have accepted, is generally correct for what you intend. It's worth noting several details though.
Remember that there are three active copies every file as far as git status
is concerned:
foo.c
exists in HEAD (HEAD:foo.c
), in the index / staging-area (:0:foo.c
), and in the work-tree (foo.c
).bar.c
exists in HEAD (HEAD:bar.c
), in the index / staging-area (:0:bar.c
), and in the work-tree (bar.c
).When you say:
Let's say
foo.c
is staged andbar.c
has been modified but is not staged ...
what you mean, in Git terms anyway, is:
HEAD:foo.c
!= :0:foo.c
, but :0:foo.c
== foo.c
HEAD:bar.c
== :0:bar.c
, but :0:bar.c
!= bar.c
Note that it's possible to have all three copies of any one file differ from each other, and you get this quite normally by using git add -p
for instance. If you ran git add -p bar.c
and selected some, but not all, of the patch hunks, you'd end up with this state.
When you run git status
, Git first diffs HEAD
-vs-index and reports whatever is different as changes staged for commit. It then diffs index-vs-work-tree and reports whatever is different as changes not staged for commit (and potentially reports untracked files as well).
Running:
git checkout <path>
tells Git to copy the index (aka staging-area) version of the file to the work-tree. That is, for every file matching <path>
, copy :0:<path>
to <path>
.
Given your setup above, this overwrites foo.c
from :0:foo.c
, which leaves foo.c
unchanged. It also overwrites bar.c
from :0:bar.c
, which changes bar.c
back to what is in HEAD:bar.c
, since :0:bar.c
matched (and still matches) HEAD:bar.c
.
It's also worth mentioning that running:
git reset <path>
tells Git to copy the HEAD
version of the file(s) to the index. This leaves the work-tree alone. You can work out for yourself what this does to :0:foo.c
and :0:bar.c
.