DEV Community

Cover image for How to Undo the Last Git Commit: Reset, Revert or Amend
head_of_david
head_of_david

Posted on Originally published at devkult.com

How to Undo the Last Git Commit: Reset, Revert or Amend

Which command you need depends on two questions: have you pushed the commit, and do you want to keep the changes?

Situation Command
Not pushed — undo the commit, keep the changes staged git reset --soft HEAD~1
Not pushed — undo the commit, keep the changes unstaged git reset HEAD~1
Not pushed — throw the commit and its changes away git reset --hard HEAD~1
Fix the last commit's message or add a forgotten file git commit --amend
Already pushed to a shared branch git revert HEAD

HEAD~1 means "the commit before the current one". Use HEAD~3 to go back three commits.

Undo a commit but keep the work

git reset --soft HEAD~1
Enter fullscreen mode Exit fullscreen mode

The commit disappears and its changes are left staged, ready to commit again — useful when you committed too early or want to split the work differently.

git reset HEAD~1
Enter fullscreen mode Exit fullscreen mode

The default (--mixed) does the same but leaves the changes unstaged in your working directory, so you can choose again what goes into each commit.

Throw the commit away completely

git reset --hard HEAD~1
Enter fullscreen mode Exit fullscreen mode

This deletes the commit and discards its changes from your files. Uncommitted work in your working directory is discarded too, so check git status first. (The commit itself is still recoverable for a while — see reflog below.)

Fix the last commit instead

To change the message:

git commit --amend -m "Better message"
Enter fullscreen mode Exit fullscreen mode

To add a file you forgot:

git add forgotten-file.js
git commit --amend --no-edit
Enter fullscreen mode Exit fullscreen mode

Amending replaces the commit with a new one. That's fine locally, but if you've already pushed it, the next push needs force (see below).

Undo a commit that's already pushed

On a branch other people use, don't rewrite history. Create a new commit that reverses the old one:

git revert HEAD
git push
Enter fullscreen mode Exit fullscreen mode

git revert works on any commit, not just the last: git revert a1b2c3d. To revert a merge commit, tell Git which parent to keep — usually the first, the branch you merged into:

git revert -m 1 <merge-commit>
Enter fullscreen mode Exit fullscreen mode

Pushed, but only to your own branch

If nobody else has pulled the branch — say, your own feature branch — you can rewrite it and force-push:

git reset --hard HEAD~1
git push --force-with-lease
Enter fullscreen mode Exit fullscreen mode

--force-with-lease refuses to push if the remote has commits you haven't seen, so you can't silently wipe out someone else's work. Prefer it to plain --force.

Recover from a reset you regret

Git keeps a log of every position HEAD has been at, including commits you reset away:

git reflog
Enter fullscreen mode Exit fullscreen mode
e4f5a6b HEAD@{0}: reset: moving to HEAD~1
9c8d7e1 HEAD@{1}: commit: Add search endpoint
Enter fullscreen mode Exit fullscreen mode

Jump back to the commit before the reset:

git reset --hard HEAD@{1}
Enter fullscreen mode Exit fullscreen mode

The same trick undoes an amend: git reset --soft HEAD@{1} puts back the original commit and leaves the amended changes staged. Reflog entries are kept for 90 days by default, and only in your local repository.

A few related undos

git restore --staged file.js    # unstage a file, keep the edits
git restore file.js             # discard uncommitted edits to a file
git update-ref -d HEAD          # undo the very first commit in a repo
Enter fullscreen mode Exit fullscreen mode

The last one is needed because the first commit has no parent, so HEAD~1 doesn't exist.


Originally published at devkult.com.

Top comments (0)