Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Git Reflog: Reading the Local History of References

Learn how reflogs record local reference updates, how to inspect HEAD and branch reflogs, and how to use reflog-based revision names to identify earlier reference values.

Levels: Advanced ~35 min read

Advanced

Learner goal

By the end of this lesson, you should be able to inspect a reflog, distinguish a HEAD reflog from a branch reflog, resolve a reflog-based revision such as `main@{1}`, and explain why a reflog is local reference history rather than the commit graph itself.

text
reflog → local record of ref updates
HEAD reflog → also records branch switching
main@{1} → previous value of the local main ref

Quick check

What does a reflog primarily record?

A branch tip has moved locally.The reflog records the reference movement as a local entry.

A reflog is reference history, not commit history

Git already has a commit graph: commits point to parent commits. A reflog records changes to a reference's value over time. The same commit can therefore appear in a reflog more than once, and a reflog entry can describe a movement that did not create a new commit.

This distinction matters after operations such as reset, rebase, branch switching, or other reference updates. The reflog answers a question such as “what did this local reference point to earlier?” rather than “which commits are ancestors of this commit?”

bash
git log --oneline --decorate --graph -5
git reflog main -5

Quick check

Which statement correctly distinguishes a reflog from the commit graph?

You are comparing two kinds of history information.One shows reference movement; the other shows commit ancestry.

`git reflog` and `git reflog show` display the reflog for `HEAD` by default. The official documentation also specifies that the `HEAD` reflog records branch switching, which makes it useful for answering “where was HEAD immediately before this checkout?”

bash
git reflog
git reflog show HEAD -5
git reflog HEAD -5

Quick check

What extra kind of activity does the HEAD reflog record?

The learner switches from one branch to another.The HEAD reflog gains a checkout entry describing the move.

Inspect a branch reflog

A local branch can have its own reflog. `git reflog main` shows the local history of the `main` reference. A branch reflog changes when the branch tip changes; merely switching away from or back to the branch is recorded in the HEAD reflog, not as a movement of the branch tip itself.

bash
git reflog main -5
git reflog exists refs/heads/main

Quick check

After switching from `main` to `feature` without moving either branch tip, which reflog is expected to record the switch?

main and feature still point at the same commits as before the checkout.The HEAD reflog records the checkout event; the branch reflog tips have not moved.

Use reflog revision names

The official revision syntax lets you refer to an earlier value of a reference. `main@{1}` means the previous reflog value of `main`, while `HEAD@{2}` means the value HEAD had two reflog moves ago. A date form such as `main@{yesterday}` asks for the value of that local reference at the specified time, provided the reference has a reflog.

bash
git rev-parse 'main@{1}'
git show --no-patch --format='%H %s' 'main@{1}'
git rev-parse 'HEAD@{2}'

Quick check

What does `main@{1}` identify?

main currently points at commit C and its reflog has a prior value B.`main@{1}` resolves to the earlier value B.

Quick check

Why can `HEAD@{1}` and `main@{1}` resolve to the same commit in a simple repository?

HEAD is attached to main and main has just moved.Both revision names can resolve to the same commit object even though they refer to different refs.

Read a previous value after a reference move

A reflog becomes particularly useful when a reference has moved. In a disposable repository, you can move `main` backward with `git reset --hard`, then inspect `main@{1}` to identify the branch tip that existed immediately before that reset. This lesson stops at identification and inspection; the next curriculum lesson owns actual recovery of abandoned commits.

bash
before=$(git rev-parse HEAD)
git reset --hard HEAD~1
git reflog main -3
git rev-parse 'main@{1}'
git show --no-patch --format='%H %s' 'main@{1}'

Quick check

After a reset that moved `main` backward, what is the key use of `main@{1}`?

main has moved and the previous tip is no longer the current branch tip.The reflog still provides a revision name for the earlier local value.

Reflogs have an existence and retention boundary

`git reflog list` lists references that currently have corresponding reflogs, and `git reflog exists <ref>` tests whether a reflog exists. The official documentation also defines reflog expiration: reachable entries default to 90 days and entries that are unreachable from the current tip default to 30 days, through the corresponding `gc.reflogExpire` and `gc.reflogExpireUnreachable` settings.

bash
git reflog list
git reflog exists refs/heads/main
git config --get gc.reflogExpire
git config --get gc.reflogExpireUnreachable

Quick check

Why should you avoid treating a reflog entry as permanent storage?

The learner is planning recovery from an old local reference value.The correct expectation is that reflog retention is bounded by expiration policy.

Local scope matters

The official Git documentation describes reflogs as local repository information. A reflog therefore describes the reference movements known in that particular repository. It is not the shared commit history of all clones, and it should not be confused with a remote branch's history on another repository.

text
Repository A reflog  → records local ref movements in A
Repository B reflog  → records local ref movements in B
Commit graph          → shared by object transfer when commits are actually transferred

Quick check

What is the correct scope for a reflog?

Two repositories contain related commits but have different local reference movement histories.Each repository can have different reflog information because the logs are local.

Practice what you learned

Use the dedicated Git code-completion exercise for this lesson.

Quick check

What should your final verification prove?

The branch tip has been moved locally in a disposable repository.The reflog and revision selector identify the earlier branch tip without changing the remote or creating a new commit.

Official-source boundary

This lesson uses only official Git project documentation: `git-reflog` for reflog behavior and subcommands, `gitrevisions` for reflog-based revision syntax, and the official Git glossary/user manual for the local-history definition. The live official `gitrevisions` documentation is Git 2.56.0; the live `git-reflog` manual is unchanged through Git 2.56.0 and reports its last manual update in 2.51.1. Foxipa's local verifier is Git 2.47.3, so execution evidence is reported for that installed executable rather than silently generalized to every Git release.

Was this page helpful?

Mark this learning resource complete to track your learning progress.