git reflog
advancedEverything you did — even the things you rewrote away.
git reflogWhat it does
git reflog is the undo-of-the-undo. It's a journal of every time HEAD moved: commits, resets, rebases, checkouts, amends — each logged as an entry with the previous and new position. Because it records what refs USED to point at, you can recover history git log no longer sees.
Every HEAD movement is journaled — scroll the list, never lose a commit
Watch it — press play
A narrated, step-by-step walkthrough that shows how to do it — not just theory. It adapts to the learner mode you picked in the top bar.
Step 1
The undo stack
Every time HEAD moves — commit, reset, rebase, checkout, amend — git journals it. git reflog prints that journal.
git reflogHEAD@{n} = where you were n moves ago
Under the hood
A reflog is just a log file
Git appends one line per ref movement to .git/logs/HEAD. Each line records old-hash, new-hash, who, when, and why. No commits are deleted at reset time — only the reflog still remembers the old pointer.
0000000 9a2f1c0 Ada <ada> 12:01 init: Repository created 9a2f1c0 4b7c2a5 Ada <ada> 12:04 commit: add components 4b7c2a5 74d3b9f Ada <ada> 12:07 commit: feat: dark mode 74d3b9f 9a2f1c0 Ada <ada> 12:09 reset: moving to HEAD~2
An 'old' commit stays until GC
Commits that lose all refs become unreachable. Git keeps them alive for up to 90 days (default) before git gc prunes them — so reflog recovery works even days later.
Entry syntax: HEAD@{n}
HEAD@{0} is 'now', HEAD@{1} is the previous HEAD position, and so on. You can also address by time: HEAD@{yesterday}, HEAD@{2.hours.ago}.
Aliases the pros type
Memorize the git reflog concept, then let one of these shortcuts make it instant. Aliases are real git config keys — add one with:
git config --global alias.st # → git reflogg rlgit reflogThe shortest rescue alias you'll ever need.
g rlggit reflog --onelineCompact, one-line reflog view.
Command anatomy
--allShow reflogs for every ref, not just HEAD.
-n <count>Show only the most recent n entries.
--since=Filter entries by the time they happened.
When to reach for it
Hard-reset the wrong way? `git reset --hard HEAD~3` — recover with `git reset --hard HEAD@{1}`.
Rebased a branch and realized the original had the commit you need.
Diagnosing 'where did that commit go?' when a coworker force-pushed over your branch.
Pro tip
The '#undo stack' mental model is exactly right: HEAD@{n} behaves like an undo history. After any destructive operation, the fix is typed as `git reset --hard HEAD@{1}`