By admin , 28 April 2026

Introduction

The reflog records every change to HEAD and to each branch tip on your local machine. It is local, per-clone, and not pushed. Almost any "lost" commit can be rescued through it.

Viewing

git reflog                            # HEAD reflog
git reflog show main                  # main's reflog
git reflog --date=iso
git log -g --oneline                  # log walk through reflog

Each entry has a sequence (HEAD@{0}, HEAD@{1}, ...), an action (commit, reset, merge, rebase, ...), and a target SHA.

Recovering a lost commit

git reflog
# 9f8a1c2 HEAD@{0}: reset: moving to HEAD~3
# a1b2c3d HEAD@{1}: commit: Important work
git switch -c rescued a1b2c3d

Or directly:

git reset --hard HEAD@{1}

Time-based syntax

git show HEAD@{2.hours.ago}
git diff main@{yesterday} main

Git interprets @{...} as either a count or a date.

Reflog expiration

By default reachable reflog entries expire after 90 days, and unreachable ones after 30:

git config gc.reflogExpire 90.days
git config gc.reflogExpireUnreachable 30.days

Until expiration, even hard-reset commits remain recoverable.

Per-ref reflogs

Each branch has its own reflog at .git/logs/refs/heads/<name>. Stash also has one (refs/stash):

git reflog show stash

Pruning the reflog

git reflog expire --expire=now --all
git gc --prune=now

Use only if you need to permanently delete data; this removes the safety net.

Reflog vs git log

git log walks the commit graph by parent pointers; the reflog walks recorded movements of a ref. After a force-reset, git log no longer shows the abandoned commits, but the reflog still does.

Per-ref reflog inspection

Each ref keeps its own reflog. Inspect a specific branch's reflog to see how its tip moved:

git reflog show feature/login
git log -g feature/login --oneline
cat .git/logs/refs/heads/feature/login

Useful when investigating "who moved this branch?" on a local clone. The reflog file format is one line per change with old SHA, new SHA, committer, timestamp, and a textual message. Combined with git blame on the file, it gives a complete local audit trail; remember reflogs are not pushed, so the trail covers your machine only.

Common mistakes

Forgetting the reflog exists in a panic and re-doing hours of work that was easily recoverable. Always check git reflog first. Pushing during recovery and assuming the reflog is on the server; it is not, only your local clone has it. Running git gc --prune=now on a "clean up" instinct and destroying the safety net for any unreferenced commit. And finally, treating reflog entries as forever; long-deleted refs do age out. Tag or branch anything you want to keep before 30 days pass.