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.