You've just deleted a branch that contained three days of work. Your stomach drops. But before you panic, know this: Git reflog: recover lost commits — a step-by-step guide is the lifeline you need. Almost nothing in Git is truly lost, and the reflog is your safety net.
Understanding reflog: A log of where HEAD and branches pointed
The reflog—short for reference log—is often misunderstood. It's not a record of commits themselves, but rather a chronological history of where your HEAD pointer and branch references have moved over time. Think of it as a detailed breadcrumb trail of your repository's navigational history.
When you check out a branch, rebase, reset, or merge, Git records that movement. Every time you run git checkout main, create a new branch, or force-push, the reflog captures it. This makes reflog invaluable for recovering work that seems to have vanished.
Here's the critical distinction: your commit history (git log) shows the ancestry of reachable commits. Your reflog shows every place your references have been, whether those commits are currently reachable or not. A commit can disappear from git log but still exist in the reflog for 30–90 days.
In practical teams, this distinction has saved us countless times. A developer accidentally force-pushes to a shared branch, a rebase goes wrong, or someone performs an interactive rebase that squashes away intermediate work. The reflog doesn't judge—it just records.
Finding the lost commit using git reflog
The first step in recovery is visibility. Run git reflog to see the recent movements of HEAD:
git reflogThis displays output similar to:
a1b2c3d HEAD@{0}: checkout: switching to main
f4e5d6c HEAD@{1}: commit: add payment gateway integration
2k3l4m5 HEAD@{2}: reset: moving to HEAD~2
7n8o9p0 HEAD@{3}: rebase -i (finish): returning to refs/heads/feature/checkout
q1r2s3t HEAD@{4}: rebase -i (start): checkout 8b9c0d1
u4v5w6x HEAD@{5}: checkout: switching to feature/checkoutEach line represents a movement. The syntax HEAD@{n} refers to the nth previous value of HEAD. The timestamp and operation description help you find exactly what you're looking for.
If you're searching for a specific branch's history, use:
git reflog show branch-nameFor example:
git reflog show feature/checkoutThis shows only movements of the feature/checkout reference, making it easier to spot when the branch was at a particular state.
In our experience, the moment you run reflog after realizing something's missing, you'll feel the tension ease. The information is almost always there. You'll see the commit hash and understand exactly what operation led to the loss.
Recovering lost commits by creating a branch
Once you've located the commit in your reflog, recovery is straightforward. The safest approach is to create a new branch pointing to that commit. This preserves the lost history without modifying any existing branches.
Suppose from the reflog above, you can see that commit f4e5d6c (the payment gateway integration) is what you need to recover. Create a branch from it:
git branch rescue-payment f4e5d6cOr, if you prefer to reference it by reflog position:
git branch rescue-payment HEAD@{1}Both commands create a new branch called rescue-payment pointing to that commit. You can then check it out and examine the work:
git checkout rescue-payment
git log --oneline -5Now the lost commits are reachable again, and you can decide how to proceed. You might cherry-pick specific commits onto your main branch, merge the entire branch, or simply copy code from the rescue branch into your working directory.
A common real-world scenario: a developer has been working on a feature branch, makes several commits, but then accidentally runs git reset --hard origin/main before pushing. Their local commits vanish from the branch. The reflog still knows they existed:
git reflog show feature/important-work
# Output shows the commits were at HEAD@{5}
git branch restore-important-work HEAD@{5}
# All commits are now accessible again
The key principle: you're never deleting anything when you create a recovery branch. You're just making an unreachable commit reachable again.
Understanding the time limit: When commits are pruned
Reflog entries don't last forever. By default, Git keeps reflog records for unreachable commits for about 30 days, though this can extend to 90 days depending on your Git configuration and system garbage collection policies.
Check your current reflog expiration setting:
git config --global gc.reflogExpireIf it returns nothing, the default (30 days) applies. You can extend it if needed:
git config --global gc.reflogExpire 90.daysThis extends the reflog retention period to 90 days for unreachable commits. For commits reachable from branches or tags, reflog entries persist indefinitely.
The practical implication: don't wait months to recover lost work. If something goes wrong, check the reflog within days. In team environments, this becomes a support question: "I lost a commit—how do I get it back?" Answer: "Run git reflog now. You have at least 30 days."
Garbage collection happens periodically during heavy Git operations like git repack or git gc. Once the reflog expires and garbage collection runs, the unreachable commits may be permanently deleted. However, even then, if you have any reference to a commit (a branch, tag, or even a reflog entry in your team's centralized logs), it can still be recovered.
Common mistakes to avoid
Mistake 1: Assuming the reflog shows all Git history. It doesn't. The reflog is local to your repository. If you clone a fresh copy of a repository, it won't have the previous reflog from another machine. The reflog is also not shared across team members—each developer has their own.
Mistake 2: Not acting quickly enough. Reflog entries expire. If weeks pass without recovery, entries may be pruned. Make recovery a priority if you discover lost commits.
Mistake 3: Directly resetting HEAD to a reflog entry. Instead of git reset --hard HEAD@{3}, which rewrites history, create a recovery branch first. This gives you a safe checkpoint to examine the lost work without risk.
Mistake 4: Forgetting that reflog is machine-specific. If you work across multiple machines, the reflog on your laptop differs from the reflog on your workstation. Lost commits might still exist on the machine where you originally worked.
Mistake 5: Ignoring the branch-specific reflog. If you lost work on a specific branch, use git reflog show branch-name rather than the global reflog. This narrows your search significantly.
Key takeaways
- The reflog records movements of HEAD and branch references, making it distinct from commit history and crucial for recovery.
- Run
git reflogimmediately when you discover lost commits to identify the commit hash and understand what happened. - Create a recovery branch from the lost commit using
git branch rescue-name commit-hashrather than directly resetting, keeping your recovery process safe. - Remember that reflog entries for unreachable commits expire after 30–90 days by default; prioritize recovery.
- The reflog is local and machine-specific; if you use multiple machines, check the reflog on the machine where you originally worked.
- Use
git reflog show branch-nameto focus on movements of a specific branch when narrowing your search.






Comments
Loading comments…