Skip to content

Lab: Recover a Deleted Git Branch

Lesson 1 of 6Beginner3 min readHands-On Git & GitHub Labs · Git Recovery Labs
Time10 minutes
LevelBeginner
You needLocal Git only — no GitHub account needed

You finished a feature on a branch, decided it was a dead end, and deleted the branch. An hour later the decision is reversed: that work is needed after all.

git branch no longer lists it. The commits appear to be gone.

They are not.

Recover a deleted branch and its commits using the reflog, and understand why it works — so that the next time this happens for real, it is a two-minute fix rather than an afternoon.

  • Git installed (git --version)
  • Familiarity with git commit and git branch
  • Understanding of HEAD helps, but the lab explains what you need

Build a disposable repository with a branch worth losing:

Terminal window
mkdir -p /tmp/lab-recover && cd /tmp/lab-recover
git init -q .
git config user.email "lab@example.com"
git config user.name "Lab User"
echo "# Project" > README.md
git add . && git commit -q -m "Initial commit"
git switch -qc feature/pricing
echo "export const PRICE = 4200;" > pricing.js
git add . && git commit -q -m "Add pricing module"
echo "export const TAX = 0.2;" > tax.js
git add . && git commit -q -m "Add tax calculation"
git switch -q main
git log --oneline --all

You should see three commits, two of them only on feature/pricing.

  1. Delete the branch. Git will refuse a safe delete because the work is unmerged, which is itself informative:

    Terminal window
    git branch -d feature/pricing

    Expected: error: the branch 'feature/pricing' is not fully merged.

    Now force it:

    Terminal window
    git branch -D feature/pricing
  2. Confirm it is gone. git branch lists only main. git log --oneline --all no longer shows the two commits.

  3. Find the lost commits. Do not panic and do not run git gc. Run:

    Terminal window
    git reflog

    Read the output before continuing. What does each line represent?

  4. Identify the tip commit of the deleted branch — the entry whose message mentions the last commit you made on it (Add tax calculation).

  5. Recover it by creating a branch at that commit:

    Terminal window
    git switch -c feature/pricing <sha>
  6. Verify. git log --oneline should show all three commits, and ls should show pricing.js and tax.js.

Stuck on step 3? The reflog is a log of where HEAD has been, newest first. Deleting a branch does not delete commits — it deletes a pointer to them. The commits are still in the object database, just unreferenced.

Stuck on step 4? git reflog shows entries like a1b2c3d HEAD@{2}: commit: Add tax calculation. You want that SHA. You can also use the HEAD@{n} form directly.

Want to see it more directly? git fsck --lost-found lists unreachable objects — the same commits, found a different way.

Terminal window
git reflog
# a1b2c3d HEAD@{0}: checkout: moving from feature/pricing to main
# a1b2c3d HEAD@{1}: commit: Add tax calculation
# 9f8e7d6 HEAD@{2}: commit: Add pricing module
# 1a2b3c4 HEAD@{3}: commit (initial): Initial commit
git switch -c feature/pricing a1b2c3d
# Switched to a new branch 'feature/pricing'
git log --oneline
ls

Your SHAs will differ — they are content-derived, so they are unique to your run.

Equivalent, using the reflog reference directly:

Terminal window
git switch -c feature/pricing HEAD@{1}

A branch is a file containing a SHA. refs/heads/feature/pricing held 41 bytes: a commit hash and a newline. git branch -D deleted that file. It did not touch the commit objects.

The commits became unreachable, not deleted. Nothing pointed at them, so they were invisible to git log and git branch — but they were still in .git/objects.

The reflog is the safety net. Git records every movement of HEAD in .git/logs/HEAD, including movements away from commits that no branch references any more. That log is what makes this recoverable.

Recovery is just creating a new pointer at the commit the reflog identifies.

What this does not cover: uncommitted changes. The reflog tracks commits. Work that was never committed is not in Git at all, and nothing here recovers it.

Terminal window
cd /tmp && rm -rf lab-recover

Resolve a merge conflict — create a genuine conflict and work through resolving it properly.

Choose a learning pathA sequenced route through the curriculum for wherever you are now.