Undoing: reset vs revert

Two Ways to Undo

Scenario: You committed something broken. Do you erase it, or neutralize it? The answer depends on whether you've pushed it yet - and getting this wrong is how people lose work or wreck a shared branch.
CommandEffectUse when
git revert <commit>Creates a new commit that undoes an old oneThe commit is already pushed/shared
git reset --soft <commit>Moves branch back, keeps changes stagedLocal, want to redo the commit
git reset --mixed <commit>Moves back, keeps changes unstaged (default)Local, want to re-stage
git reset --hard <commit>Moves back, discards all changesLocal, truly want it gone
$ git reset --soft HEAD~1    # undo last commit, keep the changes staged
$ git revert HEAD            # safely undo a pushed commit
Danger: git reset --hard permanently discards uncommitted work and rewrites history. Never reset --hard a branch you've already pushed and others use - it breaks their history. On shared branches, always revert.
Tip: HEAD = the current commit. HEAD~1 = one before it, HEAD~2 = two before, and so on.