Git Reflog: The Complete Recovery Guide

The reflog is Git's private flight recorder. Every time HEAD moves — commit, reset, rebase, checkout, merge — Git logs it. If you have ever lost work to a git reset --hard or a gone-wrong rebase, the reflog is almost certainly your path back. This guide explains how to read it and how to use it to recover from the most common disasters.

What the reflog actually is

The reference log (reflog) is a local journal stored in .git/logs/. It is separate from your commit history — it records where HEAD (and each branch tip) has pointed over time, including movements that never made it into a permanent commit. Every checkout, every reset, every rebase step creates a new reflog entry.

Critically, the reflog is local only. When you clone a repo you do not get the original author's reflog. This is what makes it a recovery tool: it captures the full history of your local session even when the normal commit graph has been rewritten.

How to read reflog output

Run git reflog (or git reflog show HEAD) to see the HEAD reflog:

git reflog

Typical output:

a3f1c29 HEAD@{0}: reset: moving to HEAD~3 9b2e847 HEAD@{1}: commit: add payment validation 4d8c013 HEAD@{2}: commit: extract form component 7f0a1b5 HEAD@{3}: checkout: moving from feature to main 2c9e6d4 HEAD@{4}: rebase (finish): returning to refs/heads/feature 1a7b3f8 HEAD@{5}: rebase (pick): fix edge case in parser

Each line has three parts:

  • Hash — the commit SHA that HEAD pointed to at that moment
  • HEAD@{N} — a relative selector (0 = current, 1 = one move ago)
  • Action + message — what caused HEAD to move and the associated commit message

You can use either the hash or the HEAD@{N} notation in any Git command that accepts a commit reference.

Recovery scenarios

  • Scenario 01
    You ran git reset --hard and lost commits

    The most common panic. You reset to an earlier state and the commits appear gone from git log. Find them in the reflog:

    git reflog # find the commit before the reset git reset --hard HEAD@{2} # jump back to that point

    Or, if you want to inspect before resetting, check out the target commit first:

    git checkout 9b2e847 # detached HEAD — safe to look git checkout -b recovered-work # make it a branch if you want to keep it
  • Scenario 02
    A rebase went wrong and rewrote commits you wanted to keep

    After a bad interactive rebase, your branch history is scrambled. The reflog records every step of the rebase. Find the entry labeled rebase (start) — the commit just before it is your pre-rebase branch tip:

    git reflog show feature-branch # see the branch-specific reflog git reset --hard feature-branch@{4} # restore to before rebase started
    Tip

    Run git reflog show <branch-name> to see the reflog for a specific branch rather than HEAD. This is more precise when you have been on multiple branches in the same session.

  • Scenario 03
    You deleted a branch with unmerged commits

    The branch pointer is gone but the commits still exist. The reflog shows the last commit that was on that branch:

    git reflog # find the last commit hash of the deleted branch git checkout -b restored-branch abc1234 # recreate the branch from that hash

    Look for a reflog entry with an action like checkout: moving from deleted-branch to ... — the hash on that line is the tip of the deleted branch at the moment you left it.

  • Scenario 04
    You accidentally amended a commit and want the original back

    git commit --amend creates a new commit and moves the branch pointer. The original commit is in the reflog:

    git reflog # find HEAD@{1} — that's the pre-amend commit git reset --soft HEAD@{1} # go back, keep changes staged

    Or, to retrieve just the original commit message without changing your staged changes, use git show HEAD@{1} to read it.

  • Scenario 05
    You ran git checkout and switched away from uncommitted work

    If you switched branches without stashing and Git silently carried your changes — or worse, overwrote them — the reflog tells you where HEAD was:

    git reflog # find the checkout entry git diff HEAD@{1} # see what changed when HEAD moved

    If Git refused the checkout due to conflicts, your working tree changes are still there. If it succeeded and carried them, git stash then switch back.

Filtering the reflog for large repos

On active repos the reflog can have hundreds of entries. Narrow it down:

git reflog --since="2 hours ago" # entries from the last 2 hours git reflog | grep "commit:" # only lines where a commit happened git reflog | grep "reset" # find all resets git log -g --oneline # reflog in log format — easier to scan

How long does the reflog keep entries?

By default, Git keeps reflog entries for 90 days (30 days for unreachable commits). After that, git gc can prune them. You can inspect the current expiry settings with:

git config --get gc.reflogExpire # default: 90 days git config --get gc.reflogExpireUnreachable # default: 30 days

To give yourself more runway on a repo where you do a lot of destructive operations:

git config gc.reflogExpire "180 days" git config gc.reflogExpireUnreachable "60 days"
Important

The reflog is local. If you clone a repo on a new machine or someone else clones yours, the reflog does not transfer. For commits you absolutely cannot lose, push to a remote branch — that is the only off-machine backup.

Quick reference

Command What it does
git reflog Show the HEAD reflog (most recent first)
git reflog show <branch> Show the reflog for a specific branch
git log -g --oneline Reflog in compact log format
git reflog --since="1 hour ago" Filter reflog to recent entries
git reset --hard HEAD@{N} Restore HEAD to the state N moves ago
git checkout -b name <hash> Create a branch at any reflog commit hash
git show HEAD@{N} Inspect any reflog entry without moving HEAD
Git Unfucked — the full recovery reference

30+ scenarios. Every reset, revert, reflog, and stash pattern documented with context on when to use each. One PDF, buy once.

Get Git Unfucked →

More from the blog

How to Recover a Deleted Git Branch → How to Recover a Lost Git Stash → How to Undo a Git Commit (The Right Way) →

Get notified when we ship

New Unfucked references and dev tips. No spam.