ReadbackLesson 01In progress
2 steps · 25 minutes · one terminal

WHAT A COMMITACTUALLY IS

Every confusing thing git does later — rebase, squash, force-push, “lost” work — falls out of four fields stored in one small file. Open it once and it stops being magic.

The model you carry

Claim · no terminal needed

Your agents commit on your behalf all day. When one of them says “rebased onto main and force-pushed”, you currently have to take its word for it. By the end of this lesson you will be able to open any commit an agent made and read, from the raw object, exactly what it did.

We start here — not with branch, not with merge — because a commit is the only real noun in git. Branches, tags, HEAD, stashes, pull requests and worktrees are all just ways of pointing at commits. Get the commit right and the rest is bookkeeping.

Almost everyone who learns git by using it ends up believing a commit is a set of changes — that git saves your diff. It is a reasonable guess, it is what the interface shows you, and it is wrong in the one way that matters.

Here is the part everyone has backwards

A commit does not store a change. A commit stores a complete snapshot of every tracked file, plus a pointer to the commit that came before it.

Git does show you diffs constantly — git show, git diff, the green and red lines in a pull request — but those are computed on demand by comparing two snapshots. They are a view, not the storage. Julia Evans makes the same point: much of git’s difficulty is that its vocabulary describes the interface while the storage works differently, and the two only diverge when you are already in trouble.

What you can check after this step

Nothing yet — this is the only step that asks you to take something on trust, and the next one takes it back.

Open the box

Claim + proof · git cat-file

Rather than take my word for it, look. git cat-file -p prints the raw contents of any object in the repository. You can read the same commit at either resolution — and only one of them is the storage:

an honest state, not a theme
Plumbing — executed, output verbatimStep 02
$ git cat-file -p HEAD
tree 63f3e1605cebea996b599360dad707e9ed872244
parent 52ce976ce7d1602050f876ae5d19a88570e8ac24
author Ada Lovelace <ada@example.com> 1785418000 +0100
committer Ada Lovelace <ada@example.com> 1785418000 +0100

Add rate limiting to the API client

That is the whole thing. A commit is a small text file with four kinds of field.

Four kinds of field. tree is the snapshot — the whole project, not a diff. parent is the commit before this one, absent on the very first commit and doubled on a merge. author and committer are two separate people-and-timestamps, which is how you spot rewritten history. Everything after the blank line is the message. The structure is exactly as documented in Pro Git §10.2.

And you only ever type this much of it1851ce1d3eb9f856d7f009f15428c41f92ff3207
Predict before you read on

If every commit stores a complete snapshot of every tracked file, a repo with 400 files and 5,000 commits would hold two million file copies. Obviously it does not. What is going on?

Run this on a repo an agent touched

Point git cat-file -p HEAD at any repository your agent has been working in. If you can name all four fields in its output, this step is done.

2 of 4 steps remain

Nothing is ever deleted

You have read the first 2 steps in full — a claim and the verification that settles it. The rest of this lesson, and the 9 lessons after it, open when subscriptions do. Nothing that is free today will be taken away then.

Read the free reference
Subscriptions open soon
the free preview stays