- Manyana es un prototipo de control de versiones basado en CRDT desarrollado por Bram Cohen, que propone un nuevo enfoque para eliminar los conflictos de fusión y preservar el historial de forma estructural
- Al usar CRDT (Conflict-Free Replicated Data Type), la fusión siempre tiene éxito, y los conflictos se tratan como una indicación informativa, lo que permite al usuario reconocer con claridad los cambios realizados
- Sus ejes principales son la persistencia del orden de las líneas, las fusiones no bloqueantes y la internalización del historial, y no destruye los registros existentes ni siquiera durante un rebase
- Es una implementación de nivel demo escrita en aproximadamente 470 líneas de Python, y tanto el código completo como el documento de diseño están publicados en GitHub en dominio público
- Un caso que presenta experimentalmente un modelo de control de versiones de próxima generación sin fallos de fusión, más allá de las limitaciones de Git
Manyana: una visión coherente para el futuro del control de versiones
- Manyana es un prototipo de sistema de control de versiones basado en CRDT publicado por Bram Cohen, que busca resolver el problema de los conflictos de fusión en los sistemas existentes
- Los CRDT garantizan que la fusión siempre tenga éxito y tratan los conflictos como marcas informativas, para que el usuario pueda ver con claridad cuáles fueron los cambios reales
- Este enfoque tiene tres características clave: persistencia del orden de las líneas, manejo no bloqueante de conflictos e internalización del historial dentro de la estructura
- Incluso durante el proceso de rebase, conserva el historial existente y puede manejar de forma estable estructuras de fusión complejas sin un único ancestro común
- Manyana es una implementación de demostración escrita en unas 470 líneas de Python, y tanto el documento de diseño como el código están publicados en GitHub en dominio público
Puntos clave del enfoque basado en CRDT
- Los CRDT ofrecen consistencia eventual, garantizando que la fusión siempre tenga éxito y que el resultado sea el mismo sin importar el orden en que se fusionen
- Aunque varios usuarios fusionen ramas en las que trabajaron de forma independiente, el resultado se mantiene igual sin importar el orden
- Mediante la persistencia del orden de las líneas, una vez que se decide el orden del código insertado en una misma posición, ese orden se mantiene después
- Esto evita que el mismo tramo en conflicto se resuelva de forma distinta en cada rama
- Los conflictos se tratan solo como marcas informativas y no bloquean la fusión
- Siempre se genera un resultado de fusión, y los conflictos se marcan como “partes modificadas simultáneamente en posiciones cercanas”
- Al rastrear quién hizo cada cambio y qué acción realizó, se ofrecen marcas de conflicto útiles
- El historial está internalizado dentro de la estructura
- El estado se representa mediante una estructura ‘weave’ que incluye todas las líneas del archivo, y cada línea contiene metadatos sobre cuándo fue agregada o eliminada
- Al fusionar, basta con ingresar dos estados para generar siempre el resultado correcto, sin buscar un ancestro común ni recorrer un DAG
Marcado de conflictos mejorado
- Los sistemas de control de versiones tradicionales, cuando hay conflictos, simplemente muestran dos bloques de código uno al lado del otro, obligando al usuario a inferir por su cuenta las diferencias
- Manyana indica cada zona en conflicto con etiquetas como “eliminado” y “agregado”, y muestra quién hizo qué cambio
- Por ejemplo, si un usuario elimina una función y otro agrega una línea dentro de esa función, Manyana muestra con claridad la estructura de cada cambio por separado
- Esto permite que el usuario, en vez de comparar dos bloques, entienda de inmediato el significado y el contexto del cambio
Redefinir el rebase
- En un sistema basado en CRDT, el rebase no destruye el historial
- El rebase tradicional vuelve a apilar commits sobre una nueva base y genera un historial ficticio
- En Manyana se logra el mismo efecto, pero se conserva todo el historial original
- Para ello, basta con añadir al DAG una anotación de “ancestro principal (primary ancestor)”
- Este método funciona de forma estable incluso en estructuras de fusión sin ancestro común, y puede evitar los fallos de la fusión tradicional de 3 vías
Estado actual del proyecto
- Manyana es una implementación de demostración y no un sistema de control de versiones completo, y opera a nivel de archivo individual
- Está compuesto por unas 470 líneas de código Python
- Las funciones de cherry-pick y deshacer local aún no están implementadas, aunque en el README se describe la dirección futura de su desarrollo
- Este proyecto demuestra que el control de versiones basado en CRDT puede resolver problemas de UX y ofrecer mejores resultados que las herramientas existentes
- Todo el código se distribuye en dominio público (public domain), y el documento completo de diseño está incluido en el README de GitHub
Resumen de la reacción de la comunidad
- Un usuario señaló que, aunque Git se ha usado durante más de 10 años, hace falta un nuevo paradigma de control de versiones, y mencionó positivamente el intento de Manyana
- Indicó que la idea de que la fusión siempre tenga éxito no resulta intuitiva y pidió más ejemplos y explicaciones
- Mostró interés en la idea de mejorar el rebase y comentó que en un proyecto personal usa un método de gestión de fusiones mediante ramas intermedias
- Señaló como limitaciones de Git el manejo de archivos binarios, la confusión al distinguir ramas izquierda y derecha y la falta de resúmenes de cambios grandes de código
- También propuso que en el futuro el control de versiones pueda ofrecer funciones token-aware o plugins por lenguaje o formato de archivo
- Otro usuario preguntó si Manyana tiene una base similar a Pijul o Darcs, y pidió una comparación con los problemas de rendimiento de Darcs y el estado actual de Pijul
Conclusión
- Manyana es una demo concreta que aplica CRDT al control de versiones, y rediseña desde la raíz el manejo de conflictos y el problema del rebase
- Una estructura sin fallos de fusión, la conversión de los conflictos en información y la internalización estructural del historial muestran una dirección de diseño que supera las limitaciones del modelo actual de Git
- Aunque no es un sistema completo, representa un punto de partida valioso como plano de diseño para sistemas de control de versiones de próxima generación
1 comentarios
Comentarios de Hacker News
Creo que la forma de mostrar los merges es un problema aparte de cómo se representa el historial
Yo también odio la UI de merge por defecto de Git, así que uso p4merge. Es una herramienta que muestra cuatro paneles (izquierda, derecha, base común y resultado), así que puedes ver de un vistazo la causa del conflicto y cómo resolverlo
No creo que sea necesario cambiar el VCS en sí
merge.conflictStylede Git a"diff3"o"zdiff3", también se muestra la versión baseAsí puedes inferir, solo viendo los marcadores de conflicto, cuál lado agregó el código nuevo
Una vez me sorprendió escuchar en un pódcast a un invitado que había creado un VCS nuevo y entendía mal la forma en que Git almacena los diff. Si después de años trabajando en proyectos ni siquiera investigó los conceptos básicos, eso demuestra que el espíritu NIH (reinventar la rueda) sigue muy vivo
Pero hacerlo a nivel de SCM tiene la ventaja de poder recordar el historial de merges del usuario. Git tiene algunos casos límite en ese aspecto
No estoy seguro de que sea bueno que un merge nunca falle
Muchas veces un fallo de merge no solo indica un conflicto de ubicación, sino un conflicto semántico. En esos casos hay que resolverlo manualmente
No creo que los CRDT sean adecuados para control de versiones
Los conflictos son parte de la esencia del control de versiones. Si dos desarrolladores cambian el código en direcciones distintas, al final hace falta una decisión semántica. En esas situaciones, CRDT puede terminar produciendo código absurdo
Ya existen muchas herramientas que ofrecen una mejor UX de merge sobre Git, y la facilidad de hacer cherry-pick o revert también es una ventaja de Git
Por ejemplo, si en una rama se elimina una constante y en otra se usa esa constante, el código se rompe
Como la mayoría de los conflictos de Git son problemas sintácticos, un enfoque más inteligente de semantic merge o CRDT podría ser útil
Por ejemplo, al rastrear nombres de archivos, propiedades y hashes se podría usar un OR-set (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type).
Pero la resolución de conflictos igual tendría que hacerse en una interfaz externa
No entiendo muy bien por qué se enfocan tanto en CRDT
El problema semántico de los conflictos sigue existiendo. De hecho, los cambios podrían verse entremezclados (interleave), lo que lo vuelve aún más confuso
Yo soy partidario del rebase. Hay que evitar los merge commits, y todos los commits deberían ser unidades independientes. Creo que Gitflow es un antipatrón
Jujutsu y Gerrit sí resuelven bien el problema real de Git: “administrar cadenas de commits basadas en feedback de revisión”
Git reaplica snapshots, así que en cierto sentido el mismo trabajo existe dos veces. En cambio, Pijul funciona en unidades de patch, así que produce el mismo resultado sin importar el orden. Para mí esa sí es una unidad de trabajo realmente independiente
Incluso en un estado con conflictos, se puede deshacer (undo) solo un commit específico. Podría tener una estructura más flexible que Git
En la práctica muchas veces solo importa el resultado final. Mezclar squash merge de forma adecuada es más realista
Pero en algunos casos el conflicto es inherentemente necesario. Por ejemplo, el fenómeno de mezclar caracteres en editores colaborativos puede incluso dar un resultado peor
Este proyecto parece expandir las ideas de Codeville, que Bram hizo hace tiempo
Codeville apareció durante el boom de los DVCS a inicios de los 2000 y usaba almacenamiento y merge basados en weave. Es una idea 10 años anterior a los CRDT, pero la conexión resulta natural
Da gusto ver que Bram sigue aferrado a este problema e intentando cosas nuevas
arxiv:2002.09511
No estoy de acuerdo con la idea de que “todavía no existe un VCS basado en CRDT”
Pijul ya existe, y es un proyecto al que expertos le han dedicado miles de horas
Lleva 6 años en fase experimental, y hace 4 años incluso publiqué un issue al respecto, pero sigue sin reflejarse
Pijul es un VCS desarrollado sobre sí mismo, así que no usa GitHub
pijul pull -ase generan conflictos y simplemente vuelvo a clonar. Me pregunto si existe algún pull para actualizaciones de seguimientomanana.py es código Python de 473 líneas sin dependencias
La implementación real son unas 240 líneas y el resto es código de prueba. Es simple, pero impresionante
Viendo el incidente de left-pad en el ecosistema JS, también pienso que en Python debería haber más paquetes pequeños y responsables
Un sistema así debería diseñarse analizando cómo cambian los conflictos de merge según el tamaño del equipo
Habría que considerar qué problemas tienen equipos de 1, 10, 100 o 1000 personas, y también cómo el desarrollo basado en agentes cambiaría eso
Por mi experiencia, entre 1 y 100 personas casi no hay conflictos porque cada equipo divide el código en subárboles.
Si aumentan los agentes, 100 personas podrían comportarse como 1000, pero por ahora da la impresión de que la solución apareció antes que el problema real
Hoy en día basta con dejarle los conflictos de merge a Codex y listo, así que hay menos motivos para usar un VCS nuevo
Git fue diseñado para equipos grandes y, en la era de los agentes, se puede responder bien solo con automatización de procesos
El problema aparece más bien en cuellos de botella de bibliotecas compartidas o en políticas de restricción de acceso
Un problema aún mayor que los conflictos es la escalabilidad de Git
El tamaño de los repositorios y la velocidad de cambio están llegando al límite. Hace falta rediseñar servidores, clientes y protocolos en conjunto
Personalmente no entiendo muy bien qué problema resuelve este sistema
En abstracto es interesante, pero en la práctica jj es mucho más útil que Git
Creo que el siguiente paso es un sistema que haga control de versiones no a nivel de archivo sino a nivel de AST.
Ya hubo intentos como LightTable o Dark; estaría bien experimentar con este tipo de VCS basados en árboles