Git Reflog
The git reflog (Reference Log) is a record of every position that HEAD has pointed to — every branch switch, every commit, every reset, every rebase, every pull. It is essentially a local diary of all movements through the repository's history.
Reflog is stored locally and is NOT pushed to GitHub. It is a personal safety net that allows recovery of commits or changes that appear to be "lost."
Real-life analogy: Think of the reflog as CCTV footage of every action taken in the repository. Even if a file is accidentally deleted from a shelf (via reset, rebase, or amend), the CCTV footage shows the exact moment it was last seen — making it possible to recover it.
When Does Reflog Save the Day?
- After an accidental
git reset --hardthat wiped commits - After a branch was deleted before merging
- After a rebase went wrong
- When looking for an old commit that no longer appears in
git log
Viewing the Reflog
git reflogSample output:
a3f92b1 (HEAD -> main) HEAD@{0}: commit: Add login page
b7c3d45 HEAD@{1}: commit: Update homepage
c1a2b3c HEAD@{2}: checkout: moving from feature to main
d4e5f6g HEAD@{3}: commit: Start feature work
e7f8g9h HEAD@{4}: reset: moving to HEAD~2
Each entry shows:
- The short commit hash
HEAD@{N}— the N-th position back in the reflog- The action that moved HEAD to this position
- A description of the action
Reflog for a Specific Branch
git reflog mainThe Most Important Use: Recovery After git reset --hard
# Scenario: Accidentally reset 3 commits
git reset --hard HEAD~3
# Oh no! Three commits were wiped.
# Step 1: Open reflog to find the lost commits
git reflog
# Output:
# a3f92b1 HEAD@{0}: reset: moving to HEAD~3
# d4e5f6g HEAD@{1}: commit: Third commit
# e7f8g9h HEAD@{2}: commit: Second commit
# f1g2h3i HEAD@{3}: commit: First commit ← This was before the reset
# Step 2: Recover by resetting back to the lost commit
git reset --hard f1g2h3i
# Or use the reflog reference:
git reset --hard HEAD@{3}
# Three commits are fully restored!
Recovering a Deleted Branch
# Scenario: A branch was deleted before merging
git branch -D feature-login
# "Oh no! I haven't merged this yet!"
# Step 1: Find the last commit of the deleted branch in reflog
git reflog
# Output includes:
# b7c3d45 HEAD@{5}: commit: Add login validation
# ...
# Step 2: Create a new branch pointing to the recovered commit
git switch -c feature-login b7c3d45
# The branch is fully restored with all its commits!
Recovering After a Bad Rebase
# Scenario: A rebase went very wrong
git rebase main
# Something went terribly wrong...
# Find the state before the rebase
git reflog
# Output:
# a1b2c3d HEAD@{0}: rebase (finish): returning to refs/heads/feature
# b1c2d3e HEAD@{1}: rebase (start): checkout main
# c1d2e3f HEAD@{2}: commit: My feature work ← Before the rebase
# Recover the pre-rebase state
git reset --hard c1d2e3f
Show Reflog with Dates
git reflog --date=relativeOutput:
a3f92b1 HEAD@{2 minutes ago}: commit: Add login page
b7c3d45 HEAD@{1 hour ago}: commit: Update homepage
How Long Does Reflog Keep History?
By default, reflog entries are kept for 90 days (30 days for unreachable commits). After that, Git may garbage-collect them. The expiry time can be configured:
# Keep reflog entries for 180 days
git config gc.reflogExpire 180.days
# Keep unreachable entries for 90 days
git config gc.reflogExpireUnreachable 90.days
Reflog is Local Only
The reflog is stored in .git/logs/ and is never pushed to GitHub. It is unique to each developer's machine. This means if a repository is cloned fresh, the reflog history from the original machine is not available.
Summary
The git reflog is the ultimate safety net in Git. It records every movement of HEAD, allowing recovery of lost commits, deleted branches, and botched rebases that would otherwise be permanently gone. The key recovery pattern is: find the hash in reflog → git reset --hard <hash> or git switch -c branch-name <hash>. The reflog is kept for 90 days by default and is stored locally only.
