Qué pasa cuando reescribes la historia
Reescribir la historia es la operación a la que la gente echa mano una vez cada dos años, ejecuta desde un conjuro de git filter-branch a medio recordar, y…
Reescribir la historia es la operación a la que la gente echa mano una vez cada dos años, ejecuta desde un conjuro de git filter-branch a medio recordar, y hace mal. El comando resulta poco familiar precisamente porque es raro, y es destructivo precisamente cuando resulta poco familiar.
Desde 0.11 y 0.12 toda la superficie son subcomandos de primera clase de torii history, y todos son el mismo motor por debajo: reword cambia mensajes, reauthor cambia identidades, redate cambia fechas, replace-text cambia contenido de ficheros, filter-path cambia qué rutas existen, y exec-filter ejecuta lo que quieras contra cada árbol materializado.
Las cuatro cosas que pasan antes de tocar un commit
Se niega a arrancar con el árbol sucio. Una reescritura recorre y reconstruye cada commit del rango; hacerlo con trabajo sin commitear por medio significa que ese trabajo no está ni en la historia vieja ni en la nueva. El pre-vuelo también se niega cuando hay una operación pendiente —un rebase a medias, un cherry-pick esperando un conflicto— porque la reescritura se construiría sobre un estado que todavía estás decidiendo.
Toma un snapshot. Ni un commit ni un stash: un guardado local del árbol de trabajo, restaurable por id, que no entra nunca en tu historia y no llega nunca a un remoto. Esa es toda la diferencia entre «la reescritura salió mal» y «la reescritura salió mal y he perdido la tarde».
torii snapshot list
torii snapshot restore <id>Preserva las fechas. Las fechas de autor y de committer sobreviven por defecto. Suena a detalle hasta que has visto a un filter-branch aplastar seis meses de historia en «todo commiteado hace treinta segundos», y con ello cada señal sobre cómo creció el proyecto de verdad.
Reescribe el árbol y luego mueve las refs. Los commits se reconstruyen primero y las referencias se apuntan a la historia nueva después, así que una reescritura interrumpida deja las refs viejas intactas en vez de a medio mover.
Lo que deliberadamente no esconde
Dos consecuencias son inherentes a reescribir la historia, y fingir lo contrario sería peor que decirlas:
Las firmas no sobreviven. Una firma GPG firma un objeto commit. Reescribir produce un objeto distinto, así que la firma ya no verifica — no se retira por cortesía, simplemente ha dejado de ser cierta. torii sign vuelve a firmar la historia nueva cuando la quieras de vuelta.
El siguiente push es forzado. Los demás siguen teniendo la historia vieja. En una rama compartida eso es una conversación que hay que tener antes de la reescritura, no después: torii sync --force hace lo que dice, y lo que dice es que gana tu versión.
La que más importa
torii history replace-text --redact-secretsRedacta todas las líneas que el escáner marca, en cada fichero de cada commit. Es la forma más rápida de limpiar un repositorio después de commitear una clave — y no hace que la clave sea segura. La clave fue pública en el momento del push; rótala primero, y limpia la historia después para que quien clone a continuación no la encuentre. El orden no es negociable y la herramienta no puede imponerlo por ti.
Previsualizar
Todas aceptan --dry-run, y --since <ref> para acotar el rango. En un repositorio cuya historia importa, la secuencia que nunca ha fallado a nadie es: ensayo en seco, leer la salida, snapshot, ejecutarlo, comprobar torii log, y solo entonces el push forzado.