Learning Objectives
By the end of this lesson you will be able to:
- Read every column of
git reflogoutput and know what each means - Identify the operation that lost your work by its action name
- Inspect a candidate commit before recovering it
- Filter the reflog when it is too long to scan
The Output, Column by Column
git reflog
d4a91e0 (HEAD -> main) HEAD@{0}: reset: moving to origin/main
8f3c2a1 HEAD@{1}: rebase (finish): returning to refs/heads/test/PAY-4417
4c1f8ab HEAD@{2}: rebase (pick): test: add refund boundary cases
1a77c60 HEAD@{3}: commit: test: extract payment fixture builder
e2b90d1 HEAD@{4}: checkout: moving from main to test/PAY-4417
Four parts to each line:
The commit ID. Where HEAD ended up after this operation. This is the one you will pass to git reset or git branch.
The HEAD@{n} reference. A usable alias for that commit, valid anywhere Git accepts a commit ID. {0} is now; larger numbers go further back.
The action name. commit, checkout, reset, merge, rebase (pick), pull, clone, cherry-pick. This is what tells you what happened.
The description. The commit subject for a commit, the branch names for a checkout, the target for a reset.
Finding the Moment It Went Wrong
Reading a reflog to recover something is a two-step process. First, find the operation that lost the work:
d4a91e0 HEAD@{0}: reset: moving to HEAD~3 ← the mistake
1a77c60 HEAD@{1}: commit: test: add timezone cases
9d3e072 HEAD@{2}: commit: test: add currency cases
7b2e551 HEAD@{3}: commit: test: extract fixture
Then take the entry directly below it — HEAD@{1} here. That is where the branch stood immediately before the operation ran, which is what you want back.
That is the whole method. The rule "one line below the mistake" covers almost every recovery in this module.
Verifying Before You Act
Never reset to a reflog entry you have not looked at. Two commands:
git show 1a77c60
The full commit — message, author, diff. Confirms you have the right one.
git log --oneline 1a77c60 -5
The five commits leading up to it. This is the better check, because it shows the branch state, not just one commit. If those five look like the branch you remember, you have found it.
When the Reflog Is Long
A busy day produces hundreds of entries. Three ways to narrow it.
Filter by branch:
git reflog show test/PAY-4417
Only the moves of that branch, which is far shorter than every move of HEAD.
Filter by action:
git reflog | grep commit:
Just the commits, skipping every checkout and rebase step. grep reset: and grep 'rebase (start)' are similarly useful.
Filter by time:
git reflog --date=iso
d4a91e0 HEAD@{2026-08-31 14:22:07 +0300}: reset: moving to HEAD~3
1a77c60 HEAD@{2026-08-31 14:19:41 +0300}: commit: test: add timezone cases
When you know roughly when things went wrong, this is the fastest way in. --date=relative gives "2 hours ago" style output, which is often more natural.
Reading Multi-Step Operations
A rebase writes many entries, and knowing the shape helps:
d4a91e0 HEAD@{0}: rebase (finish): returning to refs/heads/test/PAY-4417
d4a91e0 HEAD@{1}: rebase (pick): test: add timezone cases
4c1f8ab HEAD@{2}: rebase (pick): test: add currency cases
e2b90d1 HEAD@{3}: rebase (start): checkout origin/main
1a77c60 HEAD@{4}: commit: test: add timezone cases ← the branch before the rebase
rebase (start) marks the beginning. The entry below it is the pre-rebase branch — the same "one line below" rule, applied to a whole operation rather than a single command.
This is what ORIG_HEAD points at, incidentally. git reset --hard ORIG_HEAD and git reset --hard HEAD@{4} are the same thing here; ORIG_HEAD is just the convenient name that survives only until the next big operation.
Pro Tip: When you have found a promising entry, tag it before doing anything else:
git branch recovery/attempt-1 HEAD@{4}. Now it has a permanent name, it cannot be lost while you experiment, and you delete it once you are sure.
Key Takeaways
- Each reflog line is: resulting commit ID,
HEAD@{n}, the action, and a description - The action name identifies what happened —
commit,reset,rebase (pick),checkout - To recover, find the operation that lost the work and take the entry directly below it
- Verify with
git log --oneline <sha> -5before resetting to it - Narrow a long reflog by branch, by
grepon the action, or with--date=relative - A rebase writes
start…pick…finish; the entry belowstartis the pre-rebase branch - Give a promising commit a branch name immediately so it cannot be lost again