The working copy is a commit, and other things that took a moment to click
Part 3 of 9.
Git’s mental model has three layers: working directory, index (staging area), and
commits. Most of the day-to-day friction I associate with Git - git add -p, forgetting
to stage a file, git status showing overlapping “staged” and “unstaged” sections for
the same file - comes from managing the boundary between the first two.
jj removes that boundary. The working directory is the content of a real commit,
addressed as @. Every command snapshots it first. There’s no jj add. Wanting to
commit “some but not all” of the current changes is handled by jj split, which is an
explicit act on the commit itself rather than a running side-negotiation with an index.
Once that clicked, two more ideas fell into place quickly:
Two ids per commit, not one. The change id (qpvuntsm) identifies “this piece of
work” and stays constant across edits and rebases. The commit id (230dd059) is a
content hash, exactly like a Git SHA, and changes whenever the content does. Referring to
work by change id means the reference survives being rewritten - genuinely useful once
lesson 5’s jj edit and jj new-on-the-past become normal moves rather than special
cases.
The operation log is not the reflog. git reflog tracks where branches and HEAD
pointed. jj op log tracks every operation that changed anything about the repository -
rebases, describes, config changes made through jj config set, all of it. jj undo
reverses the last one; jj op restore <id> jumps back to any earlier point. I tested
this by deliberately describing a commit wrong and then undoing it, and it did exactly
what it says, no reflog archaeology required.
The one restriction worth internalizing early: commits at or behind trunk(), or
already pushed to a tracked remote bookmark, are immutable by default. Trying to edit one
gets a refusal with an explanation, not a rewritten shared history by accident. It’s the
same “don’t rebase what you’ve pushed” convention Git relies on people remembering,
except jj actually enforces it.