The model you carry
Claim · no terminal neededWhen an agent stops mid-task — because it hit a conflict, ran out of context, or asked you a question — the first command you run is git status. It is also the command most people read wrong, because it appears to answer “what did you change?” and in fact answers something narrower and more useful.
First, from lessons 01–02, because you have not been asked in a while: an agent rewrites the oldest of five commits on a branch. How many of the five keep their original hash?
Now the new material. Most people carry a two-place model of git: there are your files, and there is the repository. Committing moves work from the first into the second, and git add is an irritating extra keystroke on the way — a formality, a checkbox, a thing agents do for you with git add . so you never think about it.
There is no extra keystroke. There is a third copy of your project, called the index, stored in its own file. git add writes to it, git commit reads from it, and git status exists to report the two ways it can disagree with its neighbours.
Git manages three trees, in Pro Git’s naming: HEAD, the last commit snapshot; the index, the proposed next commit; and the working tree, the files on your disk. Pro Git calls the third one the working directory; git’s own documentation says working tree, and so will this course.
Read that middle definition again, because it is the one that pays: the index is not a queue, a list of filenames, or a set of flags. It is a complete proposed snapshot — the same shape of thing as a commit, sitting one step from becoming one.
Nothing yet. The next step opens the index and reads a version of a file that exists in neither your editor nor your history.
One file, three versions
Claim + proof · git cat-file, git ls-filesHere is a repository in the state an agent leaves constantly: one file was edited and staged, then edited again before anything was committed. Nothing about this is exotic — it is what happens when an agent stages its work and then keeps going.
Git gives you a way to name a file inside each tree. HEAD:a.txt is the committed version, :a.txt — with nothing before the colon — is the version in the index, and the plain path is whatever is on disk:
$ git cat-file -p HEAD:a.txt $ git cat-file -p :a.txt $ cat a.txt hello hello staged line hello staged line working line
Three commands, one filename, three different answers. The middle one is in no editor and in no commit — it exists only in the index.
The index itself is a real file — .git/index, binary, so you cannot cat it the way you read a branch in lesson 02. git ls-files -s prints it as text. One line per tracked file: mode, blob hash, merge stage, path.
$ git ls-files -s
100644 450ef9a7e0ac4c37839655d37dabef592b441cb3 0 a.txtNote what is missing: notes.md exists on disk but has no line here. That is the entire meaning of “untracked” — not in the index.
That hash is doing more work than it appears to. A hash in git names content that exists in the object database — that was lesson 01’s lesson. So if the index holds a blob hash, the staged content has already been written into .git/objects. Staging is not a note-to-self. It is a save.
Two hashes from the readout above: 450ef9a (staged) and 347f90c (on disk). Both name content that exists somewhere right now. Ask git what type of object each one is. What comes back?
Lesson 01 promised you would look at plumbing exactly twice in this course. This is the second time — ls-files, cat-file, hash-object and write-tree are all script-facing commands. From here on the course stays in porcelain, because you will have seen the thing underneath it.
Pick a file the agent touched and run git rev-parse :path/to/file then git hash-object path/to/file. If the two hashes differ, the agent staged one version and then changed it — and the staged one is not the one you are reading in your editor.
Status is two diffs, not one
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.