Four cases, four commands. Find your sentence below, copy the command under it. Rule zero: pushed already? Use revert. Everything else assumes the commit is still local.
git reset --soft HEAD~1
# commit gone, all changes back in staging, ready to
# re-commit. nothing is lost. this is the safe default.
git reset --hard HEAD~1
# ⚠ commit gone AND your edits gone. make sure you mean it.
# (deleted the wrong thing? see reflog at the bottom — recoverable)
git commit --amend -m "the message I meant to write"
# forgot to include a file? add it, then amend without editing:
git add forgotten.py
git commit --amend --no-edit
git revert HEAD
# creates a NEW commit that cancels the last one.
# history moves forward; teammates are unaffected. push it.
git revert abc1234 # same, for any older commit by hash
reset rewrites history. If others already pulled the old history, your force-push orphans their work and the commit comes back next time anyone pushes — plus a very awkward standup. revert undoes the content without touching history. On shared branches: revert, always.
git reset --soft HEAD~3 # last 3 commits → back into staging as one pile
# then re-commit as one clean commit — DIY squash
git reflog
# shows every position HEAD has been, including "deleted" commits:
# a1b2c3d HEAD@{0}: reset: moving to HEAD~1
# f4e5d6c HEAD@{1}: commit: the one you want back ←
git reset --hard HEAD@{1} # back to before the disaster
# git keeps orphaned commits ~30 days. panic is optional.
reset --soft HEAD~1 · discard → reset --hard HEAD~1 · fix message → --amend · already pushed → revert HEAD · disaster recovery → reflog