How to Undo the Last Commit in Git (Without Losing Changes)
Made a mistake in your last commit? Don’t panic. Git gives you several ways to undo it depending on whether you want to keep your changes or discard them entirely. Understanding the difference between reset and revert is crucial — the wrong choice can cause problems, especially on shared branches.
Quick Answer
To undo the last commit but keep your changes:
git reset --soft HEAD~1This moves Git’s HEAD back one commit while leaving your files and staged changes intact. You can then fix whatever was wrong and recommit.
When to Use Each Method
| Situation | Command | Effect |
|---|---|---|
| Wrong commit message | git commit --amend | Edit message only |
| Forgot to include a file | git add . && git commit --amend --no-edit | Add changes to last commit |
| Undo commit, keep changes | git reset --soft HEAD~1 | Uncommit, keep working |
| Undo commit, unstage changes | git reset --mixed HEAD~1 | Uncommit + unstage |
| Undo commit, discard all | git reset --hard HEAD~1 | Uncommit + delete changes |
| Already pushed, safe undo | git revert HEAD | Creates a new undo commit |
Detailed Examples
1. Fix the commit message
git commit --amend -m "New and improved commit message"Replaces the last commit’s message without changing its content. This is safe only if the commit hasn’t been pushed yet. If you’ve already pushed, force-pushing an amended commit is risky on shared branches.
2. Add a forgotten file
git add forgotten-file.txt
git commit --amend --no-editThe --no-edit flag keeps the existing commit message. This is the fastest way to fix an incomplete commit — you add the missing file and amend without touching the message.
3. Soft reset (undo but keep everything)
git reset --soft HEAD~1Your files remain unchanged. The changes from the undone commit are staged and ready to recommit. Use this when you committed too early or want to split one large commit into several smaller ones.
4. Mixed reset (undo + unstage)
git reset --mixed HEAD~1Your files remain unchanged. Changes are unstaged — you’ll need to git add them again before recommitting. This is the default mode of git reset (you don’t need the --mixed flag explicitly), and it’s useful when you want to review all your changes before staging them again.
5. Hard reset (completely undo)
git reset --hard HEAD~1⚠️ Dangerous. This permanently removes the commit AND discards all file changes. Only use if you’re sure you don’t need the changes. There’s no built-in undo for this command — though you can sometimes recover lost commits with git reflog.
6. Revert (safe for pushed commits)
If you’ve already pushed the commit, never use git reset. Use git revert instead:
git revert HEADThis creates a NEW commit that undoes the changes. Safe to push because it doesn’t rewrite history. Team members will see the revert commit in their log and know exactly what happened.
Undoing Multiple Commits
To undo the last 3 commits:
git reset --soft HEAD~3Or to revert a specific range:
git revert HEAD~2..HEADThis reverts commits from HEAD~2 to HEAD, creating a new commit for each one. You can also use git revert --no-commit HEAD~2..HEAD to revert them all in a single commit.
Pro Tip: Your Safety Net
If you’re unsure, use git revert instead of git reset. It’s always safe because it doesn’t delete history:
git revert HEAD --no-editFor times when you already did a hard reset and regret it, run git reflog to see a list of every HEAD position you’ve visited. You can restore lost commits with git checkout <commit-hash> or git reset --hard <commit-hash> — as long as you act before Git garbage-collects the unreferenced commits (typically 30-90 days).
Practical Workflow Examples
Scenario: You committed to the wrong branch
# Undo the commit but keep changes
git reset --soft HEAD~1
# Stash the changes
git stash
# Switch to the correct branch
git checkout correct-branch
# Apply the changes
git stash pop
git add .
git commit -m "Correct commit on the right branch"This is a common mistake when you’re working on multiple features. The soft reset undoes the commit without losing any work, and stash temporarily stores your changes while you switch branches.
Scenario: You need to remove a sensitive file
If you accidentally committed a file with passwords or API keys:
# Remove the file and amend
git rm --cached secrets.env
git commit --amend --no-edit
# Also remove from all history (if already pushed)
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch secrets.env' \
--prune-empty --tag-name-filter cat -- --allFor already-pushed secrets, use git filter-branch or the faster git filter-repo to purge the file from your entire Git history. Then notify your team to rotate the exposed credentials. Be aware that rewriting history for already-pushed commits requires force pushing and coordination with everyone who has cloned the repository.
Scenario: Undoing a pushed feature branch
When a full feature branch needs to be rolled back from main after merging, use revert on the merge commit rather than trying to reset the branch pointer:
# Find the merge commit
git log --oneline --merges -1
# abc1234 Merge pull request #456 from feature/new-checkout
# Revert it, keeping mainline
git revert -m 1 abc1234
git push origin mainThis cleanly undoes the entire feature while preserving the audit trail. If you need to re-apply the feature later after fixes, revert the revert commit.
Scenario: Undoing a merge commit
Undoing a merge is trickier because reset removes all commits from both branches:
# Revert a merge commit
git revert -m 1 <merge-commit-hash>The -m 1 flag tells Git to revert to the first parent (the branch you were on when you merged). This is the safest way to undo a merge that’s already been shared.
Scenario: Undoing a pushed commit without revert
If you cannot use revert (your team prefers linear history or you need to edit the commit rather than just undo it), the safest approach is to create a new branch, revert on the new branch, and merge:
# Create a fix branch from the current state
git checkout -b fix/bad-commit
git revert HEAD --no-edit
git push -u origin fix/bad-commit
# Open a PR and merge normallyThis avoids force pushing on shared branches while still achieving the undo. The original bad commit remains in history, but the revert commit neutralizes its effect.
Scenario: Interactive undo with git rebase
For more complex undo scenarios involving several commits in the middle of history, interactive rebase gives you surgical control:
git rebase -i HEAD~5
# In the editor, delete the line of the commit you want to remove
# Save and exit — that commit is gone from historyThis is useful when you need to remove a specific commit from the middle of your history without affecting the commits before or after it. Only use this on branches that haven’t been pushed.
More Git help: Learn how to stash changes, branching strategies, and advanced Git commands.
FAQ
Q: What is the difference between git reset --soft and git reset --mixed?
A: --soft keeps changes staged (ready to recommit). --mixed unstages changes but keeps them in your working directory. Use --soft to fix a commit quickly; use --mixed to review what changed before recommitting.
Q: Can I undo a commit that was pushed days ago?
A: Yes. Use git revert <commit-hash> to create a new commit that undoes the changes. This is safe on shared branches because it preserves history.
Q: What does HEAD~1 mean?
A: It means “one commit before HEAD.” HEAD~3 means three commits before HEAD. You can also use HEAD^ as shorthand for HEAD~1.
Q: Is git commit --amend the same as git reset --soft followed by git commit?
A: Almost. --amend replaces the last commit with a new one that includes the additional changes. reset --soft followed by git commit creates a separate commit with a new hash.
Q: How do I undo a commit that is not the most recent?
A: Use git revert <hash> (safe, creates a new commit) or git rebase -i and delete the commit line (dangerous, rewrites history).
Q: What is the best way to undo changes that are not yet committed?
A: For unstaged changes: git restore <file>. For staged changes: git restore --staged <file> then git restore <file> if you want to discard them entirely.
Related Concepts and Further Reading
Understanding git undo last commit requires familiarity with several interconnected ideas and principles that together form a complete picture. Exploring these related concepts deepens your knowledge and provides context that makes the core material more meaningful and applicable. Each concept builds on the others, creating a web of understanding that supports deeper learning and practical application. Taking time to explore how these elements connect reveals patterns that accelerate comprehension and retention of new information.
The relationship between git undo last commit and adjacent fields is worth particular attention. Many of the most important insights emerge at the boundaries between disciplines, where ideas from different areas combine to create new approaches and solutions that neither field could produce alone. Exploring these connections pays dividends in both breadth and depth of understanding, revealing patterns and principles that might otherwise remain hidden from view. Cross-disciplinary knowledge is increasingly valued as problems become more complex and interconnected.
For those looking to go beyond introductory material, several excellent resources provide deeper treatment of specific aspects of git undo last commit. Academic journals, industry publications, authoritative reference works, and online courses each offer different perspectives and levels of detail. The key is to match your reading to your current learning goals and build knowledge progressively, focusing on quality over quantity in your study materials. A well-chosen resource that matches your current level is worth more than dozens of resources that are too basic or too advanced.