Git Reflog: Recovering Lost Commits and History
In this tutorial, you'll learn about Git Reflog: Recovering Lost Commits and History. We cover key concepts, practical examples, and best practices.
The reflog is Git's local record of where HEAD and branch references have pointed, acting as a safety net for recovering lost commits and undoing mistakes.
In this tutorial, you'll learn Git reflog — the reference log that records every movement of Git's HEAD pointer. When you lose a commit (deleted branch, hard reset, rebase gone wrong), the reflog is your safety net. By the end, you'll confidently recover lost work and understand Git's internal reference tracking.
flowchart TD
A[Mistake made] --> B{What happened?}
B --> C[git reset --hard]
B --> D[Deleted branch]
B --> E[Rebase went wrong]
C --> F[git reflog]
D --> F
E --> F
F --> G[Find commit hash before mistake]
G --> H[git reset --hard ]
G --> I[git checkout -b branch ]
H --> J[Restored!]
I --> J
Viewing the Reflog
git reflog
Expected output:
a1b2c3d HEAD@{0}: reset: moving to HEAD~1
b2c3d4e HEAD@{1}: commit: Add payment feature
c3d4e5f HEAD@{2}: commit: Fix login bug
d4e5f6g HEAD@{3}: commit: Add login page
e5f6g7h HEAD@{4}: commit: Initial commit
Each entry shows: commit hash, reflog position, action, and description.
Recovering from a Hard Reset
You run git reset --hard HEAD~1 by mistake and lose your last commit:
git reflog
# Find the commit before the reset
# a1b2c3d HEAD@{1}: commit: The lost work
git reset --hard a1b2c3d
Restoring a Deleted Branch
git branch -D feature/login # Oops, deleted the wrong branch
git reflog
# Look for the "branch: checkout" entry for your branch
# c3d4e5f HEAD@{2}: checkout: moving from feature/login to main
git checkout -b feature/login c3d4e5f
Undoing a Rebase Mistake
If a rebase produces wrong results:
git rebase main # Something went wrong
git reflog
# BEFORE the rebase starts, you see:
# d4e5f6g HEAD@{1}: checkout: moving from feature to main
git reset --hard d4e5f6g # Restore pre-rebase state
Reflog vs Log
| Feature | git log | git reflog |
|---|---|---|
| Scope | Commit history | Reference changes |
| Includes orphaned commits | No | Yes |
| Includes branch switches | No | Yes |
| Includes resets and rebases | No | Yes |
| Shared via push | Yes | No (local only) |
| Persistence | Permanent | ~90 days |
| Use case | Project history | Disaster recovery |
Understanding Reflog Entries
Each reflog entry has a specific format:
<commit-hash> HEAD@{<index>}: <action>: <description>
Common actions include:
commit:A new commit was madecheckout:Moving between branches or commitsreset:HEAD pointer was moved (reset or rebase)merge:A merge was performedrebase:A rebase started or finishedcherry-pick:A commit was cherry-pickedam:Patches applied viagit am
The index number (HEAD@{0}, HEAD@{1}, etc.) represents recency — HEAD@{0} is the most recent action.
Time-Based Reflog Queries
You can reference reflog entries by time instead of index:
# What was HEAD 1 hour ago?
git show HEAD@{1.hour.ago}
# What was HEAD yesterday?
git show HEAD@{yesterday}
# What was HEAD last week?
git show HEAD@{1.week.ago}
Time formats: 5.minutes.ago, 2.hours.ago, 3.days.ago, 1.month.ago.
Reflog for All References
git reflog --all
This shows reflog entries for all references, not just HEAD.
Common Errors
| Error | Cause | Fix |
|---|---|---|
fatal: bad object in reflog |
Object garbage collected | Cannot recover — expired entry |
| Reflog entry not found | Entry too old (90+ days) | Increase gc.reflogExpire |
reflog: no such ref |
Reference deleted history | Check with git reflog show <ref> |
sha1 is ambiguous |
Short hash matches multiple | Use longer hash (7-10 chars minimum) |
Could not find a unique ref |
Hash not in reflog | Try with more characters or different ref |
| Reflog shows nothing | Empty repository | No history to log |
reset --hard brought wrong commit |
Typo in commit hash | Reflog again and double-check |
| Branch recovered but dirty | Uncommitted changes lost | Can't recover without prior stash |
Practice Questions
Challenge
Create a repository with five commits. Delete the latest commit with git reset --hard HEAD~1. Use reflog to recover it. Then create a branch, add two commits, delete the branch with git branch -D. Use reflog to recover both the branch and its commits. Document each reflog command used.
Real-World Task
In a shared repository, a teammate accidentally force-pushed a rebased branch, losing three commits from another developer. Use git reflog on the local clone of the developer who lost commits to find the commit hashes. Recover them by creating new branches at those hashes. Cherry-pick the recovered commits onto the current branch. Push and notify the team. This recovery scenario is part of incident response at DodaTech for Durga Antivirus Pro's development.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro