Git

Git Reflog: Recover Deleted Local Branch or Lost Commit

The reflog is Git's local, chronological record of everywhere HEAD and your branch references have pointed over time — it's specifically designed as a safety net for exactly this kind of accident, and recovering a deleted branch or seemingly lost commits from it is one of the most common and reliable Git recovery operations.

The Problem

A local branch was deleted, either intentionally by mistake or as an unintended side effect of another command, and you need the commits it contained back:

git branch -D feature-branch
Deleted branch feature-branch (was a1b2c3d).

Or, separately, a series of commits seem to have simply vanished after a hard reset, a rebase gone wrong, or another history-altering operation.

Reflog: where HEAD has been HEAD@{0} HEAD@{1} HEAD@{2} deleted branch tip Even after deletion, the commit is still findable here

Why It Happens

Deleting a branch (or performing a hard reset, or a rebase) removes the reference pointing to certain commits, but the commits themselves typically remain in Git's object database — the reflog specifically tracks the history of what a reference (like HEAD or a branch) pointed to over time, giving you a trail back to commits that are no longer referenced by any current branch. This makes recovery possible in exactly this scenario, as long as the commits haven't been permanently removed by garbage collection, which normally only happens after a substantial grace period (commonly 30-90 days by default) for unreferenced objects.

The Fix

To recover a deleted branch, first check the reflog to find the commit hash the branch pointed to right before deletion:

git reflog

Look for an entry corresponding to the branch's last known state — often visible directly in the reflog message itself, especially right after a deletion:

a1b2c3d HEAD@{2}: commit: Add new feature logic
e4f5g6h HEAD@{1}: checkout: moving from feature-branch to main
i7j8k9l HEAD@{0}: branch: Deleted feature-branch

Once you've identified the correct commit hash (in this example, a1b2c3d, the last commit on the branch before it was deleted), recreate the branch pointing at it:

git branch feature-branch a1b2c3d

Your branch is now restored, containing exactly the commits it had at the point of deletion.

For lost commits after a hard reset or a botched rebase, the same fundamental approach applies — check the reflog to find the commit hash from before the operation that seemingly lost them:

git reflog
# find the entry showing HEAD's position before the reset/rebase

git reset --hard <commit-hash-from-reflog>
# or, more cautiously, create a new branch instead of directly resetting:
git branch recovered-work <commit-hash-from-reflog>

Creating a new branch pointing at the recovered commit, rather than immediately doing a hard reset on your current branch, is generally the safer first step — it lets you inspect and confirm the recovered state is genuinely what you expect before deciding whether to actually reset your working branch to match it.

If you're not sure exactly which reflog entry corresponds to what you're looking for, use git show on candidate commit hashes to inspect their actual content before committing to a recovery choice:

git show a1b2c3d

Still Not Working?

If the reflog itself doesn't show the entry you're looking for (perhaps because significant time has passed, or the reflog was cleared), broaden the search using git fsck, which finds dangling commits directly in Git's object database, independent of what the reflog specifically remembers:

git fsck --unreachable --no-reflogs | grep commit

This can surface commits the reflog itself no longer references, though without the reflog's helpful context messages, you'll need to inspect each candidate hash with git show to identify which one is actually what you're looking for among potentially several unreferenced commits found this way.

It's worth understanding the reflog's own limitations so you know when to trust it versus when to reach for this broader search. The reflog is entirely local to your machine — it's never pushed to a remote and doesn't exist at all in a fresh clone, so this recovery technique only works on the same machine and local repository where the original branch or commits existed. It also only retains entries for a limited time (30 days by default for entries no longer reachable from any branch, though this is configurable), after which Git's garbage collection becomes eligible to permanently remove genuinely unreferenced objects.

Given these limitations, if you regularly find yourself needing to recover from accidental branch deletions or resets, it's worth building the habit of checking git reflog immediately after realizing something was lost, rather than continuing to work in the repository for an extended period first — while the entries themselves persist for a while, minimizing the time between the mistake and the recovery attempt reduces any chance of relevant entries being affected by an intervening garbage collection run, whether triggered automatically or manually.