References: Branches, Tags, and HEAD
October 30, 2026
References: Branches, Tags, and HEAD
After this page you can say what a ref is, where it lives, and how HEAD relates to a branch.
A ref is a name for a hash
A ref (reference) is a name that points at a commit (or, for annotated tags, at a tag object). Git stores them as files under .git/refs/ and, when there are many, in .git/packed-refs.
| Ref | Typical path | Meaning |
|---|---|---|
| Branch | .git/refs/heads/main |
Movable name for a line of work |
| Tag | .git/refs/tags/v1.0 |
Name meant to stay put |
| Remote-tracking | .git/refs/remotes/origin/main |
Last-seen tip of a branch on a remote |
| HEAD | .git/HEAD |
Where you are |
git rev-parse turns a name into a hash. Use it when a diagram and the disk disagree in your head.
Branches move, tags mostly do not
git branch # local branches
git branch feature # new name at current HEAD
git switch feature # HEAD now points at feature
git switch -c hotfix # create and switchgit switch is the modern command for changing branches (git checkout still works; this book uses switch for branches and restore for files).
A tag is a bookmark:
Moving a published tag surprises people who already fetched it. Moving a branch is normal.
HEAD is usually a pointer to a pointer
.git/HEAD → ref: refs/heads/main
.git/refs/heads/main → a1b2c3d4….
Commit while on main: Git writes a new commit whose parent is a1b2c3d4…, then overwrites refs/heads/main with the new hash. HEAD did not change its text; the branch it names did.
Detached HEAD: .git/HEAD contains a raw hash instead of ref: refs/heads/…. You get there with git switch --detach, or by checking out a tag. To keep work from a detached HEAD:
That creates a branch at the current commit and attaches HEAD to it.
Remote-tracking names
After you add a remote named origin and fetch (chapter 11):
refs/remotes/origin/main
That is your last photograph of main on that remote. It updates on fetch. You do not commit onto it. Your local main is a separate name you push.
Plumbing vs porcelain
git branch, git switch, git tag are porcelain (human commands). git update-ref and git symbolic-ref are plumbing (the same operations, no sugar). This book stays on porcelain until internals (chapter 16). Knowing refs are files is enough to understand why creating a branch is cheap: Git writes a 41-byte file.