First, read the link suggested by @Ant P above.
Whats the difference between git reset --mixed, --soft, and --hard?
Let me supplement that with a bit of model of what's going on.
'git reset' works with three different things.
- The HEAD reference. This indicates the point of reference. This has several uses, but perhaps the most relevant to you here is that this will be the parent of your next commit (assuming you don't change it again).
- Your working tree.
- The index. (The "Staging" pane in SourceTree). This is what git uses to construct the next commit. It's not actually creating commits from your working tree directly. That's why you need to do 'git add'.
So if you create a git repo with two files, foo.txt and bar.txt.
In your first revision put 'v1' in each file.
In your second revision put 'v2' in each file.
Now, put 'v3' in each, and do 'git add foo.txt'.
At this point, you change your mind, and decide to reset to the first revision. What state do you want to end up in?
- 'git reset --hard HEAD^': resets everything. Your tree is back to the first revision, with no changes queued to the index.
- 'git reset --soft HEAD^': Just resets the HEAD pointer. The index still has the state before the reset. This means that all the changes in the second commit, PLUS anything you've already added. So it has the 'v3' you put in foo.txt, and the 'v2' you committed in your first try at the second commit.
- 'git reset --mixed HEAD^': This just resets the index, filling it in with the current revision. In effect, it's undoing any 'git add' you may have done (or 'git rm').
So why would you want to do git reset --soft?
Let's say you create a commit, and decide you didn't get it right, and want to fix it before you push. (IMPORTANT! Once you push, you want to consider commits as permanent, or you'll make things hard for everyone else)
You could make your changes, and do 'git commit --amend'. But that only works for the last commit. Or you could do 'git rebase --interactive', and make your change to a specific commit, merge commits, etc.
Or you could do 'git reset --soft', add, change, rm, or reset any files, until you get the state you want for your new commit, and then commit it as your new commit.
'git reset --mixed' (or without the --mixed; it's the default) is just useful for undoing 'git add' or 'git rm'.
Bottom line is, in my opinion you probably don't want to use --soft in interactive usage. There's nothing wrong with using it, but 'git commit --amend' or 'git rebase --interactive' may be a more intuitive way to get what you want.
'git reset --mixed' you will use a lot.