iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

git reflog

`git reflog` records every change to HEAD on every branch in your local clone. It is the safety net for "I deleted that commit", "I force-pushed over it", "rebase ate my work". Reflog entries last ~90 days by default and are LOCAL — so they survive force-pushes but not a fresh clone. Learn it before you need it.

Find, recover, and curate your local reflog

EXAMPLE
# 1) See where HEAD has been
git reflog                              # newest at the top
git reflog --date=iso                   # include real timestamps
git reflog show main                    # per-branch reflog (a different log)

# 2) Recover a 'lost' commit after a reset, rebase, or branch delete
git reflog | head -20                   # find the lost SHA
git reset --hard HEAD@{4}               # or use the raw SHA
# Note HEAD@{N} = where HEAD was N moves ago

# 3) Reattach a detached HEAD's work as a new branch
git checkout -b rescued 9fceb02

# 4) Undo a bad rebase or merge
git reflog                              # find the commit before the bad rebase
git reset --hard HEAD@{12}              # reset to that snapshot
# Or, if it's clearly named:
git reset --hard ORIG_HEAD              # set automatically before destructive ops

# 5) After a 'whoops, I deleted that branch'
git reflog | grep -i 'feature-x'
# Recover the tip and re-create the branch
git checkout -b feature-x abc1234

# 6) Inspect a specific reflog entry
git show HEAD@{7}                       # the commit HEAD pointed at 7 moves back
git diff HEAD@{7} HEAD                  # what changed since

# 7) When the reflog is NOT enough
# - You never had the commit locally (only on the remote, and someone deleted the ref)
# - Your reflog has been pruned (gc.reflogExpire defaults to 90 days)
# - You re-cloned, wiping the local reflog
# In those cases, look on the remote:
git ls-remote --refs origin             # surviving refs only
# Or open the host UI; GitHub keeps deleted commits reachable for ~30 days.

# 8) Curate / expire — usually unnecessary
git reflog expire --expire=30.days.ago --all
git reflog expire --expire-unreachable=7.days.ago --all
git gc --prune=now                       # actually remove unreachable objects

# 9) Two reflogs to know about
# HEAD reflog:    git reflog              (where HEAD has been)
# Branch reflog:  git reflog show <ref>   (where this ref has been)
# Stash reflog:   git reflog show stash   (your stash history)

# 10) Make recovery a reflex
# Alias for the common 'find a lost commit, look at it, decide what to do':
git config --global alias.last 'reflog -n 20 --date=iso'
git config --global alias.unduck 'reset --hard HEAD@{1}'   # undo the last destructive op

# 11) Confidence-builder
# Before any scary command (rebase -i, reset --hard, filter-branch), run:
git tag _SAFETY HEAD                    # creates a movable bookmark
# If anything goes wrong:
git reset --hard _SAFETY
git tag -d _SAFETY

Why it matters

`git reflog` is the offline undo button most teams discover after their first force-push regret. Make it part of the muscle memory: before any destructive command, glance at `git reflog | head` so you know where HEAD is — then if the next step is wrong, `git reset --hard HEAD@{1}` rolls back to exactly where you started.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
git reflog          # ALL ref movements — recover "lost" commits
git reset --hard HEAD@{2}
Try it Yourself »

Discussion

Loading…