svn - subversion - tortoise que es
Cuando SVN no logra fusionarse y Mercurial tiene éxito (3)
Antes de que aparezca, ya he visto varios hilos sobre este tema, incluyendo estos:
Estoy pensando en cambiar a Mercurial (de Subversion) para nuestro grupo de desarrollo. Antes de hacerlo estoy haciendo la lista de pros / contras habituales.
Uno de mis "profesionales" es que la fusión es superior en Mercurial, pero hasta ahora no encuentro pruebas convincentes de ello. Es decir, hay una declaración hecha en HgInit.com que no he podido verificar:
Por ejemplo, si cambio una función un poco y luego la muevo a otro lugar, Subversion realmente no recuerda esos pasos, por lo que, cuando llegue el momento de fusionarse, podría pensar que una nueva función simplemente apareció de la nada. . Mientras que Mercurial recordará esas cosas por separado: la función cambió, la función se movió, lo que significa que si también la modificaste un poco, es mucho más probable que Mercurial fusione con éxito nuestros cambios.
Esta sería una funcionalidad extremadamente convincente, pero por lo que puedo decir, es solo aire caliente. No he podido verificar la declaración anterior.
Creé un repositorio de Mercurial, hice un Hello World y luego lo cloné. En uno modifiqué la función, la confirmé y luego la moví, y luego la confirmé. En el otro simplemente agregué otra línea de salida en la función y me comprometí.
Cuando me fusiono, obtengo básicamente el mismo conflicto de fusión que obtendría usando Subversion.
Comprendo que mercurial puede rastrear mejor los nombres de archivos y que DVCS tiene otras ventajas además de la fusión, pero este ejemplo me interesa. ¿Está Joel Spolsky fuera de la base aquí, o me estoy perdiendo algo?
No tengo experiencia en esta área, pero parece que ya que Mercurial guarda más información que, en teoría, podría hacer mejor en la fusión (si los desarrolladores también hicieran checkins frecuentes). Por ejemplo, considero que es factible que Mercurial obtenga cambios contextuales al comparar múltiples cambios, por ejemplo, modifico una función, registré, moví la función, registré y Mercurial asocia esas dos partes.
Sin embargo, la fusión de Mercurial no parece aprovecharse realmente de la información adicional, y parece funcionar de la misma manera que Subversion. ¿Es esto correcto?
AFAIK, SVN hace toda su fusión interna: las herramientas de combinación están ahí solo para los casos en que hay un conflicto, ya que (obviamente) necesita informarle y solucionarlo.
Los casos no conflictivos se basan en la aplicación de parches, es decir, svn tomará los cambios que realizó en una revisión y los aplicará al objetivo. Las versiones recientes de SVN (desde la versión 1.5) recuerdan las fusiones que realizó anteriormente, almacenando esta información en una propiedad asociada con el directorio. 1.6 hace un trabajo mucho mejor de manejar estas propiedades en comparación con 1.5.
SVN no se fusiona al comparar 2 árboles y diferenciarlos; consulte el libro , excepto cuando los árboles a fusionar no están relacionados, solo entonces realizará una operación de fusión de tipo diff (o si especifica la opción --ignore-ancestry) . Aquí hay una breve descripción de lo que sucede. Puede ver esto cuando fusiona conflictos pasados: una vez que haya resuelto una fusión de revisión complicada, svn recuerda qué revisiones se fusionaron y aplicará esos cambios nuevamente. Puedes probarlo al intentarlo: filmar, editar 2 archivos, combinar para obtener un conflicto. Edite el archivo bifurcado solo en la misma línea, luego fusione: se abrirá un conflicto a pesar de que el archivo de destino no haya cambiado, pero debido a que la fusión está aplicando un cambio a una línea que ha sido modificada de lo que esperaba el archivo bifurcado ( es decir, como un parche que muestra lo que cree que la línea que va a cambiar debería haber sido). En la práctica, no ve esto, ya que no tiende a rechazar repetidamente los cambios de combinación.
Sin embargo, SVN hace un mal trabajo con archivos renombrados, ya que los rastrea como operaciones de eliminar + agregar. Otros SCM hacen un mejor trabajo, pero incluso ellos realmente no pueden saber si un nombre de archivo se ha cambiado, o si se elimina y agrega, especialmente cuando ese archivo también se modifica. Git usa algunas heurísticas para intentar determinar esto, pero no puedo ver que garantice el éxito. Hasta que tengamos un SCM que se enganche al sistema de archivos, creo que este seguirá siendo el caso.
Dos cosas:
Mercurial tiene un código interno para realizar combinaciones y solo llamará a una herramienta de combinación externa si falla la "fusión previa" interna.
Usted se vincula al this y dice que no hay una herramienta integrada para manejar conflictos (no es lo mismo que una combinación integrada) y el wiki de Mercurial donde se afirma que Mercurial intentará hacer combinaciones internamente antes de llamar a un proveedor externo. programas
Usted se vincula a una pregunta en la que mi respuesta da un caso explícito en el que Mercurials tiene éxito y Subversion falla en una combinación. Esta es una comparación inmediata utilizando el código de combinación interno en Mercurial y Subversion.
Por lo que sé, cualquier persona que diga Mercurial hace un seguimiento de los códigos de movimiento en menos de partes del tamaño de un archivo está mal. Hace un seguimiento de los nombres de los archivos independientemente de los cambios en el código, por lo que si Dave cambia el nombre de un archivo y Helen cambia algo en el archivo, puede automatizar eso, pero hasta donde sé, ¡Subversion también puede hacer eso! (CVS no puede).
Pero hay una manera en que la lógica de fusión de Mercurial es dramáticamente mejor que la de Subversion: recuerda las resoluciones de conflicto. Considera este gráfico de la historia:
base ---> HELEN1 ---> merge1 --> HELEN2 -> merge2
/--> DAVE1 ---/ /
/--> DAVE2 ---------/
Helen y Dave hicieron cambios independientemente. Helen tiró del árbol de Dave y se fusionó, luego hizo otro cambio por encima de eso. Mientras tanto, Dave continuó programando sin molestarse en tirar de Helen. Entonces Helen tiró de nuevo el árbol de Dave. (Quizás Dave está trabajando en el tronco principal de desarrollo, y Helen está fuera en una rama de características, pero quiere sincronizar con los cambios del tronco periódicamente). Al construir "fusionar2", Mercurial recordaría todas las resoluciones de conflicto hechas en "fusionar1" y solo muestra a Helen los nuevos conflictos, pero Subversion haría que Helen vuelva a fusionarse desde cero. (Hay maneras de evitar tener que hacer eso con Subversion, pero todas involucran pasos manuales adicionales. Mercurial se encarga de ello).
Para obtener más información, lea sobre el algoritmo de marca-fusión que fue desarrollado para Monotone y AFAIK ahora es usado tanto por Mercurial como por Git.