Git pretends to be a version-control tool, but underneath it's a tiny content-addressable filesystem. Learn the storage model and the porcelain commands stop being incantations.

Four objects, that's the whole store

A blob is file contents. A tree is a directory listing pointing at blobs and other trees. A commit points at one tree plus its parents. A tag names a commit. Everything is keyed by the hash of its content, so identical content is stored exactly once.

A branch isn't a thing — it's a 41-byte file containing a commit hash. That's why making one is instant and deleting one loses nothing but a pointer. HEAD is just a pointer to a pointer.

"Detached HEAD" stops being scary the moment you realize HEAD is a sticky note, not a place.

The payoff

Rebase, cherry-pick, reset — they're all just moving pointers and replaying commits onto a different parent. When a command confuses you, ask what it does to the objects and the refs. The answer is always smaller than the command made it look.