So these were the two first reset modes, --soft and --mixed, which leaves 3 to be explored: --keep, --merge and --hard.
Our first table lumped these together as they have similar range, considering they all impact HEAD, the index and the working copy. That’s usually when self-proclaimed Git experts chime up and go “Wait, there’s something else besides reset --hard?!” Yes, my friends, there is, and once we’re through this I trust you’ll never want to use --hard again… Yes, I did say not use --hard again!
OK right now this new table is quite useless, so let’s see where the differences are and why you’d favor --keep or --merge over --hard? These two modes will let us preserve modifications that weren’t committed yet. So their goal is to avoid losing our work, considering that if we erase changes that weren’t committed yet, they’re lost for good (unless the files are still open in your editor and you can leverage its undo capability).
OK so what’s the difference between --keep and --merge? Both will attempt to preserve ongoing changes in the working copy. Again, let me stress we’re trying to retain ongoing, uncommitted work. The --keep mode will unstage but retain working copy changes. The --merge mode can partially lose work as it will only retain changes that were not staged yet.
Where does that come from? Well, the --merge mode was intended to let us reset right in the midst of a merge conflict situation, after, say, a merge or pull. Git would then say we have a “dirty state” or “dirty working directory” to signal files in the working copy that need manual resolution. But it’s actually unlikely you want to manually git reset --merge in such a scenario, as you’ll likely favor the more explicit, and slightly different git merge --abort or, if you’re rebasing, git rebase --abort.
What’s more, should you try and do a git reset --keep in such a situation, Git will refuse to perform it and display a message stating it can’t do a “reset keep” in the middle of a merge-like situation.
Which leaves our last mode, the ominous --hard. Abandon hope all ye who enter here, as any change will perish with --hard! 😈
I guess the cavernous voice and creepy soundtrack were a bit overkill to nail the point home: --hard undoes work across all zones. Couldn’t resist, tho.
So in summary: forget --hard unless you’re absolutely sure you want to nuke your work and prefer --keep when undoing commits, it’s an additional safety net to avoid losing work forever.
Typical work-losing scenarios ⚠️
We’ve now covered the 3 typical scenarios when we may accidentally lose work beyond recovery: git checkout on files, git reset --hard and git reset --merge with staged changes. For everything else, there is (Eurocard Mastercard?) commits, and any known commit can be retrieved as long as it wasn’t pruned by the garbage collector. We’ll soon see how to dig out lost commits, but for now let’s get back to our three modes and compare their behaviors using diagrams.