2 puntos por GN⁺ 16 일 전 | 1 comentarios | Compartir por WhatsApp
  • 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 git y 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

  • jj es 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 de git
    • jj fue diseñado como una herramienta más simple, más fácil de usar y al mismo tiempo potente que git
    • Normalmente, la “potencia” y la “complejidad” están en tensión, pero jj propone un nuevo equilibrio entre ambas
    • jj combina las fortalezas de git y 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
    • jj usa un backend compatible con git, por lo que permite experimentar de forma independiente sin cambiar el entorno de colaboración
    • Mantiene la compatibilidad con los repositorios existentes de git y, si es necesario, permite volver fácilmente a git
    • El tutorial anticipa que, a través de estas características, mostrará directamente por qué jj es una herramienta que vale la pena seguir de cerca

1 comentarios

 
GN⁺ 16 일 전
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 jj para revisar el estado, y después de hacer cambios basta con hacer commit con jj commit -m "made changes"
    Si te equivocas, corriges y luego usas jj squash para combinarlo con el último commit
    Solo hace falta usar jj new -r lmnop cuando quieres trabajar desde una revisión específica, como si fuera una rama nueva
    El historial de git se puede revisar con git log, y el funcionamiento interno de jj no se ve

    • Yo quería algo parecido, así que hice un alias de git como alias.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 new es como un área de staging vacía en git
      En 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 split
    • Yo suelo hacer commits temporales con jj new y dejar el mensaje vacío
      Má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
    • En realidad, jj new simplemente significa “crear un commit nuevo encima”, así que no hace falta escribir la descripción de inmediato
      Yo también traté de crearme ese hábito al principio, pero en realidad era ineficiente
    • En JJ esta forma de trabajar es estándar
      En Git también se ha recomendado un flujo parecido, y consultando Squash Workflow puedes lograr un flujo similar al índice de Git
    • A mí también me pasa que, cuando hago varios cambios, se terminan mezclando funcionalidades distintas
      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

    • Yo también pensaba así antes, pero cambié de opinión después de conocer jj evolog
      jj 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
    • Si usas jj new en vez de edit, puedes rastrear los cambios de forma limpia
      Se siente mucho mejor que andar haciendo malabares con el stash de git
    • jj edit es la trampa más grande de jj
      En su lugar conviene usar jj new, y si te equivocas puedes recuperarlo con jj undo
      jj 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
    • Que las modificaciones de archivos se guarden automáticamente en commits es una función central de jj
      Puedes combinar jj new y jj squash para manejarlo como si fuera el head de una rama en git
      jj hace que trabajar en estado detached head sea sencillo
    • Probablemente hiciste checkout de un commit antiguo con jj edit
      Si cambias a jj new, el problema se resuelve
  • El ú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

    • Aunque hay excepciones en organizaciones que usan LFS, submodules o hooks
    • No es compatibilidad total. La interoperabilidad existe, pero no es perfectamente fluida
      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
    • Antes yo también usaba git así, junto con CVS y Subversion
    • Pero si usas git y jj al mismo tiempo en el mismo directorio, se puede romper todo
  • Mi función favorita es jj absorb
    Mueve 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 .gitignore
    Haces jj new, luego los cambios, y después jj absorb
    Y lo mejor es que no tienes que lidiar con merge conflict

    • Si jj absorb se aplica mal, puedes revertirlo con jj undo
      Gracias a esta función ya no me dan miedo los rebases complejos
    • Por cierto, en git también existe git absorb
  • No 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

    • La clave está en la diferencia de inmutabilidad del DAG entre git y jj
      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
    • jj oculta automáticamente los cambios “poco interesantes”
      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

    • Claro, en el 99% de los casos probar cosas con beneficios mínimos también puede ser una pérdida de tiempo
  • 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

    • Lo que hace jj también se puede hacer en git, pero la forma habitual de pensar en git lo dificulta
      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 tuviera que mencionar algunas ventajas de jj:
      • no hace falta resolver de inmediato los conflictos de rebase/merge
      • manipular commits es muy fácil, sobre todo con jjui
      • jj tiene un operation log que rastrea los cambios de estado de git
      • las ramas sin nombre permiten experimentar con libertad
      • es totalmente compatible con git, así que se puede mezclar dentro de un equipo
    • Cuando pasamos de SVN a git sentimos una gran mejora, pero ahora no tenemos grandes molestias con nuestro flujo de trabajo en git
    • Puedes trabajar en varios PR al mismo tiempo dentro de un solo repositorio y hacer push de cada uno como corresponda
      Si no tienes esa necesidad, quizá no percibas el valor de jj
    • El atractivo de jj no está en los comandos, sino en su flujo de trabajo intuitivo
      Hay que usarlo para entenderlo
    • Solo jj undo ya vale la pena por sí mismo
      En 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

    • Me pregunto si sobre este tipo de cambios ramificados se usa un flujo de trabajo de mega-merge + absorb