Skip to main content
RunBook Academy

Git, CI/CD & GitOpsXVII · ReflogNavigation

Navigation with reflog — @{N}, @{date}, and using reflog as a history of HEAD

Advanced⏱ ~22 mingit

What you'll learn

  • Use the @{N} and HEAD@{N} reflog selectors to address prior states of HEAD
  • Use date-based selectors like @{yesterday} and @{2.days.ago} for time-based navigation
  • Combine reflog selectors with reset, switch, and checkout to navigate or recover
  • Distinguish @{N} (reflog-relative) from ~N (commit-relative) and ^N (parent)

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

The reflog’s primary operational use is navigation: it lets the engineer address prior states of a ref by ordinal position or by date. The selectors @{N}, HEAD@{N}, @{yesterday}, and HEAD@{2.days.ago} resolve to specific commits in the reflog and can be passed to any command that takes a revision — git reset, git checkout, git diff, git log. Combined with the recovery commands from lessons 4 and 5, the reflog selectors are the navigational layer that makes the reflog actionable.

The @{N} selector

@{0} is the current value of HEAD (the same as HEAD). @{1} is the previous value (the OID HEAD pointed at before the most recent update). @{2} is the value before that, and so on.

git reflog -3
# 9a8b7c6 HEAD@{0}: commit: bump terraform module
# 4d2c8e0 HEAD@{1}: commit: update iam policy
# 8a3f9d2 HEAD@{2}: checkout: moving from main to feature/iam

git show HEAD@{1}
# commit 4d2c8e0
# Author: ...
#     update iam policy

git diff HEAD@{2} HEAD
# diff between the commit at HEAD@{2} and the current tip

HEAD@{N} and @{N} are equivalent in the common case. The explicit form is required only when the command’s position parser would otherwise bind @{N} to a different ref.

flowchart LR
    A["HEAD@{0} = current"] --> B["HEAD@{1} = previous"]
    B --> C["HEAD@{2} = before that"]
    C --> D["HEAD@{N} = N updates ago"]

Date-based selectors

@{<date>} resolves to the most recent reflog entry at or before the given date. The date can be a relative phrase, an ISO date, or a Unix timestamp.

git show @{yesterday}
# shows the commit HEAD pointed at most recently as of yesterday

git show @{2.days.ago}
# shows the commit HEAD pointed at most recently two days ago

git show @{"2026-08-19 14:00"}
# shows the commit HEAD pointed at most recently at the named time

The date selector walks the reflog from newest to oldest and returns the first entry whose timestamp is at or before the named time. If no entry exists at or before that time, the selector fails with an error.

The relative phrases supported include yesterday, 1.day.ago, 2.weeks.ago, 3.hours.ago. The full grammar is in git help revisions under “Reflog selectors”.

Combining reflog selectors with commands

The selector is just a revision; it works anywhere a revision is accepted.

# Reset to the previous state of HEAD (soft: keep working tree)
git reset --soft HEAD@{1}

# Reset to a previous state and discard working tree changes
git reset --hard HEAD@{1}

# Switch to a previous state in detached HEAD mode (for inspection)
git switch --detach HEAD@{1}

# Diff working tree against the state two commits ago
git diff @{2}

# Cherry-pick a commit the engineer remembers making yesterday
git cherry-pick @{yesterday}

The reset and cherry-pick combinations are the recovery patterns covered in the next two lessons. The switch --detach and diff combinations are diagnostic patterns: inspect a prior state without committing to it, then git switch - back to the previous branch.

@{N} versus ~N versus ^N

Three selectors look similar but resolve differently:

  • HEAD@{N} — the Nth most recent state of HEAD, as recorded in the reflog. Resolves to a commit OID.
  • HEAD~N — the Nth ancestor of HEAD, walking first parents only. Resolves to a commit OID.
  • HEAD^N — the Nth parent of HEAD. For a merge commit, HEAD^2 is the second parent.
# Three different ways to write "two commits ago" — usually the same:
git show HEAD@{2}
git show HEAD~2
git show HEAD^^

# But they differ at the start of a rebase:
# HEAD@{1} might point at the pre-rebase tip, while
# HEAD~1 points at HEAD's parent (which is the first replayed commit)
flowchart LR
    A["HEAD@{N}"] --> A1["N updates ago\n(reflog ordinal)"]
    B["HEAD~N"] --> B1["N first-parent ancestors\n(history traversal)"]
    C["HEAD^N"] --> C1["Nth parent\n(merge parents)"]

The rule of thumb: @{N} is time-based (when was HEAD last at this OID), ~N is history-based (walk back through the DAG), ^N is parent-based (which parent of a merge). Production engineers default to ~N for “back through the history” and reach for @{N} only when the reflog is the authoritative record (recovery scenarios, time-based diagnostics).

Using reflog for navigation without recovery

The reflog is useful even when nothing has gone wrong. Common non-recovery uses:

  • “What did I have on this branch yesterday?”git diff @{yesterday} answers the question without changing branches.
  • “When did I last touch this file?” — combine with git log -g -- <path> to walk the reflog as if it were history.
  • “What was the tip of main three days ago?”git log main@{3.days.ago} shows the tip at that time.

The -g (or --walk-reflogs) flag makes git log walk the reflog instead of the commit graph. The reflog has a chain shape (each entry is an update event), so git log -g shows the chronological history of HEAD movements rather than the DAG history of commits.

git log -g --oneline
# 9a8b7c6 HEAD@{0}: commit: bump terraform module
# 4d2c8e0 HEAD@{1}: commit: update iam policy
# 8a3f9d2 HEAD@{2}: checkout: moving from main to feature/iam

Production discipline

  1. Default to HEAD@{N} for “the prior state of HEAD”. The selector is unambiguous and matches the recovery pattern in lesson 4.
  2. Use date selectors for diagnostics, not recovery. HEAD@{2.days.ago} is a fine way to ask “what was I working on Tuesday?” but a recovery recipe should pin to an ordinal @{N} so the recipe is repeatable.
  3. Combine reflog selectors with --walk-reflogs (-g) for chronological views. git log -g -- <path> shows when a path was last touched, which git log -- <path> cannot answer directly.
  4. Verify before destructive commands. git reset --hard HEAD@{1} is the recovery; git diff HEAD@{1} HEAD first shows what will be lost.

Cross-course references

  • Git, CI/CD & GitOps — Part V (Branches, Refs and HEAD) — Part V lesson 4 covered detached HEAD state; the switch --detach HEAD@{N} pattern is the same idea applied to a reflog-relative commit.
  • Git, CI/CD & GitOps — Part XV (Reset) — the recovery recipes in lesson 4 use HEAD@{N} to address the pre-reset state.
  • Linux for Production Sysadmins — Part XXVII (Backup and Recovery) — reflog selectors are the Git analogue of find -mtime -3: a time-based recovery primitive for a different storage layer.

Quiz

Knowledge check · 4 questions

  1. Q1. Which command addresses the state of HEAD two updates prior to the current state, as recorded in the reflog?

  2. Q2. The reflog selector `@{yesterday}` resolves to the most recent state of HEAD at or before yesterday, and fails with an error if no reflog entry exists at or before that time.

  3. Q3. State the difference between `HEAD@{N}`, `HEAD~N`, and `HEAD^N`, and give one scenario where they resolve to different commits.

  4. Q4. Choose the correct reflog selector and command combination for three time-relative and history-relative queries against an engineer's last day of work.

    An engineer worked on `feature/iam-rotation` yesterday from 14:00 to 17:30, made three commits, and switched to `main` at 17:45. Today at 10:00 the engineer asks three questions: (a) 'what did `feature/iam-rotation` point at when I last touched it?' (b) 'show me the diff between the working tree and where I was at 16:00 yesterday' (c) 'restore the branch tip to the state it was in at 17:30 yesterday'.

Passing score: 75%. Answers are checked in this browser.