Fix: How to Recover a Deleted Git Branch

Problem

You accidentally deleted a local Git branch and you haven’t pushed the work anywhere. The branch had commits you need back.

git branch -D feature/payment-gateway
# Deleted branch feature/payment-gateway (was a3f2b1e).

Panic sets in. The commits aren’t merged, and there’s no remote backup.

Symptoms

  • git branch no longer lists the branch
  • git log --all shows the commits are gone
  • The work was local-only, never pushed

Root Cause

Git never truly deletes commits immediately. Deleting a branch only removes the branch pointer. The commits themselves remain as dangling objects in Git’s object database — for a while. Git’s garbage collector (git gc) eventually prunes unreferenced objects, but you have a window of days or weeks depending on your GC settings.

Git’s reflog records every movement of HEAD and branch tips for 90 days by default. This is your safety net.

Solution

Step 1: Find the lost commit hash

Use git reflog to see recent HEAD movements:

git reflog

You’ll see output like:

a3f2b1e HEAD@{0}: checkout: moving from feature/payment-gateway to main
b7c8d2f HEAD@{1}: commit: Add Stripe integration
e9f0a3b HEAD@{2}: commit: Add payment model

The commit you want is b7c8d2f or the one just before you checked out main.

Step 2: Recreate the branch at that commit

git branch feature/payment-gateway b7c8d2f

Or create and switch to it:

git checkout -b feature/payment-gateway b7c8d2f

Your branch is back with all commits intact.

Step 3 (Alternative): Use git fsck if reflog doesn’t help

If the reflog was cleared or the entry expired:

git fsck --lost-found

This lists dangling commits — commits unreachable from any branch or tag. Look for lines like:

dangling commit b7c8d2fabc123...

You can inspect a dangling commit before restoring it:

git show b7c8d2f

If it looks correct:

git branch feature/payment-gateway b7c8d2f

When Recovery is Impossible

  • The commits were never created (working tree changes without committing)
  • git gc --prune=now was run manually
  • The repository was cloned fresh after deletion (reflog doesn’t transfer on clone)

Verification

git branch --list feature/payment-gateway
# feature/payment-gateway

git log feature/payment-gateway --oneline -5
# Shows your commits

Prevention

  • Push early and often — even to a draft PR or a backup remote
  • Use git branch -d instead of -D — it refuses to delete unmerged branches
  • Create tags before risky operations: git tag backup-$(date +%Y%m%d)
  • Know your reflog expiry: git config gc.reflogExpire (default: 90 days)
  • Never run git gc --prune=now unless you’re certain

References


Advertisement