Naming the hashes
The object database is complete but unusable by hand. Nobody types forty hex characters to describe where they are working.
A ref is a name for a hash. That is the entire concept, and it is stored the way it sounds:
$ cat .git/refs/heads/feature
cc8e3e195cca577668c7e26ac6524211c422c40f
A branch is a file whose contents are a commit hash. Forty-one bytes with the newline.
That one fact resolves most branch confusion. Creating a branch writes a file, which is why it is instant regardless of repository size. Deleting one removes a file, which is why the commits survive deletion. And a branch does not contain commits: it points at one, and the rest of history is reached by following parent links.
So the mental picture of a branch as a container, inherited from centralised systems where a branch was a directory copy, is wrong in a way that makes Git seem arbitrary. A branch is a bookmark.

