jj – CLI para Jujutsu
(steveklabnik.github.io)jj, la interfaz de línea de comandos de Jujutsu, es una herramienta basada en un sistema de control de versiones distribuido (DVCS)- Ofrece funciones más simples e intuitivas que
git, pero también más potentes - Combina las ventajas de
gity Mercurial para reducir la cantidad de herramientas principales y reforzar su integración orgánica - Usa un backend compatible con
git, lo que permite experimentar de forma independiente sin cambiar el entorno de colaboración existente - Para usuarios avanzados, es importante que permite aprovechar funciones adicionales de control de versiones que son difíciles de lograr con
git
Introducción y características de jj
-
jjes la CLI (interfaz de línea de comandos) de Jujutsu, y Jujutsu es un sistema de control de versiones distribuido (DVCS)- Es posible que los usuarios ya estén familiarizados con otros DVCS como
git, y el tutorial parte de la perspectiva de un usuario degit jjfue diseñado como una herramienta más simple, más fácil de usar y al mismo tiempo potente quegit- Normalmente, la “potencia” y la “complejidad” están en tensión, pero
jjpropone un nuevo equilibrio entre ambas jjcombina las fortalezas degity Mercurial (hg) para construir una nueva forma de DVCS- Reduce la cantidad de herramientas principales y ofrece un entorno de trabajo eficiente mediante la integración orgánica entre ellas
- Los usuarios avanzados pueden aprovechar funciones adicionales de control de versiones que son difíciles de conseguir con
git jjusa un backend compatible congit, por lo que permite experimentar de forma independiente sin cambiar el entorno de colaboración- Mantiene la compatibilidad con los repositorios existentes de
gity, si es necesario, permite volver fácilmente agit - El tutorial anticipa que, a través de estas características, mostrará directamente por qué
jjes una herramienta que vale la pena seguir de cerca
- Es posible que los usuarios ya estén familiarizados con otros DVCS como
1 comentarios
Opiniones en Hacker News
Mucha de la discusión se enfoca en las diferencias entre git y jj, pero yo creo que es mejor olvidarse de git y concentrarse en el flujo de trabajo básico de jj
En un repositorio limpio puedes ejecutar
jjpara revisar el estado, y después de hacer cambios basta con hacer commit conjj commit -m "made changes"Si te equivocas, corriges y luego usas
jj squashpara combinarlo con el último commitSolo hace falta usar
jj new -r lmnopcuando quieres trabajar desde una revisión específica, como si fuera una rama nuevaEl historial de git se puede revisar con
git log, y el funcionamiento interno de jj no se vealias.save="!git add -A; git commit -m"y lo uso como$ git save "made changes"Siento que JJ me pide pensar al revés
En git haces cambios y luego escribes el mensaje del commit, pero en jj primero creas un commit nuevo y después le pones una descripción
Estoy acostumbrado a tener un estado desordenado con varias funcionalidades mezcladas y seleccionar solo los cambios necesarios para hacer commit, pero viendo solo el tutorial de jj no me queda claro si eso se puede hacer
jj newes como un área de staging vacía en gitEn jj siempre existe un commit, y ese commit tiene un changeid estable calculado a partir del contenido de la carpeta
Si quieres dividir varios cambios en commits separados, puedes usar
jj splitjj newy dejar el mensaje vacíoMás tarde, cuando ya está listo, hago squash de varios commits en uno y le agrego el mensaje
Este método funciona como una especie de historial de undo, así que experimentar es mucho más cómodo
jj newsimplemente significa “crear un commit nuevo encima”, así que no hace falta escribir la descripción de inmediatoYo también traté de crearme ese hábito al principio, pero en realidad era ineficiente
En Git también se ha recomendado un flujo parecido, y consultando Squash Workflow puedes lograr un flujo similar al índice de Git
Por eso tengo varios workspaces y uso mucho la función de shelve de IntelliJ
A veces también guardo temporalmente diffs como parches de git
Y trato de ocultar todo ese proceso caótico a mis compañeros para parecer un poco más profesional
Algo que no me gusta de jj es que las modificaciones de archivos se guardan automáticamente en commits
Si haces checkout de un commit viejo para explorarlo y luego modificas archivos, ese commit cambia y todo el historial posterior se rebasea
Por eso termino creando un commit vacío por precaución
Con git me resulta más cómodo porque el repositorio no cambia hasta que yo haga commit explícitamente
jj evologjj ya tenía una solución mejor que el staging
Estar acostumbrado al CLI de git era más bien un obstáculo para aprender jj
Curiosamente, usar jj te ayuda a entender mejor la estructura del motor de almacenamiento de git
jj newen vez deedit, puedes rastrear los cambios de forma limpiaSe siente mucho mejor que andar haciendo malabares con el stash de git
jj edites la trampa más grande de jjEn su lugar conviene usar
jj new, y si te equivocas puedes recuperarlo conjj undojj trata los commits como snapshots baratos, así que lo correcto es enfocarse en los “cambios” más que en los commits
El rebase automático queda fijado como inmutable después del push, así que es seguro
Puedes combinar
jj newyjj squashpara manejarlo como si fuera el head de una rama en gitjj hace que trabajar en estado detached head sea sencillo
jj editSi cambias a
jj new, el problema se resuelveEl último párrafo sobre jj es el punto clave
Como usa un backend totalmente compatible con git, puedes probarlo tú solo sin que todo el equipo tenga que cambiar
Si no te convence, siempre puedes volver a git
Las operaciones hechas con git no se registran en el log de jj, así que hay que importarlas manualmente
En un proyecto se recomienda usar una sola interfaz
Mi función favorita es
jj absorbMueve automáticamente los cambios de la revisión actual a commits anteriores relacionados
Es útil cuando se te olvida modificar archivos de configuración o
.gitignoreHaces
jj new, luego los cambios, y despuésjj absorbY lo mejor es que no tienes que lidiar con merge conflict
jj absorbse aplica mal, puedes revertirlo conjj undoGracias a esta función ya no me dan miedo los rebases complejos
git absorbNo he podido actualizar el tutorial desde hace bastante tiempo, pero sigo usando jj todos los días
He estado ocupado en la startup ersc.io, así que no he podido trabajar en upstream
Las preguntas siempre son bienvenidas
jj usa change ID estables, mientras que git usa commit ID inmutables
Por eso en jj el undo y el rebase se sienten mucho más flexibles
A veces quiero ver más cambios y me pregunto si hay una opción para mostrarlos todos de una vez
Vale la pena probar jj precisamente porque es distinto de git
Solo experimentar otro enfoque ya amplía tu perspectiva de ingeniería
No hace falta probarlo todo, pero sí es importante entender los trade-offs de distintos flujos de trabajo
La relación entre git y jj me recuerda a la relación entre C y Python
git es rastreo forense, y jj se parece más a capítulos de una historia
A veces hay que reescribir capítulos tempranos para que los posteriores se sientan más naturales
jj está diseñado con la filosofía de que “el working tree en sí es un commit” y que “hasta un conflicto puede guardarse como commit”
Siento que afirmaciones como “más poderoso y más fácil” necesitan ejemplos concretos
Si no tienes esa necesidad, quizá no percibas el valor de jj
Hay que usarlo para entenderlo
jj undoya vale la pena por sí mismoEn git es fácil terminar en un estado imposible de recuperar, mientras que en jj se resuelve con unos cuantos undo
Gracias a jj me siento con confianza para aprovechar un DAG no lineal
Manejo cambios con varios padres o varios hijos sin problema
Antes forzaba un orden innecesariamente, pero ahora puedo expresar con claridad las dependencias
El proceso de revisión y envío también se volvió mucho más eficiente