Undo Commits (amend, reset, revert)

First, breathe — Git rarely loses anything

Once something is committed it's very hard to truly lose, even if you "delete" it — Git keeps a log of where you've been (Recover Lost Work shows how to read it). This chapter covers undoing commits: fixing the last one, un-committing, and reversing one that's already pushed. For edits you haven't committed yet, the gentler tools live in Discard & Unstage Changes.

The one rule that keeps you safe: amend and reset rewrite local history — perfect before you push. Once a commit is pushed and shared, undo it with revert instead (it adds a new commit rather than rewriting the old one).

Fix the last commit: --amend

Typo in the message? Forgot to include a file? git commit --amend replaces the most recent commit with a new one. To fix just the message, run it alone. To add a forgotten file, stage it first, then amend.

Repair the most recent commit

Terminal
$ git commit --amend -m "Better message"   # fix the message
$ 
$ # or: include a file you forgot
$ git add forgotten-file.css
$ git commit --amend --no-edit             # keep the same message
In VS Code
  1. Source Control → '…' menu → CommitCommit Staged (Amend)
  2. Or enable the setting 'Git: Show Commit Input Validation' and use the amend option

Only amend commits you haven't pushed yet — amending rewrites the commit, which confuses anyone who already pulled it.

Undo the last commit, but keep the work: reset

Committed too soon? git reset HEAD~1 removes the last commit and drops its changes back into your working tree so you can redo them. HEAD~1 means "one commit before now".

Un-commit, keep the changes

Terminal
$ git reset HEAD~1          # changes return, unstaged (default = --mixed)
$ git reset --soft HEAD~1   # changes return, still staged
In VS Code
  1. Source Control → '…' menu → CommitUndo Last Commit
  2. Your files stay exactly as they were — only the commit is removed

The three reset modes, in plain English (all move the branch back, they differ in what they keep):

--soft → keeps your changes staged · --mixed (default) → keeps changes unstaged · --harddeletes the changes too. Reach for --soft or --mixed day to day; treat --hard with care.

Throw commits away entirely (careful)

git reset --hard moves the branch back and discards the changes. It's the fastest way to wipe local experiments — and the easiest way to lose work, so double-check first.

Discard the last commit AND its changes

Terminal
$ git reset --hard HEAD~1
$ # everything from that commit is gone from the working tree
In VS Code
  1. There's no one-click button for this on purpose — it's destructive
  2. If you must, run it in the integrated terminal

Pushed that commit already? Don't reset --hard it — use git revert below instead.

Safely undo a commit you've already pushed: revert

For shared history, you don't erase — you add a new commit that reverses an old one. git revert does exactly that, keeping everyone's history consistent.

Reverse a commit with a new commit

Terminal
$ git revert a1b2c3d        # creates a commit that undoes a1b2c3d
$ git push
In VS Code
  1. Command Palette → Git: Revert Commit…
  2. Pick the commit to reverse; VS Code makes the undo commit for you

Use this for anything already on GitHub. It's the team-safe undo.

Quick map: fix last commit → --amend · un-commit keep work → reset · undo a pushed commit → revert · discard uncommitted edits → Discard & Unstage · work seems gone → Recover Lost Work.

Up next: the classic panic — you committed, then noticed the status bar says the wrong branch. Nothing is lost.

FAQ

Frequently Asked Questions

How do I undo the last commit but keep my changes?
Run git reset HEAD~1. It removes the commit and returns its changes to your working tree (unstaged). Use git reset --soft HEAD~1 to keep them staged.
How do I change the last commit message?
git commit --amend -m "Better message" replaces the most recent commit's message. In VS Code: Source Control '…' menu → Commit → Commit Staged (Amend). Only amend commits you haven't pushed.
What is the difference between git reset and git revert?
reset rewrites local history — use it before pushing. revert adds a new commit that undoes an old one, which is safe for commits you've already shared.
I ran git reset --hard and lost work — can I get it back?
Usually yes — git reflog can find the "lost" commit's hash. Recover Lost Work walks through the whole rescue.