Die Arbeitskopie ist ein Commit, und andere Dinge, die einen Moment brauchten, bis es klick machte
Teil 3 von 9.
Gits mentales Modell hat drei Schichten: Arbeitsverzeichnis, Index (Staging-Bereich)
und Commits. Die meiste alltägliche Reibung, die ich mit Git verbinde, git add -p,
das Vergessen, eine Datei zu stagen, git status, das überlappende “staged”- und
“unstaged”-Abschnitte für dieselbe Datei zeigt, kommt vom Verwalten der Grenze
zwischen den ersten beiden.
jj entfernt diese Grenze. Das Arbeitsverzeichnis ist der Inhalt eines echten Commits,
adressiert als @. Jeder Befehl macht zuerst einen Snapshot davon. Es gibt kein
jj add. Der Wunsch, “manche, aber nicht alle” der aktuellen Änderungen zu committen,
wird von jj split erledigt, was ein expliziter Akt am Commit selbst ist statt einer
laufenden Nebenverhandlung mit einem Index.
Sobald das klick gemacht hatte, fügten sich zwei weitere Ideen schnell ein:
Zwei IDs pro Commit, nicht eine. Die Change-ID (qpvuntsm) identifiziert “dieses
Stück Arbeit” und bleibt über Bearbeitungen und Rebases hinweg konstant. Die
Commit-ID (230dd059) ist ein Content-Hash, genau wie eine Git-SHA, und ändert sich,
wann immer sich der Inhalt ändert. Arbeit über die Change-ID zu referenzieren
bedeutet, dass die Referenz das Umschreiben übersteht, wirklich nützlich, sobald
jj edit und jj new auf der Vergangenheit aus Lektion 5 zu normalen Zügen werden
statt zu Sonderfällen.
Das Operations-Log ist nicht das Reflog. git reflog verfolgt, wohin Branches und
HEAD zeigten. jj op log verfolgt jede Operation, die irgendetwas am Repository
geändert hat, Rebases, Describes, Konfigurationsänderungen über jj config set, das
alles. jj undo macht die letzte rückgängig; jj op restore <id> springt zu jedem
früheren Punkt zurück. Ich habe das getestet, indem ich einen Commit absichtlich
falsch beschrieb und es dann rückgängig machte, und es tat genau, was es sagt, keine
Reflog-Archäologie nötig.
Die eine Einschränkung, die es sich früh einzuprägen lohnt: Commits auf oder hinter
trunk(), oder bereits zu einem getrackten Remote-Bookmark gepusht, sind
standardmäßig unveränderlich. Der Versuch, einen zu bearbeiten, bekommt eine
Ablehnung mit einer Erklärung, keine versehentlich umgeschriebene geteilte History.
Es ist dieselbe “rebase nicht, was du gepusht hast”-Konvention, auf die Git sich
verlässt, dass die Leute sich daran erinnern, nur dass jj sie tatsächlich durchsetzt.