Four cases, four commands. Find your sentence below and copy the command under it. Rule zero: pushed already? Use revert. Everything else assumes the commit is still local.
🎙️ Published & recorded: ·
If the commit is local, decide what should happen to its files. Soft reset removes only the commit and leaves every change staged, so it is the right default when you plan to recommit. Hard reset removes the commit and makes your working files match the previous snapshot. Do not use hard reset merely because the word “undo” sounds decisive.
# "Undo the commit, KEEP my changes" — most common:
git reset --soft HEAD~1
# "Undo the commit AND throw away the changes":
git reset --hard HEAD~1
# Last N commits, with all changes staged as one pile:
git reset --soft HEAD~3
fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree.Run git log --oneline. If it shows only one commit, there is no earlier snapshot for reset to target. Keep the files, create a new orphan branch if you truly need fresh history, or amend that first commit instead. Adding random tildes cannot produce a parent that does not exist.
Amend replaces the latest commit with a corrected one. Use it for a typo in the message or a file you forgot to stage. The commit hash changes, so amend is clean while the commit is still yours and still local. If teammates may already have the old hash, make a new commit instead.
# The content is right; only the message is wrong:
git commit --amend -m "the message I meant to write"
# Add a forgotten file without changing the message:
git add forgotten.py
git commit --amend --no-edit
fatal: You have nothing to amend.Check git log --oneline. You are either in a repository with no commits, or on an unborn branch. Stage the files and create the first normal commit; amend only works when HEAD already points to a commit.
Revert reads an existing commit and creates a new commit with the opposite change. That keeps the public history intact, which means a teammate who already pulled does not have to repair their branch. On a shared branch, I would rather explain an ugly revert commit than explain why somebody’s work vanished after a force-push.
git revert HEAD
# creates a new commit that cancels the latest one; then push it
git revert abc1234
# same operation for an older commit by hash
error: could not revert abc1234... Remove broken validationhint: after resolving the conflicts, mark the corrected paths with 'git add <paths>'Run git status, open each unmerged file, keep the version that represents the desired post-revert code, delete the conflict markers, then run git add for each file and git revert --continue. To abandon the attempt and restore the pre-revert state, run git revert --abort.
A hard reset moves the branch label, but Git usually keeps the old commit object. Reflog records where HEAD used to point. Read the entries, identify the commit before the reset, inspect it if necessary, and only then move back. Do not assume HEAD at one is always the right entry; another command may have added a newer reflog record.
git reflog
# a1b2c3d HEAD@{0}: reset: moving to HEAD~1
# f4e5d6c HEAD@{1}: commit: the one you want back
git show f4e5d6c # inspect before moving anything
git reset --hard f4e5d6c # restore that exact commit
# equivalent here: git reset --hard HEAD@{1}
reset --soft HEAD~1 · discard: reset --hard HEAD~1 · fix latest commit: --amend · already pushed: revert HEAD · recover: reflog.