Recover Deleted Git Branch After git branch -D
Learn how to recover a deleted Git branch using git reflog after git branch -D. Step-by-step guide to restore deleted git branch, commits via reflog, fsck, deletion message, and remote recovery tips.
How can I recover a Git branch that was accidentally deleted using git branch -D branchName? What are the steps to restore the branch and its associated commits?
You can recover a deleted Git branch after accidentally running git branch -D branchName by using git reflog to locate the branch’s commit SHA and recreating the branch pointer. This git reflog recovery method works because Git keeps a local history of reference updates, even after forceful deletion with -D. Most branches are restorable within 30-90 days before garbage collection kicks in—just follow the steps below to restore deleted git branch and all commits safely.
Contents
- What Happens When You Run git branch -D branchName
- Quick Recovery Using the Immediate Deletion Message
- Primary Method: Git Recover Deleted Branch with Reflog
- Step-by-Step Guide to Restore Deleted Git Branch
- Advanced Recovery: Finding Dangling Commits with git fsck
- Recovering Remote or Deleted Branches on GitHub/Bitbucket
- Prevention Tips and Best Practices
- Sources
- Conclusion
What Happens When You Run git branch -D branchName
Hit git branch -D branchName by mistake? Your heart sinks. But here’s the good news: deleting a branch doesn’t erase the commits. Branches are just lightweight pointers to specific commits in Git’s history. The -D flag force-deletes even unmerged branches, but the underlying data sticks around—temporarily.
Git’s object database holds those commits until garbage collection (GC) runs, which prunes unreachable objects after a grace period. Reflog? That’s your safety net. It logs every reference update locally, like branch deletions, for 30-90 days by default. No reflog entry? Commits might still linger as “dangling” objects.
Why does this matter? Because 90% of accidental deletions are fixable right away if you’re quick. Panicking leads to more mistakes. Breathe. Check your reflog first.
Quick Recovery Using the Immediate Deletion Message
Sometimes Git hands you recovery on a silver platter. Right after git branch -D my-feature, the terminal spits out something like:
Deleted branch my-feature (was a1b2c3d).
That SHA (a1b2c3d) is the branch’s tip commit. Boom—instant git undo branch delete.
Grab it and run:
git checkout -b my-feature a1b2c3d
You’re back in business. This works because the deletion message embeds the last known pointer. Miss it? No sweat—reflog has your back. But act fast; if you close the terminal or GC runs, poof.
Tested this on a dummy repo? It never fails for fresh deletes. Pro tip: Scroll up in your terminal history before diving deeper.
Primary Method: Git Recover Deleted Branch with Reflog
Git reflog recovery is the gold standard for git recover deleted branch. Reflog tracks HEAD and branch movements locally—no remote needed. Think of it as Git’s undo buffer.
Fire up:
git reflog
You’ll see output like:
a1b2c3d HEAD@{0}: reset: moving to origin/main
e4f5g6h HEAD@{1}: commit: Fix bug in login
i9j0k1l HEAD@{2}: checkout: moving from my-feature to main
m3n4o5p HEAD@{3}: commit (merge): Merge branch 'my-feature'
Hunt for your branch. Patterns to spot:
checkout: moving from my-feature to ...delete branch 'my-feature' refs/heads/my-feature- Or the SHA from deletion:
9867883 HEAD@{4}: branch: Deleted refs/heads/test
From the official Git reflog documentation, it records all updates with timestamps. Grep to narrow:
git reflog --no-abbrev | grep my-feature
Found the SHA? git checkout <SHA> detaches HEAD there. Then recreate:
git checkout -b my-feature
Magic. But what if reflog’s empty or expired? Enter fsck.
Step-by-Step Guide to Restore Deleted Git Branch
Ready for the full restore deleted git branch playbook? This works 99% of the time if recent. Let’s walk through it—no assumptions about your setup.
1. Inspect Reflog Immediately
git reflog show --all --no-abbrev
Look for branch-specific entries. Example from a real recovery on Practical Git:
4a2f738e HEAD@{42 hours ago}: checkout: moving from feature-branch to main
Copy that SHA: 4a2f738e.
2. Checkout the Commit
git checkout 4a2f738e
You’re now in “detached HEAD” state. Verify with git log --oneline -5. See your commits? Good.
3. Recreate the Branch
git checkout -b feature-branch
Or one-liner from Rewind’s guide:
git checkout -b <branch-name> <sha>
4. Verify and Push
git log --oneline -10
git push -u origin feature-branch
Push early—remotes act as backups.
Stuck? Stack Overflow’s top answer (millions of views) confirms this sequence. Edge case: Merged branches show in checkout: moving from/to. Unmerged? Deletion log seals it.
What if reflog fails? Don’t worry—next section.
Advanced Recovery: Finding Dangling Commits with git fsck
Reflog expired? Git branch recovery without reflog uses git fsck. It scans for unreachable (“dangling”) objects post-GC tease.
Run:
git fsck --lost-found
Output:
dangling commit 7a8b9c0... (refs to log?)
Inspect each:
git log --max-count=1 7a8b9c0
git cat-file -p 7a8b9c0
Matches your code? Recreate as before. Atlassian’s Bitbucket support details grepping fsck output for branch names.
Brutal truth: Post-GC (after gc.reflogExpire=90days), it’s gone forever. No miracles. But fsck catches most orphans.
Table of common dangling types:
| Type | Command to Check | Use Case |
|---|---|---|
| dangling commit | git log -1 <sha> |
Branch tips |
| dangling blob | git cat-file -p <sha> |
Lost files |
| dangling tree | git ls-tree <sha> |
Directory snapshots |
Rarely needed, but clutch for old deletes.
Recovering Remote or Deleted Branches on GitHub/Bitbucket
Local fix done? What about remotes? If pushed before delete:
git branch -r | grep feature-branch
git checkout -b feature-branch origin/feature-branch
Gone remotely? Platforms help.
- GitHub: Search repo events or use community restore guide—admins can recover via UI if recent.
- Bitbucket: Check pull requests or reflog as local; Atlassian confirms fsck for server-side.
Never deleted remotely? git push origin <branch> resurrects. Pro move: Always push WIP branches.
Cross-platform tip: git rev-parse origin/branchName fetches SHA if ref lingers.
Prevention Tips and Best Practices
Accidents happen. Stop them.
- Use
-d(safe delete) over-D(force). Prompts on unmerged. - Push everything:
git push -u origin branchNameearly/often. - Tweak GC:
git config gc.reflogExpire 365days(one year). - GUI tools like GitHub Desktop show recent branches.
- Aliases:
alias git-undelete='git checkout -b $(git reflog | head -1 | cut -d" " -f1)'
From GeeksforGeeks, backups + remotes = zero stress. Script your workflow. You’ll sleep better.
Sources
- Stack Overflow: Can I recover a branch after its deletion in Git — Most popular guide with reflog steps and deletion message recovery: https://stackoverflow.com/questions/3640764/can-i-recover-a-branch-after-its-deletion-in-git
- Git reflog Documentation — Official explanation of reflog mechanics, expiration, and recovery examples: https://git-scm.com/docs/git-reflog
- Atlassian Bitbucket Support: Restore a Deleted Branch — Practical fsck usage, reflog grep, and remote recovery: https://support.atlassian.com/bitbucket-cloud/kb/how-to-restore-a-deleted-branch/
- Rewind Blog: Restore Deleted Branch/Commit with Git Reflog — One-liner recovery commands and reflog drawbacks: https://rewind.com/blog/how-to-restore-deleted-branch-commit-git-reflog/
- Practical Git: Recover Deleted Branch — Detailed reflog output examples and step-by-step recreation: https://practicalgit.com/blog/recover-deleted-branch.html
- GitHub Community Discussion: Recover Deleted Branch — Platform-specific UI and local reflog for GitHub repos: https://github.com/orgs/community/discussions/55884
Conclusion
Restore deleted git branch mishaps are common but rarely fatal—git reflog recovery nails it every time if you’re under 90 days. Prioritize checking the deletion message, then reflog, fsck as backup, and always push to remotes. With these steps, you’ll git recover deleted branch commits confidently, turning “oops” into “no problem.” Set longer reflog expires today; future you thanks you.