Q34 of 40 · Git
Explain `git reflog` — what it records, for how long, and walk through a scenario where it saves a QA engineer's work.
Short answer
Short answer: `git reflog` records every position HEAD (and every branch ref) has been at, even after resets, rebases, and branch deletes. Entries are kept for 90 days (reachable) or 30 days (unreachable) by default. It's the universal undo for any local destructive operation.
Detail
What reflog records: every time HEAD moves — commit, checkout, rebase step, reset, merge, cherry-pick — Git appends a line to .git/logs/HEAD. Each entry shows the old and new SHA, the operation, and a timestamp. Branch-specific reflogs live in .git/logs/refs/heads/<branch>.
Retention policy: controlled by gc.reflogExpire (default 90 days for commits reachable from a branch tip) and gc.reflogExpireUnreachable (default 30 days for commits not reachable from any ref). These are the commits most at risk of being pruned.
Scenario — accidental hard reset:
A QA engineer spends two hours writing 4 commits of integration tests. They run git reset --hard HEAD~4 thinking they're on a throw-away branch, but they're actually on feature/payment-tests. Those 4 commits are now unreachable — but still in the object store. git reflog shows the SHA before the reset (HEAD@{1}). Running git reset --hard HEAD@{1} instantly restores all four commits.
Scenario — deleted branch:
git branch -D feature/old-tests deletes the branch pointer, but the commits are still in the object store. git reflog shows the last SHA on that branch. git switch -c feature/old-tests <sha> recreates the branch at that exact commit.
Limitation: reflog is local only — it is not pushed or cloned. A freshly cloned repo has an empty reflog. This is why pushing to a remote is the only true backup.
// EXAMPLE
# View HEAD reflog (most recent first)
git reflog
# HEAD@{0}: reset: moving to HEAD~4
# HEAD@{1}: commit: test: add OrderIntegration retry assertions ← want this
# HEAD@{2}: commit: test: add OrderIntegration happy path
# HEAD@{3}: commit: test: add OrderIntegration setup
# HEAD@{4}: commit: test: OrderIntegrationTest skeleton
# Restore lost commits after accidental --hard reset
git reset --hard HEAD@{1}
# View reflog for a specific branch
git reflog show feature/payment-tests
# Recover a deleted branch
git reflog | grep "feature/old-tests"
# HEAD@{12}: checkout: moving from feature/old-tests to main
git switch -c feature/old-tests HEAD@{12}
# Reflog with timestamps (useful for time-based recovery)
git reflog --date=iso
# Expire unreachable reflog entries manually (dangerous!)
git reflog expire --expire-unreachable=now --all # don't run lightly// WHAT INTERVIEWERS LOOK FOR
// Related questions
Your local Git repository is reporting corrupted objects or a detached HEAD you can't escape. How do you diagnose and recover?
Git
A teammate accidentally force-pushed to `main` and lost 3 commits that were never backed up. How do you recover them?
Git
Explain the three modes of `git reset` — `--soft`, `--mixed`, and `--hard` — with concrete use cases for each.
Git