Git Reflog — The 90-Day Safety Net That Saved a Deleted Branch
git reflog records every HEAD movement for 90 days.
20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.
- ✓Solid grasp of devops fundamentals
- ✓Comfortable reading and writing code examples independently
- ✓Basic understanding of production deployment concepts
git reflog shows every HEAD movement. Find the SHA before the disaster, then git reset --hard to restore. Reflog entries expire after 90 days (configurable).
Think of git reflog as the black box flight recorder on an airplane. It records every single move the plane (HEAD) makes — every turn, every altitude change, every bump. When something goes wrong, you can rewind the tape and see exactly where things went off course. The regular git log is the passenger manifest (who's on board). Reflog is the flight recorder (how the plane moved). Both are essential, but only reflog can tell you how you GOT to the current state.
| Chrome | Firefox | Safari | Edge |
|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ |
Every Git user eventually has a 'oh no' moment: git reset --hard on the wrong commit, deleted the wrong branch, rebase gone wrong. git reflog is the safety net for all of these. It records every HEAD movement for 90 days, and recovering from almost any disaster is a single reflog lookup away. The catch: reflog is LOCAL. It only records YOUR movements on YOUR machine. If you never had the commit locally, reflog can't help you. This guide covers the core recovery patterns and the incident where reflog saved three weeks of work after a botched rebase.
Understanding the Reflog
The reflog lives in .git/logs/HEAD. Each line records: old SHA, new SHA, committer, timestamp, and action description. git reflog displays a simplified view with an index (HEAD@{0}, HEAD@{1}, etc.), SHA, and action.
git reflog show <branch> shows the reflog for a specific branch. git reflog --all shows reflogs for all refs including stashes. git log -g shows the log with reflog references.
Reflog expiration is 90 days for reachable commits and 30 days for unreachable (dangling) commits. Running git gc (garbage collection) manually can expire entries early. git reflog expire --expire=now --all clears the reflog intentionally.
git reflog expire --expire-unreachable=now --all && git gc --aggressive on build agents to prevent reflog bloat. Developer machines should keep the default 90-day expiry. For critical repos, consider backing up .git/logs/ as part of your backup strategy — it's a small file that can save weeks of work.git reflog before panicking after a Git disaster.Deleted Branch With 3 Weeks of Work — Reflog to the Rescue
git branch -D instead of -d. The branch had 3 weeks of unmerged work. The developer panicked. A senior engineer ran git reflog | grep feature/payments, recovered the SHA, and recreated the branch in 30 seconds.git branch -D feature/payments to delete an old local branch. 2. The branch contained commits that had never been pushed to remote. 3. Git deleted the branch pointer but NOT the commits. The commits became dangling objects. 4. The developer didn't know about reflog. They assumed the commits were gone forever. 5. Three weeks of work was recoverable — still in Git's object database, referenced by reflog.git reflog | head -30 to see recent HEAD movements. 2. Found the entry: a1b2c3d HEAD@{14}: checkout: moving from feature/payments to main. 3. The SHA a1b2c3d was the last commit on the deleted branch. 4. Ran git branch feature/payments a1b2c3d to restore the branch pointer. 5. Pushed the recovered branch to remote: git push origin feature/payments.- Reflog records every HEAD movement for 90 days.
git branch -Ddeletes the pointer, not the commits.- Recovery is always possible if you haven't run
git gc. - Check reflog before panicking.
- Push important branches to remote frequently — reflog is local, remote is permanent.
git reflog | head -20, find the SHA before the reset, then git reset --hard <sha>git reflog | grep <branch-name> to find the tip commit SHA, then git branch recovered-branch <sha>git reflog to find ORIG_HEAD or the SHA before rebase, then git reset --hard <sha>Key takeaways
git reflog | grep <branch> then git branch <name> <sha>20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.
That's Git. Mark it forged?
3 min read · try the examples if you haven't