Recovery
Recover after an over-aggressive reset
When reset moves the branch, index, or working tree farther than expected, first identify which layer changed, then recover with reflog, ORIG_HEAD, or a rescue branch.
- Anyone actively handling a Git mistake
- Readers who want a conservative rescue habit before trouble happens
- Stop mutating the repo further
- Be ready to inspect `git reflog`, `git status`, and `git log --graph`
- Running more reset or rebase commands before preserving a checkpoint
- Changing shared history before assessing blast radius
Data & Performance
- no deletereset moves a pointer; the orphaned commits stay in the object database until gc prunes themSource: git-reset(1) official manual
Key Quotes
Because git reset only moves branch pointers and never deletes commits, the previous tip is still in the reflog and can be restored with git reset --hard <reflog-sha>.
Citations & Further Reading
- Git reset [Official]
- Git reflog [Official]
- Git Tools Reset Demystified [Book]
What you will learn
- Understand the core purpose of Recover after an over-aggressive reset
- Master the basic usage and common options of Recover after an over-aggressive reset
- When reset moves the branch, index, or working tree farther than expected, first identify which layer changed, then recover with reflog, ORIG_HEAD, or a rescue branch.
- Understand key concepts: First, identify what you actually lost
- Know when to use this feature and when to avoid it
Start with a problem
You just ran a Git command and the result wasn't what you expected — maybe you even lost some commits. This has happened before, and you want a reliable set of recovery techniques.
First, identify what you actually lost
git reset is scary because it may affect three different layers:
- where the branch and
HEADpoint - what is staged in the index
- what your working tree files look like
Before you “fix” anything, stop and decide which layer changed unexpectedly.
The safest first step
git status
git log --oneline --graph --decorate -n 20
git reflog
Each command answers a different question:
statuschecks working tree and index statelogshows where the branch points nowreflogshows where it pointed before
Many “lost commit” situations are really “the branch name moved away from the commit.”
Three common cases
1. You wanted to uncommit, but keep your local changes
This is usually closer to a --soft or --mixed scenario.
If you reset farther back than intended, find the earlier position in reflog and create a rescue branch first:
git reflog
git switch -c rescue/reset HEAD@{1}
That gives the old position a durable name before you decide what to do next.
2. The branch moved, but the commits still exist
This is the most common case. Find the old position and recreate a pointer:
git reflog
git branch rescue/reset <old-commit>
Then decide whether to keep working from that rescue branch or move the original branch back.
3. reset --hard also replaced your working tree
This is the dangerous one.
If the content never existed in a commit, stash, or another ref, Git may not be able to restore the file state.
But if those changes did exist in a commit, reflog can often still get you back to that point.
When ORIG_HEAD helps
Git updates ORIG_HEAD for some risky operations, and it can be a fast way back:
git show ORIG_HEAD
git switch -c rescue/orig-head ORIG_HEAD
Do not treat it as a full history log. It is closer to “the position before the last big move.”
A conservative recovery order
- Stop running more
resetcommands - Inspect
git reflog - Create a
rescue/*branch from the old position - Only then choose whether to reset back, cherry-pick, or continue from the rescue branch
A good rule
If you are not fully sure which old position is correct, do not move the original branch yet.
Create a rescue branch first. It is the cheapest safety move in this kind of incident.
Try it yourself
- Practice the recover-after-reset command in a test repository and observe state changes before and after
- Experiment with different options and compare the output differences
- Simulate a real scenario where you would need to use this, and walk through the full process
Further reading
Keep going on the same topic: