Technology git reflog explained

Learn with diagrams, code, systems and practical examples.

</>
Git recovery reference · Reviewed 2026-08-24

git reflog: recover from ref movement before you rewrite more state

Learn git reflog as local ref-movement history for recovering commits after resets, rebases, branch moves, and other history-changing operations.

01Inspect

Read the local ref-movement timeline and identify candidate states without changing anything.

02Predict

State what the candidate commit should contain and why that reflog entry plausibly represents the lost state.

03Preserve

Make the candidate reachable with a recovery branch before attempting another destructive operation.

04Verify

Inspect files/history and choose the least disruptive way to reintegrate the recovered work.

Understand

Reflog records local ref movement—not a second copy of remote history

A reflog records updates to refs in your local repository. For HEAD, that means you can often see where your checkout or branch tip pointed before a reset, rebase, amend, checkout, or other movement. It is a recovery aid—not a remote audit log, shared history, or durable backup.

Predict before revealing

You reset a private branch from commit C back to A. If C is no longer in normal git log output, does that automatically mean the commit object is gone?

Reveal the reasoning

No. Moving the branch pointer changes reachability from that branch, but the local reflog often records the old tip. If C is still available, you can inspect it and create a recovery branch before deciding how to reintegrate the work.

Recovery principle

Reflog is most useful when you stop making destructive changes, inspect the local evidence, and preserve a candidate commit before moving any branch again.

Read the timeline

Understand the selectors before using one

show [<ref>]

Show the reflog for HEAD or another named ref.

Inspecting recent local movements before attempting recovery.
HEAD@{<n>}

Revision syntax selecting an earlier reflog entry by ordinal position.

Referring to a known earlier local HEAD state after inspecting the reflog.
<ref>@{<date>}

Revision syntax selecting where a ref was at a prior local time, when the reflog retains that history.

Investigating an approximate pre-change state when you know roughly when the movement happened.
--date=<format>

Control how reflog timestamps are displayed.

Making a recovery timeline easier to read; this changes display, not repository history.
expire / delete / drop

Maintenance operations that remove or expire reflog entries.

Repository maintenance only—not as part of an ordinary recovery attempt.

A selector such as HEAD@{1} means “an earlier entry in this local HEAD reflog,” not “the parent commit” or “one commit ago.” Read the reflog first.

Stop moving state

Before you attempt recovery

  1. Stop resets, rebases, pruning, or cleanup while you are still trying to understand what moved.
  2. Run git status so unrelated working-tree changes do not become a second recovery problem.
  3. Read git reflog --date=local and note the operation labels, timestamps, and old/new states around the mistake.
  4. Inspect candidate entries with git show before deciding that an ordinal such as HEAD@{1} is the state you want.
  5. Remember that reflog evidence is local; do not infer remote/shared history from it.
Work the recovery

Three situations where reflog is useful

Recover a commit after an accidental hard reset

Scenario: You ran git reset --hard HEAD~2 on a private branch and then realized one of the discarded commits contained work you still need.

git reflog --date=local
git show HEAD@{1}
# once you identify the wanted commit
git branch recovery/reset-mistake <commit-sha>

Inspect the reflog first, then inspect candidate commits. Creating a recovery branch preserves the discovered commit without moving your current branch again. Only after the work is safely reachable should you decide whether to cherry-pick, merge, reset, or keep the recovery branch.

Find the pre-rebase branch tip

Scenario: A completed rebase produced the wrong history and you want to inspect the feature branch tip from before the rewrite.

git reflog show feature/login
git show feature/login@{1}
git branch recovery/pre-rebase feature/login@{1}

The branch reflog records recent movements of that local ref. The exact entry number depends on what else happened, so read the reflog instead of assuming @{1} is always the pre-rebase state.

Investigate an approximate earlier state by time

Scenario: You remember that main pointed to the desired local state yesterday afternoon, but several operations happened afterward.

git reflog show --date=local main
git show main@{yesterday}

Date selectors are revision syntax interpreted against the local reflog. Treat the result as a candidate to inspect—not as proof that every clone or remote had the same state at that time.

Preserve before rewriting

Turn a reflog candidate into durable recovery evidence

The safest sequence is inspect → preserve → verify → reintegrate. Avoid jumping directly from “I found a SHA” to another hard reset.

  1. Read the movement timeline

    Find the reset, rebase, checkout, amend, or other movement around the moment the work disappeared.

    git reflog --date=local
  2. Inspect the candidate

    Review the commit and patch before changing any refs.

    git show <candidate-sha>
  3. Preserve it

    Create a normal branch so the candidate is no longer dependent on reflog reachability alone.

    git branch recovery/lost-work <candidate-sha>
  4. Compare with current state

    Use log/diff to understand whether you need the whole branch tip or only selected commits.

    git log --graph --oneline --decorate --all
    git diff HEAD...recovery/lost-work
  5. Reintegrate deliberately

    Choose merge, cherry-pick, reset, or another operation only after you can explain the desired final graph.

Failure modes

Mistakes that make recovery harder

Treating reflog as a shared or remote audit trail

Reflogs describe ref updates in this local repository. A teammate, CI clone, or remote server may have different reflogs or none of the entries you are relying on.

Safer move: Use reflog to recover local reachability, then record important recovered work in normal commits/branches and push it if it needs durable shared history.

Resetting immediately to the first plausible entry

A reflog can contain checkouts, rebases, commits, resets, amendments, and other movements. Moving HEAD again before inspecting the candidate can make the recovery harder to reason about.

Safer move: Use git show or create a temporary recovery branch at the candidate SHA first. Preserve evidence before changing more state.

Using reflog as a backup strategy

Reflog entries can expire and are local implementation metadata. They are a useful safety net, not a substitute for committed, pushed, or otherwise backed-up work.

Safer move: Once valuable work is recovered, make it reachable from a normal branch/tag/commit and push or back it up according to the project workflow.

Running reflog cleanup during an active recovery

expire, delete, and drop remove recovery evidence. They solve maintenance problems, not uncertainty about where your work went.

Safer move: Do not prune reflog information while investigating lost work. First identify and preserve the commits you need.

Practice

Recover a local branch tip without resetting twice

You accidentally ran git reset --hard HEAD~1 on a private branch. What is the safer first recovery sequence if you are not yet certain which reflog entry contains the lost commit?

Hint

Do not reset again. Inspect the reflog, inspect the candidate commit, then give it a durable branch name.

Reveal the tutor answer
git status
git reflog --date=local
git show <candidate-sha>
git branch recovery/reset-mistake <candidate-sha>

This sequence stops further state movement, uses the reflog only as evidence, verifies the candidate, and makes the recovered commit normally reachable before you decide how to integrate it.

Independent practice

In a disposable repository, create three commits, record the graph, then hard-reset the branch by one commit. Use reflog to find the old tip, inspect it, create a recovery branch, and compare the two lines. Repeat with a small rebase and locate the pre-rebase tip. Finish by explaining why reflog helped locally but would not replace pushing a real backup branch.

Clarify

Questions worth answering before relying on reflog

Is git reflog the same as git log?

No. git log walks commit history. Reflog records local movements of refs such as HEAD or a branch, including movements caused by reset, rebase, checkout, commit, and other operations.

Can reflog recover a commit after git reset --hard?

Often, if the earlier commit is still present and the relevant reflog entry has not expired. Inspect the reflog and candidate commit first, then create a recovery branch or otherwise make the commit reachable before doing more destructive work.

Does the remote have my reflog?

Do not assume so. Reflogs are local to the repository that recorded the ref movement. Use normal pushed branches/tags/commits for shared durable history.

What does HEAD@{2} mean?

It refers to an earlier entry in HEAD’s local reflog. The number is positional in that reflog, so inspect git reflog instead of assuming a fixed meaning such as “two commits ago.”

How long do reflog entries last?

Git has reflog-expiration policies and entries are not permanent. Exact retention can depend on repository configuration and reachability, which is why reflog should be treated as a recovery aid rather than a backup guarantee.

Next step

Use reflog to preserve evidence, then choose the recovery command by intent.

Once the old state is safely reachable, decide whether the goal is history movement (reset), path restoration (restore), history-preserving undo (revert), selective replay (cherry-pick), or temporary work storage (stash). Reflog helps you find the state; it does not choose the final graph for you.