Advertisement

Git branches intimidate people far more than they should, largely because the word "branch" implies something big and physical — a copy of the whole project you might damage. The truth is almost anticlimactic: a branch in Git is just a lightweight, movable pointer to a single commit. Internalise that one sentence and half of Git's apparent mystery evaporates.

Everything Git does with branches — creating, switching, merging, the dreaded detached HEAD — makes immediate sense once you picture commits as a chain and branches as sticky labels you move along it.

Commits form a chain; branches label it

Each commit is a snapshot that points back to its parent, forming a chain (really a graph) of history. A branch is nothing more than a named pointer to one commit in that graph — usually the latest on that line of work. Create a new branch and Git simply writes a new label pointing at your current commit; it copies nothing. That is why branching in Git is instant even on huge projects.

When you make a new commit on a branch, Git moves that branch's label forward to the new commit. The branch "grows" not by copying but by the pointer advancing along the chain of history.

Advertisement

HEAD and "detached HEAD"

HEAD is Git's pointer to "where you are right now" — normally it points at a branch, which points at a commit. When you switch branches, you are really just moving HEAD to point at a different label. The alarming "detached HEAD" state simply means HEAD is pointing directly at a commit instead of at a branch label — you are looking at history without a branch to catch new commits.

It sounds like damage and is not; it is just a warning that commits made here have no branch label, so they could be lost when you move away. Create a branch to keep them, and detached HEAD becomes a non-event.

Merging and rebasing, demystified

Merging combines two lines of history by creating a new commit with two parents, tying the branches together while preserving what happened. Rebasing instead replays your branch's commits on top of another branch, producing a cleaner straight-line history at the cost of rewriting those commits. Both are just operations on the graph of commits and the pointers into it — not magic, and not dangerous once you can picture the shapes.

The whole fear of Git tends to come from treating it as an opaque set of incantations. Replace that with the mental model — commits are a chain, branches and HEAD are movable labels — and commands you once copied nervously become obvious moves on a structure you can see in your head.