Every Commit Names Its Parent, and a Branch Is One Line in a File
Last timeA Snapshot, Not a Change
A commit holds its parent's name inside the bytes that give the commit its own name, which makes history a graph, a branch a 41 byte file, and a rewrite unavoidably a set of new commits.
What is actually inside a commit
Everything in the store is named by a fingerprint of its own contents, and a
commit is no exception to that. So the useful question is not what a commit
means but which bytes it is made of, because the name is a function of those
bytes and of nothing else.
The repository behind these examples has three files, four commits on the main
line, and a side line of three commits that branches off the second. Here is the
third commit on the main line, read straight back out of the store.
$ git cat-file -p 2c74519
tree f4db054a3709a8b5298a1e007e884b08c6e85a7b
parent 5c79a65d0318ae221e939eddc831adc7952477c6
author A Writer <[email protected]> 1767603600 +0000
committer A Writer <[email protected]> 1767603600 +0000
Raise the default width
$ git cat-file -s 2c74519
230
$ (printf 'commit 230\0'; git cat-file commit 2c74519) | shasum
2c74519cfeecfef02a58771338350ba0abe652db -
$ old=5c79a65d0318ae221e939eddc831adc7952477c6
$ new=6f74b130bc453e3eac1436ca41795df6c3d5e583
$ git cat-file commit 2c74519 | sed s/$old/$new/ | git hash-object -t commit --stdin
0ca058495cfc9d00ed6334e5c60410802f9a09c3Six lines of content and that is the entire object. The first names a tree,
which is the whole directory as it stood at that moment. The second names the
parent, which is the commit this one came after. Then two identity lines, a
blank line, and the message.
Read the list again for what is missing. There is no record of which files
changed. There is no difference against anything. And there is nothing pointing
forwards, no field naming the commits that came later, because at the moment
those 230 bytes were written the later commits did not exist and this name was
already settled.
Those three absences are the whole of what follows. Branching, merging and
rewriting all behave the way they do because a commit has exactly one backward
link and no forward one.
The parent is part of the name
The parent is not metadata hung off the side of a commit. It is 48 of the 230
bytes that go through the hash.
The lesson stops here
8 more paragraphs to go
You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.
The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.
See the planThe contentsThis is the reading half
Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.
The contents