What is a ref
A ref is a name that points to an object — usually a commit. Branches are refs under refs/heads/, tags under refs/tags/, remote-tracking under refs/remotes/, and pseudo-refs like HEAD, FETCH_HEAD, ORIG_HEAD live at the root of .git. Internally, refs are either loose files or entries in .git/packed-refs.
Inspecting refs
git for-each-ref
git for-each-ref --sort=-committerdate --format='%(refname:short) %(committerdate:relative)' refs/heads
git symbolic-ref HEAD
git update-ref refs/heads/foo <sha>
git update-ref is the plumbing way to move a branch atomically.
The reflog
Every change to a ref is logged: branch tip moves, commits, resets, rebases, fetches. The reflog is a per-clone safety net independent of the object graph.
git reflog
git reflog show feature
git reflog show HEAD@{2.weeks.ago}
git log -g --oneline
Recover a "lost" commit by referencing the reflog entry:
git checkout HEAD@{1}
git branch rescue HEAD@{5}
Reflog expiration
Reflog entries are subject to expiry: gc.reflogExpire (default 90 days) for reachable, gc.reflogExpireUnreachable (30 days) for unreachable. After expiry, gc may prune the underlying objects.
git config gc.reflogExpire never
git config gc.reflogExpireUnreachable 60.days
Special pseudo-refs
HEAD points to the current branch (or directly at a commit when detached). ORIG_HEAD records the previous tip before destructive ops like merge, rebase, reset. FETCH_HEAD records the last fetched tip(s). MERGE_HEAD exists during a merge in progress. See "The ORIG_HEAD, FETCH_HEAD, and other special refs".
Reftable backend
Modern Git supports the reftable ref storage backend, designed for repos with hundreds of thousands of refs (used internally by JGit). Enable on init:
git init --ref-format=reftable
Common mistakes
Trusting reflog forever: it expires. Tag or branch important recoveries promptly. Editing .git/refs/ by hand: use git update-ref for atomicity. Confusing HEAD@{2} (reflog index) with HEAD~2 (commit ancestry); they mean very different things.
Related
See "Git internals: the object database" and "Git internals: packfiles and delta compression".