Did you have staged files you want to keep staged, or are you willing to have all files go back to completely unstaged?
The latter is very easy: use git reset
with no additional arguments, as galath commented. This does a --mixed
reset:
- move the current branch to the named commit, but with no named commit, that means move the current branch to
HEAD
, and HEAD
is the current commit, so we move the current commit to itself, which does nothing; then
- replace files in the index with their versions in the named commit (which, again, we didn't name, so that's the
HEAD
commit).
(These two steps are the --soft
and --mixed
parts; without --hard
, git reset
skips the third step of wiping out work-tree changes. Obviously you don't want those wiped out, so you should not use --hard
.)
The former is harder. To get a list of all staged files, use:
git diff --cached --name-only
If you want to selectively re-set most, but not all, of these files, you can write those file names to a file (preferably outside your work-tree) such as /tmp/list
, then edit the file to remove the names you want to keep staged. Then:
git reset -- $(cat /tmp/list)
or:
xargs git reset -- < /tmp/list
to run git reset --
on each path name. This assumes there is no white-space in the file names; if there is, use additional shell trickery to break only at newlines (assuming no newlines in the path names).
If you had carefully staged some but not all of some files using git add -p
, it is usually possible to recover these using git fsck --lost-found
and poking through all the resulting "dangling blobs", but that's rarely worth the effort.
git reset