Git Reset: Undo Your Last Commit Without Losing a Single Line
Committed too early? Wrong branch? Wrong message? git reset --soft HEAD~1 is the command every developer should have in muscle memory.
Technologies Discussed
The Scenario
You commit. Then immediately realize you forgot to add a file, used the wrong branch, or the commit message is embarrassing. Your work is good — you just committed too soon.
The Command
bash
git reset --soft HEAD~1
This undoes your last commit but leaves every changed file **staged and ready**. Nothing is lost.
Breaking It Down
- **`git reset`** — moves the branch pointer back
- **`--soft`** — keeps your changes in the staging area
- **`HEAD~1`** — one commit before the current HEAD
The Three Reset Modes
bash
git reset --soft HEAD~1 # undo commit, keep changes staged ✅ safest
git reset --mixed HEAD~1 # undo commit, unstage changes (default)
git reset --hard HEAD~1 # undo commit, DELETE changes ☠️ destructive
In most "oops" situations, **`--soft`** is exactly what you want.
Step-by-Step Recovery
bash
# Check what happened
git log --oneline -3# Undo the commit, keep changes staged git reset --soft HEAD~1
# Verify your files are still staged git status
# Fix whatever you need to fix # Then recommit with a better message git commit -m "feat: add user authentication with proper error handling"
If You Already Pushed
Rewriting shared history is risky, but if you pushed to *your own* feature branch:
bash
git reset --soft HEAD~1
# fix and recommit
git push --force-with-lease
Always use **`--force-with-lease`** over `--force`. It refuses to push if someone else has added commits to the remote branch — protecting you from overwriting a teammate's work.
Undo Multiple Commits
bash
git reset --soft HEAD~3 # undo last 3 commits, keep all changes staged
Emergency Lifeline: git reflog
If something goes wrong, `git reflog` shows every action Git has recorded — including commits you thought were lost.
bash
git reflog
# Find the commit hash you need
git checkout <hash>
Takeaway
**`git reset --soft HEAD~1`** — commit it to memory (pun intended). It's the safest undo in Git's toolkit and the one you'll reach for most often.