First: Did You Already Push?

The right command depends on one question above all else: have you pushed the commit to a remote yet? If not, you have full freedom. If yes, your options narrow because you need to avoid rewriting history that others may already have pulled.

Use the decision tree below, then jump to your scenario.

Did you push the commit?
│
├── NO (local only)
│   ├── Keep your changes?  → git reset --soft HEAD~1
│   ├── Discard changes?    → git reset --hard HEAD~1
│   └── Fix commit message? → git commit --amend
│
└── YES (already pushed)
    ├── On a feature branch → git revert HEAD (safe)
    ├── On main/protected   → git revert HEAD (only option)
    └── Shared history      → NEVER use reset --hard

Scenario 1: Undo the Last Commit, Keep Your Changes

You committed too early. The code changes are correct, you just want to recommit differently — maybe to fix the message, split into smaller commits, or add a forgotten file.

git reset --soft HEAD~1

This moves the branch pointer back one commit but leaves your changes staged, ready to recommit. Your working directory is untouched.

To go back two commits:

git reset --soft HEAD~2

Scenario 2: Undo the Last Commit, Discard All Changes

You want to completely erase the commit and the changes it introduced — start fresh as if it never happened.

git reset --hard HEAD~1

Warning: This permanently discards your working directory changes. There is no undo for --hard unless you use git reflog (see Scenario 6 below).

Scenario 3: Undo the Last Commit, Keep Changes Unstaged

You want to undo the commit but keep the changes in your working directory without staging them — useful when you want to review what changed before deciding what to do next.

git reset HEAD~1
# or equivalently:
git reset --mixed HEAD~1

Scenario 4: Fix the Commit Message (Not Pushed)

The commit is fine but you made a typo in the message, or you want to update it to follow Conventional Commits format.

git commit --amend -m "fix(auth): correct typo in login error message"

If you want to open your editor instead of passing the message inline:

git commit --amend

You can also stage additional files before amending to include them in the same commit.

Scenario 5: Undo a Commit That Was Already Pushed

The commit is on the remote. git reset would rewrite history — if anyone else has pulled, you will create divergence and force-push problems. The safe solution is git revert, which creates a new commit that undoes the changes without erasing history.

# Revert the last commit
git revert HEAD

# Revert a specific commit by its hash
git revert a1b2c3d

# Revert without immediately committing (review first)
git revert HEAD --no-commit
git revert --continue

git revert is always safe on shared branches. It adds a revert commit to history but never removes commits.

Scenario 6: Recover a Commit After git reset --hard

You ran git reset --hard and realized you needed those changes. Git does not immediately delete commits — they still exist in the reflog for 30–90 days.

# See the reflog — find the commit hash you want to recover
git reflog

# Output looks like:
# a1b2c3d HEAD@{0}: reset: moving to HEAD~1
# f4e5d6c HEAD@{1}: commit: feat: add user dashboard  ← this is what you lost

# Recover it
git checkout f4e5d6c
# or restore the branch to that point
git reset --hard f4e5d6c

The reflog is your safety net. It records every change to HEAD, including resets and amends.

Scenario 7: Undo a Commit in the Middle of History

You want to undo a commit from 5 commits ago, not the most recent one.

# Find the commit hash
git log --oneline

# Revert it specifically (creates a new revert commit)
git revert a1b2c3d

# If the commit is not pushed and history is local-only:
# Use interactive rebase to drop it
git rebase -i HEAD~5
# In the editor, change 'pick' to 'drop' on the commit to remove

Quick Reference

Scenario Command Safe to push?
Undo commit, keep changes staged git reset --soft HEAD~1 Not pushed only
Undo commit, keep changes unstaged git reset HEAD~1 Not pushed only
Undo commit, discard all changes git reset --hard HEAD~1 Not pushed only
Fix commit message git commit --amend Not pushed only
Undo pushed commit safely git revert HEAD Yes — always safe
Recover lost commit git reflog then git reset --hard <hash> Not pushed only

The golden rule: never rewrite history on a shared branch. If the commit is on a branch that others use, always use git revert. For personal git workflows, git reset is fine and cleaner. Use our Diff Checker to review changes before committing, and our Conventional Commits Formatter to write structured messages that make your git history easier to navigate.