How to Undo Last Git Commit

Git provides several ways to undo your last commit, each designed for different situations. Whether you need to fix a typo in your commit message, add a forgotten file, completely discard recent changes, or safely reverse a commit that has already been shared with others, Git has a command for your scenario. By the end of this guide, you will understand when to use git reset, git revert, and git commit --amend, and you will be able to confidently undo commits without losing important work.

This guide assumes Git is already installed on your system. If you need to install Git first, see our installation guides for Ubuntu, Debian, Fedora, or Linux Mint.

Choose the Right Method for Your Situation

Before running any commands, determine which method fits your situation. Using the wrong approach can make recovery harder or disrupt teammates working on the same branch.

ScenarioBest MethodEffect on History
Fix commit message or add forgotten files (not pushed)git commit --amendReplaces last commit
Undo commit but keep changes staged for editinggit reset --soft HEAD~1Removes commit, keeps index
Undo commit and unstage changes for reviewgit reset HEAD~1 (default)Removes commit, unstages files
Completely discard commit and all changesgit reset --hard HEAD~1Removes commit and changes permanently
Undo a commit already pushed to a shared branchgit revert HEADCreates new reverting commit

The key distinction is whether you have already pushed the commit. If others have pulled your changes, rewriting history with git reset causes problems for everyone. In that case, use git revert to create a new commit that undoes the changes while preserving history.

Amend the Last Commit

The git commit --amend command modifies your most recent commit. Use it to fix a typo in the commit message, add files you forgot to stage, or adjust the commit contents before pushing. This is the simplest fix when you catch a mistake immediately after committing.

Change the Commit Message

To change only the commit message without modifying any files:

git commit --amend -m "Corrected commit message"

Git replaces the previous commit with a new one containing your updated message:

[main e9b07e5] Corrected commit message
 Date: Sat Jan 3 18:12:39 2026 +0800
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 file2.txt

Add Forgotten Files to the Last Commit

If you forgot to include a file in your last commit, stage it first, then amend:

git add forgotten-file.txt
git commit --amend --no-edit

The --no-edit flag keeps the original commit message. Git creates a new commit that includes both the original changes and the newly staged file.

Amending rewrites history by replacing the commit with a new one (different hash). Only amend commits you have not pushed yet. If you already pushed, use git revert instead, or coordinate with your team before force pushing.

Undo a Commit with git reset

The git reset command moves your branch pointer backward, effectively removing commits from history. It offers three modes that control what happens to your working directory and staging area (index).

Soft Reset: Keep Changes Staged

A soft reset removes the commit but keeps all changes staged in the index, ready to commit again. Use this when you want to combine multiple commits into one or restructure your commits before pushing.

git reset --soft HEAD~1

The HEAD~1 notation means “one commit before HEAD” (your current position). After running this command, check the status:

git status

Git shows your changes staged and ready to commit:

On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   file1.txt
        new file:   file2.txt

Your files remain exactly as they were before the reset. You can now edit them further, add more files, or create a new commit with a different message.

Mixed Reset: Unstage Changes for Review (Default)

A mixed reset removes the commit and unstages the changes, leaving them in your working directory. This is Git’s default behavior when you omit the mode flag. Use this when you want to review and selectively re-add files.

git reset HEAD~1

This command is equivalent to git reset --mixed HEAD~1. Git confirms the operation:

Unstaged changes after reset:
M       file1.txt

Check the status to confirm your changes are now unstaged:

git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   file1.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        file2.txt

no changes added to commit (use "git add" and/or "git commit -a")

Modified files appear as “not staged” and new files appear as “untracked.” This gives you full control to decide which changes to include in your next commit.

Hard Reset: Discard Everything

A hard reset permanently destroys uncommitted changes to tracked files. There is no undo for working directory changes lost this way. If you have any doubt, use --soft or --mixed instead, or create a backup branch first with git branch backup-branch.

A hard reset removes the commit and discards all changes to tracked files in your working directory. Your repository returns to exactly the state it was in at the target commit.

git reset --hard HEAD~1

Git confirms the operation by showing where HEAD now points:

HEAD is now at 993af32 Initial commit

After a hard reset, git status shows a clean working directory with no pending changes (unless you have untracked files, which hard reset does not remove).

Reset to a Specific Commit

To undo multiple commits, specify the target commit hash instead of HEAD~1. First, find the commit you want to return to:

git log --oneline
e9b07e5 (HEAD -> main) Add dashboard feature
6446df2 Update configuration
923676c Initial commit

Then reset to that commit using its hash:

git reset --soft 923676c

This removes all commits after 923676c while keeping their changes staged. You can use any reset mode (--soft, --mixed, or --hard) with a commit hash.

Create a Reverting Commit with git revert

The git revert command creates a new commit that undoes the changes from a previous commit. Unlike reset, revert does not rewrite history, making it safe to use on commits that have already been pushed to shared branches.

git revert HEAD

By default, Git opens your configured text editor so you can edit the revert commit message. The default message explains which commit Git will revert:

Revert "Add new feature"

This reverts commit 6446df2.

Save and close the editor to complete the revert. Git creates a new commit:

[main 5a25268] Revert "Add new feature"
 1 file changed, 1 deletion(-)
 delete mode 100644 file2.txt

Your commit history now shows both the original commit and the revert commit, providing a clear audit trail of what changed and why.

Revert Without Opening an Editor

To accept the default revert message without opening an editor, use the --no-edit flag:

git revert HEAD --no-edit

This is useful in scripts or when the default message is sufficient.

Revert a Specific Commit

To revert a commit other than the most recent one, specify its hash:

git revert 6446df2 --no-edit

Git creates a new commit that undoes only the changes from commit 6446df2, leaving all subsequent commits intact.

Revert Multiple Commits

To revert a range of commits, specify the range using the .. notation. Git reverts them one at a time, creating separate revert commits for each:

git revert HEAD~2..HEAD --no-edit

This reverts the last two commits (the commit before HEAD~2 is excluded from the range). Git processes them in reverse chronological order, so the newest commit is reverted first.

Undo a Commit That Was Already Pushed

When you have already pushed a commit to a shared branch, you have two options: revert (recommended) or force push (use carefully).

Option 1: Revert and Push (Safe)

Create a revert commit and push it normally:

git revert HEAD --no-edit
git push origin main

This preserves history and causes no problems for teammates who have already pulled the original commit. The revert commit documents both what was undone and when.

Option 2: Reset and Force Push (Destructive)

Force pushing rewrites remote history. Anyone who has already pulled the removed commit will encounter conflicts on their next pull. Coordinate with your team before force pushing to shared branches. Never force push to protected branches like main or master without explicit team agreement.

If you must remove the commit from history entirely (for example, if you accidentally committed sensitive data), reset locally and force push:

git reset --hard HEAD~1
git push --force origin main

After you force push, notify your teammates to run:

git fetch origin
git reset --hard origin/main

This synchronizes their local branch with the rewritten remote history. Any local commits they had on top of the removed commit will need to be reapplied.

Troubleshooting

Recover a Commit After Hard Reset

If you accidentally ran git reset --hard and lost a commit, Git’s reflog can help you recover it. The reflog records where HEAD pointed over time.

View recent HEAD movements:

git reflog
993af32 HEAD@{0}: reset: moving to HEAD~1
12d96ca HEAD@{1}: commit: Important feature
993af32 HEAD@{2}: commit (initial): Initial commit

The lost commit (12d96ca) appears at HEAD@{1}. Recover it by resetting to that reflog entry:

git reset --hard HEAD@{1}
HEAD is now at 12d96ca Important feature

Verify the recovery with git log --oneline. The commit and its changes are restored.

Reflog entries expire after 90 days by default. Act quickly if you need to recover a lost commit. Uncommitted changes that were never staged cannot be recovered through reflog.

Revert Fails Due to Conflicts

When reverting a commit that modified files that have since been changed again, Git may report conflicts:

error: could not revert 6446df2... Add new feature
hint: After resolving the conflicts, mark them with
hint: "git add <paths>" or "git rm <paths>"
hint: and commit the result with 'git commit'

Resolve the conflicts manually by editing the affected files, then complete the revert:

git add resolved-file.txt
git revert --continue

If you want to abort the revert and return to your previous state:

git revert --abort

Cannot Reset: You Have Uncommitted Changes

If git reset refuses to run because you have uncommitted changes, you can either commit them first, stash them temporarily, or discard them:

# Option 1: Stash changes, reset, then restore
git stash
git reset --soft HEAD~1
git stash pop

# Option 2: Discard all uncommitted changes and reset
git reset --hard HEAD~1

HEAD~1 Does Not Work on the First Commit

If you try to reset the very first commit in a repository, HEAD~1 has no parent to point to:

fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree.

To undo the initial commit, use:

git update-ref -d HEAD

This removes the branch reference entirely. Your files remain staged in the index and present in your working directory, but the repository has no commits. You can then create a new initial commit.

Conclusion

Undoing commits in Git requires matching the right tool to your situation. Use git commit --amend for quick fixes to your most recent unpushed commit. For local commits you want to remove, git reset with --soft, --mixed, or --hard controls what happens to your changes. When you need to undo commits that have already been shared with others, git revert creates a new commit that reverses the changes safely. If you accidentally lose a commit, the reflog provides a recovery path as long as you act within the default 90-day retention period.

For related Git workflows, see commands to clear Git cache when your .gitignore changes are not being respected, and how to rename a local and remote Git branch for branch management. For complete command documentation, consult the official git-commit, git-reset, and git-revert manual pages.

Categories Git

Leave a Comment