There are a number of answers here with a misconception about git reset --soft
. While there is a specific condition in which git reset --soft
will only change HEAD
(starting from a detached head state), typically (and for the intended use), it moves the branch reference you currently have checked out. Of course it can't do this if you don't have a branch checked out (hence the specific condition where git reset --soft
will only change HEAD
).
I've found this to be the best way to think about git reset
. You're not just moving HEAD
(everything does that), you're also moving the branch ref, e.g., master
. This is similar to what happens when you run git commit
(the current branch moves along with HEAD
), except instead of creating (and moving to) a new commit, you move to a prior commit.
This is the point of reset
, changing a branch to something other than a new commit, not changing HEAD
. You can see this in the documentation example:
Undo a commit, making it a topic branch
$ git branch topic/wip (1)
$ git reset --hard HEAD~3 (2)
$ git checkout topic/wip (3)
- You have made some commits, but realize they were premature to be in the "master" branch. You want to continue polishing them in a topic branch, so create "topic/wip" branch off of the current HEAD.
- Rewind the master branch to get rid of those three commits.
- Switch to "topic/wip" branch and keep working.
What's the point of this series of commands? You want to move a branch, here master
, so while you have master
checked out, you run git reset
.
The top voted answer here is generally good, but I thought I'd add this to correct the several answers with misconceptions.
Change your branch
git reset --soft <ref>
: resets the branch pointer for the currently checked out branch to the commit at the specified reference, <ref>
. Files in your working directory and index are not changed. Committing from this stage will take you right back to where you were before the git reset
command.
Change your index too
git reset --mixed <ref>
or equivalently
git reset <ref>
:
Does what --soft
does AND also resets the index to the match the commit at the specified reference. While git reset --soft HEAD
does nothing (because it says move the checked out branch to the checked out branch), git reset --mixed HEAD
, or equivalently git reset HEAD
, is a common and useful command because it resets the index to the state of your last commit.
Change your working directory too
git reset --hard <ref>
: does what --mixed
does AND also overwrites your working directory. This command is similar to git checkout <ref>
, except that (and this is the crucial point about reset
) all forms of git reset
move the branch ref HEAD
is pointing to.
A note about "such and such command moves the HEAD":
It is not useful to say a command moves the HEAD
. Any command that changes where you are in your commit history moves the HEAD
. That's what the HEAD
is, a pointer to wherever you are. HEAD
is you, and so will move whenever you do.
soft: stage everything
,mixed: unstage everything
,hard: ignore everything
up to the commit I'm resetting from. – user1164937David Zych
with clear explanation - davidzych.com/difference-between-git-reset-soft-mixed-and-hard – src3369