What is HEAD?
Where you are: the name for the commit your working copy was built from, and what detached means.
HEAD is Git’s name for where you are. It points at the branch you are on, and through the branch at a commit: the one your working copy was built from, and the one the next commit will have as its parent. Every diagram on these pages draws it, because most of what Git does is described in terms of it.
Switching branches is moving HEAD. Git rewrites the files on disk to match
the commit the new branch points at, which is why it refuses to switch over
uncommitted changes the switch would lose. HEAD points at main, so you are on main. The files on disk are C's. Switching to feature moves HEAD. The files on disk become D's. A commit goes where HEAD points. E's parent is D, and feature moves to E; HEAD follows, because it points at feature. Checking out a commit rather than a branch puts HEAD on B itself, with no branch under it. That is a detached HEAD. Switching to a branch attaches HEAD again. Nothing was lost by looking; a commit made while detached would have had no branch to keep it.
Detached, and why it is not an error
Looking at an old commit is a reasonable thing to want, and checking one out is how the command line does it: the working copy becomes that snapshot, and HEAD points at the commit itself. The state is called detached because no branch is under HEAD to move along with it. The one thing to know is what happens if you commit while detached: the commit is made, but no branch points at it, so once you switch away only the reflog remembers it. Make a branch first if the work is meant to be kept.
On the command line
git switch feature # move HEAD to a branch
git switch --detach B # put HEAD on a commit: detached
git status # "On branch main", or "HEAD detached at …"
Git’s own reference: git-switch, and HEAD in the glossary.
In Innesta
Moving HEAD between branches is the switcher on creating and switching branches, and the stash it offers when the switch would lose something is on switching with uncommitted work. The history can be scoped to a branch or a tag without checking anything out, which is usually the way to look at an old commit. Where HEAD has been is the reflog, and finding a commit that has disappeared reads it.
The Playground is a repository made for trying this on.