Ever run git reset --hard and instantly regret it? Or deleted a branch only to realize it had work you still needed?
Here’s the good news: Git rarely loses anything immediately. And when things seem gone, git reflog is often your way back.
What is Git Reflog (and why it exists)
While git log shows commit history, git reflog shows the history of where your HEAD and branches have pointed over time.
Think of it as a local timeline of every move you've made — commits, resets, checkouts, rebases — even the destructive ones.
If Git is a time machine, reflog is its hidden audit trail.
The key detail: reflog is local. It’s not shared with GitHub or other collaborators.
A quick look at reflog output
Run this:
1git reflogYou’ll see something like:
1a1b2c3d HEAD@{0}: reset: moving to HEAD~1
2f6e7d8c HEAD@{1}: commit: add payment validation
39a0b1c2 HEAD@{2}: commit: initial checkout logicEach entry tells you:
- The commit hash
- The position (HEAD@{n})
- What action happened
This is exactly what makes recovery possible.
Recovering a lost commit after a hard reset
Let’s say you did this:
1git reset --hard HEAD~1That commit looks gone. It’s not.
Check reflog:
1git reflogFind the commit before the reset:
1f6e7d8c HEAD@{1}: commit: add payment validationNow restore it:
1git checkout f6e7d8cOr move your branch back:
1git reset --hard f6e7d8cJust like that, your “lost” work is back.
Undoing a branch deletion
Deleted a branch too early?
1git branch -D feature/loginNo panic. Reflog still remembers where it pointed.
Search for it:
1git reflogLook for the last commit on that branch, then recreate it:
1git checkout -b feature/login <commit-hash>This works because Git doesn’t immediately delete the underlying commits.
Using HEAD references (the underrated trick)
You don’t always need hashes. Git lets you reference history like this:
1git checkout HEAD@{2}Or reset:
1git reset --hard HEAD@{3}This is incredibly useful when you're moving quickly and don’t want to copy hashes manually.
When reflog saves you during rebase mistakes
Interactive rebase can get messy:
1git rebase -i HEAD~5If something breaks or commits disappear, reflog shows the pre-rebase state:
1git reflogThen restore:
1git reset --hard HEAD@{before-rebase}This is often faster than trying to fix a broken rebase manually.
Important limitations
Reflog is powerful, but not magic:
- Entries expire (default ~90 days for commits, ~30 days for unreachable ones)
- It only exists locally
- Garbage collection can permanently remove commits
If you wait too long, recovery might not be possible.
Tips that make reflog even more useful
- Run git reflog immediately after mistakes
- Use descriptive commit messages to identify entries faster
- Avoid aggressive garbage collection during recovery
- Bookmark important commits with tags before risky operations
A mental model that helps
Instead of thinking “I lost my commit,” think:
“I just moved the pointer — the commit still exists somewhere.”
Reflog tells you exactly where that “somewhere” is.
Common developer mistakes
A few patterns show up often:
- Assuming git reset --hard permanently deletes work
- Not checking reflog before redoing work manually
- Panicking and making more changes before investigating
In most cases, reflog could have saved hours.
When you’ll use reflog in real projects
- Undoing accidental resets
- Recovering overwritten commits
- Fixing broken rebases
- Restoring deleted branches
- Investigating “what just happened” in your repo
It’s less about daily usage and more about having a safety net when things go wrong.
Wrapping it up
Git reflog isn’t flashy, but it’s one of the most practical recovery tools in your workflow. When history seems lost, it’s usually just hidden — and reflog is how you find it.
If you work with Git long enough, you’ll eventually need it. Knowing how to read and use reflog turns those “oh no” moments into quick recoveries.