Does a branch identify a commit, or does a commit identify a branch?

A disparity between conceptual Git branching diagrams and actual Git branching diagrams

Here is a relatively famous picture illustrating some branches in a git repository:

In this diagram, each vertical line is supposed to be a branch. Each commit in the diagram sits on one of those vertical lines. Look at any other diagram that someone has made to illustrate how branching works in Git, and you’ll find the same thing. The idea is that every commit belongs to a particular branch. This is how we think and talk about branches in Git.

But it is a lie, isn’t it? Because in the Git data model, a branch is just a pointer to a commit. The model is not that every commit has a property that identifies a branch; it’s that every branch has a property that identifies a commit.

One way to see the incorrectness of the ‘intuitive’ model is to observe that you can have two branches pointing to the same commit. How would we draw this in the above diagram?

Another way is to observe that the initial commit in the repository must be on all branches; not just on the master branch.

Can we recover the intuitive diagram from the Git data model? I can think of three sources to do so:

  • Git commit parents are an ordered list?
  • Git merges say what branch they merged from, if they merged a branch.
  • Git reflog gives us the local history of a branch pointer.