La copia de trabajo es un commit, y otras cosas que tardaron un momento en encajar
Parte 3 de 9.
El modelo mental de Git tiene tres capas: directorio de trabajo, índice (área de
staging) y commits. La mayor parte de la fricción del día a día que asocio con Git,
git add -p, olvidarme de preparar un archivo, git status mostrando secciones
solapadas de “preparado” y “sin preparar” para el mismo archivo, viene de gestionar
la frontera entre las dos primeras.
jj elimina esa frontera. El directorio de trabajo es el contenido de un commit real,
direccionado como @. Cada comando hace primero una instantánea de él. No hay
jj add. Querer hacer commit de “algunos pero no todos” los cambios actuales lo
gestiona jj split, que es un acto explícito sobre el propio commit en lugar de una
negociación paralela continua con un índice.
Una vez que eso encajó, otras dos ideas se colocaron en su sitio rápidamente:
Dos identificadores por commit, no uno. El identificador de cambio (qpvuntsm)
identifica “esta pieza de trabajo” y se mantiene constante a lo largo de ediciones y
rebases. El identificador de commit (230dd059) es un hash del contenido, exactamente
como un SHA de Git, y cambia siempre que lo hace el contenido. Referirse al trabajo
por el identificador de cambio significa que la referencia sobrevive a ser reescrita,
algo genuinamente útil una vez que jj edit y jj new sobre el pasado, de la
lección 5, se vuelven movimientos normales en lugar de casos especiales.
El registro de operaciones no es el reflog. git reflog rastrea dónde apuntaban
las ramas y HEAD. jj op log rastrea cada operación que cambió algo del
repositorio: rebases, describes, cambios de configuración hechos con jj config set,
todo ello. jj undo revierte la última; jj op restore <id> salta de vuelta a
cualquier punto anterior. Lo probé describiendo deliberadamente un commit mal y luego
deshaciéndolo, e hizo exactamente lo que dice, sin arqueología de reflog necesaria.
La única restricción que merece la pena interiorizar pronto: los commits en trunk()
o por detrás de él, o ya empujados a un bookmark remoto con seguimiento, son
inmutables por defecto. Intentar editar uno recibe un rechazo con una explicación, no
un historial compartido reescrito por accidente. Es la misma convención de “no hagas
rebase de lo que has empujado” en la que Git confía en que la gente recuerde, salvo
que jj de verdad la impone.