Git Course 0%

git reflog

Advanced Git CLI Safe ≈ 6 min

Summary: git reflog lists every position HEAD has held in this clone, newest first, with what moved it. It is how you find a commit that git log can no longer see.

Safe — it only reads. Nothing in this command changes anything.

What it does

Prints the reference log: a local record Git writes every time HEAD or a branch moves, whether by commit, checkout, merge, rebase, reset or pull. Each line gives the hash the reference pointed at afterwards, a position such as HEAD@{2}, and the action.

Why it exists

Branches are pointers, and pointers move. Without a record of where they have been, a git reset --hard would leave a commit with no way to name it. The reflog is that record, and it is the reason a committed change is almost never lost.

When to use it

  • After a reset, rebase or amend removed something you wanted.
  • To find a deleted branch's last commit.
  • To answer "where was main yesterday?".
  • Before any risky operation, to note the current position.

When not to use it

  • To find work you never committed. The reflog holds commits; uncommitted edits were never recorded.
  • To find what a colleague did. It is local to your clone and is never pushed or fetched.

Syntax

Form Effect
git reflog The log for HEAD
git reflog show <branch> The log for that branch, as <branch>@{n}
git reflog --date=relative Show "2 hours ago" instead of positions
git reflog -20 Limit the number of entries
main@{yesterday} Valid anywhere a commit is expected
git reflog expire --expire=now --all Delete entries; almost never what you want

Examples

Find a commit removed by a reset:

Terminal
$ git reflog
b81702c HEAD@{0}: reset: moving to HEAD~1
d3b92ec HEAD@{1}: checkout: moving from docs/12-windows-install-steps to main
95a0014 HEAD@{2}: commit: docs: add Windows steps to installation guide (#12)
d3b92ec HEAD@{3}: checkout: moving from main to docs/12-windows-install-steps
d3b92ec HEAD@{4}: commit: chore: add CI configuration and contributing guide

HEAD@{2} is the commit that git log no longer shows. Bring it back:

Terminal
$ git reset --hard HEAD@{1}
HEAD is now at d3b92ec chore: add CI configuration and contributing guide

Or give the lost commit a branch instead, which is safer:

Terminal
$ git branch rescue/windows-steps 95a0014

One branch's history:

Terminal
$ git reflog show main
d3b92ec main@{0}: reset: moving to ORIG_HEAD
28593d2 main@{1}: reset: moving to HEAD~2
d3b92ec main@{2}: reset: moving to HEAD@{1}
b81702c main@{3}: reset: moving to HEAD~1
d3b92ec main@{4}: commit: chore: add CI configuration and contributing guide

Expected result

A list, newest first. Nothing changes; the command is a lookup.

Common mistakes

  • Expecting it on the server. It is local by definition.
  • Counting HEAD@{n} instead of reading the messages. The message names the action, which is a far more reliable way to identify the entry you want.
  • Waiting. Entries expire after about ninety days, and unreachable commits are collected after that.
  • Running git gc --prune=now while recovering, which removes the objects you are looking for.
  • Assuming it covers uncommitted work.

How to undo or recover

Nothing to undo. If a recovery attempt went wrong, the attempt is itself in the reflog: run it again and pick an earlier entry.

In VS Code

No reflog view. Use the built-in terminal.

In IntelliJ IDEA

No direct reflog view either, but Git → Recent Branches covers the common case of returning to a branch, and Local History covers work Git never saw, which the reflog cannot help with.

git reset to move a branch to an entry you found · git branch to name a rescued commit · git log for reachable history · git show to inspect a candidate hash.

Lessons that use this command

The safety net and the reflog · Recover files, branches, commits · Force push.

Key terms

Reflog HEAD Commit Hash (SHA)