In git you have:
- HEAD pointer that tells you what commit you're working on
- working tree that represents the state of the files on your system
- staging area (or the index) that "stages" changes so that they can later be committed together
Let us see what --hard, --soft, and --merge do:
- The parameter --soft will move the HEAD but it will not touch the staging area or the working tree.
- The parameter --mixed will move the HEAD and will update the staging area, but it will not touch the working tree.
- The parameter --merge moves HEAD, resets the staging area, and tries to move all the changes in your working tree into the new working tree.
- The parameter --hard moves HEAD and adjusts your staging area and working tree to the new HEAD, throwing away everything.
You should use --soft only when you want to move to another commit and patch things up without "losing your place".
$ touch foo
$ git add foo
$ git commit -m "Bad-commit-message"
$ git reset --soft HEAD^
$ git commit -m "Good-commit-message"
You should use --mixed when you want to see what things look like at another commit, but you don't want to lose any changes you already have.
You should use --merge when you want to move to a new spot but incorporate the changes you already have into that the working tree.
You should use --hard to wipe everything out and start a fresh slate at the new commit.