Introduction
HEAD is the most important reference in Git. It tells Git which commit your next commit will descend from. Most of the time HEAD points at a branch, and that branch points at a commit; but HEAD can also point directly at a commit (detached HEAD).
Where it lives
HEAD is a single file at .git/HEAD. Inspect it:
cat .git/HEAD
# ref: refs/heads/main
That single line says "HEAD currently points at the branch main". When you commit, Git advances main and HEAD follows.
Inspecting HEAD
git rev-parse HEAD # commit SHA
git symbolic-ref HEAD # underlying ref name
git log -1 HEAD --oneline
Detached HEAD
Checking out a commit, tag, or remote-tracking branch directly puts HEAD in detached state:
git checkout v1.2.3
# You are in 'detached HEAD' state.
.git/HEAD now contains a raw SHA. New commits go nowhere except into the reflog; switch back to a real branch (or create one) before you lose them:
git switch -c experiment
HEAD shorthands
HEAD: the current commit.HEAD^orHEAD~1: parent.HEAD~3: three commits back via first parent.HEAD^2: second parent of a merge commit.HEAD@{1}: previous position from the reflog.
git log HEAD~5..HEAD --oneline
git diff HEAD^ HEAD
Other special HEADs
ORIG_HEAD: previous HEAD before a "dangerous" operation (merge, reset).MERGE_HEAD: tip of the branch being merged.FETCH_HEAD: tip of whatever was just fetched.CHERRY_PICK_HEAD: commit being cherry-picked.
HEAD in scripts
Scripts often need to know the current branch name. Use plumbing rather than parsing porcelain output:
branch=$(git symbolic-ref --short -q HEAD) || branch="(detached)"
sha=$(git rev-parse HEAD)
short=$(git rev-parse --short HEAD)
symbolic-ref --short -q HEAD exits non-zero in detached state, which makes it a perfect detector. git branch --show-current (Git 2.22+) is a friendlier alternative that prints empty output when detached. Both are stable across versions; git status output is not.
HEAD and worktrees
Linked worktrees each have their own HEAD. The main repository's .git/HEAD is one of many; each worktree has its own under .git/worktrees/<name>/HEAD. This means two worktrees of the same repository can be on different branches simultaneously:
git worktree add ../wt-feature feature/login
git -C ../wt-feature rev-parse HEAD
git -C . rev-parse HEAD
The two HEADs are independent. Branch checkout is exclusive across worktrees: a branch can only be checked out in one worktree at a time, preventing accidental concurrent edits to the same branch from two locations.
Common mistakes
Believing that HEAD is a synonym for "current branch". It is not; it is a pointer that usually points at one. Treating HEAD~3 and HEAD^3 as equivalent: they differ on merge commits. Editing .git/HEAD by hand to switch branches; use git switch or git checkout instead. And finally, ignoring "detached HEAD" warnings and committing into the void; if you find yourself there with new commits, do git switch -c <newbranch> immediately to anchor them.