Chapter 41: Git Recovery
Git Recovery (how to get back almost anything you think you permanently lost or deleted)
This is the part that makes Git feel like it has superpowers. Most people only discover how good Git’s recovery tools are after they panic and think:
- “I just lost three days of work with git reset –hard”
- “I deleted the wrong branch”
- “I rebased and everything disappeared”
- “I force-pushed and broke the main branch”
The good news: Git is extremely hard to permanently destroy — as long as you act reasonably quickly and know where to look.
Today I will explain every realistic recovery scenario beginners (and even experienced people) face — step by step, with real commands, exact outputs you will see, and clear safety levels.
1. The Four Main Git Recovery Tools (memorize these names)
| Tool / Command | What it recovers / rescues | Time window (typical) | Local or remote? | Safety / Ease |
|---|---|---|---|---|
| reflog | Any commit you moved HEAD away from (reset, rebase, amend, checkout…) | ~90 days (default) | Local only | Very easy |
| git fsck + lost-found | Truly dangling / unreachable commits & blobs | Until garbage collection runs | Local only | Medium |
| GitHub / remote backup | Pushed commits (even after local disaster) | Forever (if pushed) | Remote | Very easy |
| git stash | Uncommitted changes you stashed | Until you drop the stash | Local only | Easy |
2. Most Common Recovery Scenarios + Exact Steps
Scenario 1 – “I did git reset –hard and lost everything!”
This is the #1 panic moment — and reflog saves you 95% of the time.
You had:
|
0 1 2 3 4 5 6 7 8 9 10 |
git log --oneline -4 # 89abcde Add login validation # fedcba9 Fix button color # 456def7 Add login form # 123abcd Initial commit |
Then you did:
|
0 1 2 3 4 5 6 |
git reset --hard HEAD~3 |
Now only “Initial commit” is visible → panic!
Recovery:
|
0 1 2 3 4 5 6 |
git reflog -10 |
Typical output:
|
0 1 2 3 4 5 6 7 8 9 10 |
123abcd HEAD@{0}: reset: moving to HEAD~3 456def7 HEAD@{1}: commit: Add login form fedcba9 HEAD@{2}: commit: Fix button color 89abcde HEAD@{3}: commit: Add login validation ... |
Find the hash you want (e.g. 89abcde = last good state)
Then:
|
0 1 2 3 4 5 6 7 8 |
git reset --hard 89abcde # or safer: create branch first git checkout -b recovered-work 89abcde |
→ Everything is back exactly as it was.
Rule: Do git reflog immediately after any scary command.
Scenario 2 – “I deleted a branch by mistake”
You did:
|
0 1 2 3 4 5 6 |
git branch -D feature/add-search |
Branch disappeared from git branch list.
Recovery:
|
0 1 2 3 4 5 6 |
git reflog |
Look for lines like:
|
0 1 2 3 4 5 6 |
fedcba9 HEAD@{5}: checkout: moving from feature/add-search to main |
The hash fedcba9 is the tip of the deleted branch.
Recover:
|
0 1 2 3 4 5 6 7 |
git checkout -b feature/add-search-recovered fedcba9 # or git branch feature/add-search fedcba9 |
→ Branch is back.
Scenario 3 – “I rebased / amended and lost original commits”
Rebase or amend changes commit hashes — old ones seem gone.
Again — reflog:
|
0 1 2 3 4 5 6 |
git reflog |
Find the old HEAD before rebase/amend:
|
0 1 2 3 4 5 6 7 |
abc1234 HEAD@{7}: rebase (finish): returning to refs/heads/feature/add-search def5678 HEAD@{8}: rebase (start): checkout origin/main |
Recover old state:
|
0 1 2 3 4 5 6 |
git checkout -b before-rebase def5678 |
Scenario 4 – “I force-pushed and teammate lost work” (remote recovery)
You did git push –force on main — teammate pulled before → now their local is broken.
Their recovery:
They run:
|
0 1 2 3 4 5 6 7 |
git fetch origin git reflog origin/main |
Find the hash before your force-push:
|
0 1 2 3 4 5 6 |
git reset --hard origin/main@{1} |
→ Their local matches the old (good) state again.
Prevention: Always use –force-with-lease instead of –force.
Scenario 5 – “I never pushed — and deleted .git folder / lost laptop”
→ Very bad news → reflog & objects are inside .git → they are gone locally
Only hope:
- If you pushed before disaster → clone from GitHub/remote again
- GitHub keeps full history of every pushed commit forever
- Use git clone or even GitHub’s “download ZIP” as last resort (loses history)
4. Quick Git Recovery Cheat Sheet (save this forever)
| Disaster | First command to run | Then usually… | Time window |
|---|---|---|---|
| git reset –hard / rebase gone wrong | git reflog | git reset –hard HEAD@{n} or hash | ~90 days |
| Deleted branch | git reflog | git branch recovered-branch <hash> | ~90 days |
| Bad amend / squash | git reflog | git checkout -b recovered <old-hash> | ~90 days |
| Force-push broke teammate | Teammate runs git reflog origin/main | git reset –hard origin/main@{1} | Until GC |
| Lost .git folder (but pushed before) | git clone from GitHub again | — | Forever |
| Never pushed anything | Almost impossible to recover | Pray you have backup / Time Machine | — |
Got the recovery feeling now?
Git reflog = your personal time machine — Git secretly records every move so you can almost always go back
The only things that are truly hard/impossible to recover:
- Uncommitted changes never added/stashed
- Local-only work never pushed + .git folder deleted
- Very old reflog entries after 90+ days + aggressive garbage collection
Next?
- Want to do a full “reset –hard → reflog recover” live practice?
- See how reflog works during interactive rebase?
- Or wrap up with a big summary of all undo/recovery commands?
Just tell me — we’ll finish strong. You’ve come incredibly far — you now know Git better than most developers with 2–3 years experience. Really proud of you! 🚀
