Posible duplicado:
soy un geek de Subversion, ¿por qué debería considerar o no considerar Mercurial o Git o cualquier otro DVCS?
De vez en cuando, escuchas a alguien decir que el control de versión distribuido (Git, HG) es inherentemente mejor que el control de versión centralizado (como SVN) porque la fusión es difícil y dolorosa en SVN. La cuestión es que nunca tuve problemas para fusionarme en SVN, y dado que solo escuchas esa afirmación hecha por los defensores de DVCS, y no por los usuarios reales de SVN, tiende a recordarme esos anuncios desagradables en la televisión donde trata de venderte algo que no necesitas haciendo que los torpes actores pretendan que lo que ya tienes y funciona bien es increíblemente difícil de usar.
Y el caso de uso que siempre se menciona es volver a fusionar una sucursal, lo que nuevamente me recuerda a esos anuncios de productos de moda; si sabes lo que estás haciendo, no deberías (y nunca deberías) volver a fusionar una sucursal en primer lugar. (¡Por supuesto, es difícil de hacer cuando estás haciendo algo fundamentalmente incorrecto y tonto!)
Entonces, descontando el ridículo caso de uso de Strawman, ¿qué hay en la fusión de SVN que es inherentemente más difícil que la fusión en un sistema DVCS?
Respuestas:
Es porque svn carecía de las estructuras de datos adecuadas para determinar con precisión el último ancestro común de las dos ramas. Eso no es un gran problema para una rama que solo se fusiona una vez, pero puede causar muchos conflictos de fusión erróneos en situaciones en las que varias ramas se fusionan varias veces.
No sigo svn muy de cerca, pero entiendo que esos problemas técnicos particulares se han solucionado en versiones recientes. Sin embargo, no se solucionó lo suficientemente temprano como para disipar el mito, y las personas que probaron DVCS para las fusiones se han quedado con él por otras razones.
fuente
Y ahí radica la fuente de su confusión y todo el problema en general.
Dices que fusionar ramas es "fundamentalmente incorrecto y tonto". Bueno, ese es exactamente el problema: estás pensando en las ramas como cosas que no deberían fusionarse. ¿Por qué? Porque eres un usuario SVN que sabe que fusionar sucursales es difícil . Por lo tanto, nunca lo haces y animas a otros a que no lo hagan. Usted ha sido entrenado para evitar la fusión; Ha desarrollado técnicas que utiliza para evitar la fusión.
Soy un usuario de Mercurial. Incluso en mis propios proyectos, donde soy el único desarrollador, fusiono sucursales todo el tiempo . Tengo una rama de lanzamiento, en la que puse una solución. Bueno, fusiono eso nuevamente en la línea principal para que la solución vaya allí.
Si estuviera usando SVN, adoptaría una estructura completamente diferente de la base de código. ¿Por qué? Porque SVN hace que las fusiones sean difíciles y, por lo tanto, desarrollas modismos y técnicas para evitar hacer fusiones complejas.
Los DVCS facilitan las fusiones complejas porque son el estado predeterminado . Todo es una rama, más o menos, en un DVCS. Por lo tanto, toda su estructura está construida desde cero para facilitar la fusión. Esto le permite desarrollar un flujo de trabajo que usa la fusión a diario, en lugar del flujo de trabajo SVN donde nunca usa la fusión.
El hecho simple es este: debe acercarse a un DVCS de una manera diferente que SVN. Debería usar los modismos apropiados para estos tipos muy diferentes de sistemas de control de versiones. En SVN, adoptas modismos que no implican fusión porque las fusiones son difíciles. En DVCS, adoptas expresiones idiomáticas que con frecuencia usan fusiones porque no son gran cosa.
Herramienta adecuada para el trabajo correcto.
La cuestión es que el flujo de trabajo centrado en la fusión es mucho más agradable y fácil de usar que el flujo de trabajo de estilo SVN donde no se fusionan las cosas. Es más fácil ver cuándo se introdujo algo de la rama de lanzamiento en la rama de desarrollo. Es más fácil ver las diversas interacciones entre las ramas. Es fácil crear ramas de prueba para cosas, luego cortarlas si la prueba no funciona. Y así.
Realmente, Joel explica esto mucho mejor que yo . Deberías tener una buena lectura de eso.
fuente
No hay nada demasiado difícil sobre la fusión de SVN ... más ... si sigues la filosofía correcta
Lo que veo en la mayoría de las otras respuestas parece provenir de personas que no han usado SVN en mucho tiempo. Como alguien menciona con precisión: "no se solucionó lo suficientemente temprano como para disipar el mito".
Desde mi experiencia actual de usar SVN 1.6 a 1.8 en un proyecto heredado que heredé recientemente, SVN ha recorrido un largo camino para hacer que la fusión sea mucho más fácil. Sin embargo, no es infalible, y creo que no sufre fácilmente que los usuarios se desvíen del uso previsto.
Si bien conocía a SVN bastante bien y, mientras tanto, también había probado Mercurial para proyectos personales, nunca había hecho muchas ramificaciones en SVN antes de este proyecto. Hubo un poco de prueba y error y tuve muchos conflictos de fusión inesperados cuando comencé.
En última instancia, sin embargo, me di cuenta de que cada vez que recibía uno (u otro problema), era porque no había hecho las cosas correctamente (también conocido como "la forma SVN" - posiblemente, la forma correcta de control de versiones). Creo que aquí es donde radica la dificultad: no puedes hacer lo que quieras de una manera desorganizada y esperar que SVN funcione perfectamente, especialmente con fusiones. Las fusiones requieren una disciplina rigurosa de los usuarios antes de mostrar su verdadero poder.
Aquí hay cosas que he notado que son recomendaciones sólidas, si no requisitos, para un uso limpio de las fusiones:
Si no sigue lo anterior, es muy probable que tenga conflictos. Siempre son solucionables, pero no son terriblemente divertidos para pasar el tiempo.
Ah, una cosa más sobre la fusión donde, de todo lo que he leído y probado, SVN realmente apesta: archivos / carpetas eliminados / movidos / renombrados. Aparentemente , SVN todavía no puede lidiar con un archivo que se renombra, elimina o mueve en una rama, y su versión original se modifica en otra rama ... y luego se fusionan. Simplemente no sabrá a dónde se dirigió el archivo de una manera y "olvidará" los cambios de la otra manera. Obviamente, un cambio no tiene solución (puede eliminar o cambiar el archivo, no puede hacer ambas cosas), pero la aplicación de cambios a los archivos movidos / renombrados debería funcionar y no funciona. Esperemos que esto se arregle pronto.
Entonces, en general, ¿es fácil la fusión de SVN? Supongo que no. No de una manera despreocupada, seguro. ¿Es malo ? No lo creo. Solo te escupe en la cara cuando lo usas de manera incorrecta y no piensas lo suficiente sobre lo que estás haciendo.
Basado en esto, puedo ver por qué la gente podría preferir Mercurial (por ejemplo), ya que es un poco más indulgente con estas cosas desde mi experiencia y tenía todo automatizado desde el primer momento (al menos desde las primeras versiones con las que comencé). Sin embargo, SVN se ha recuperado bastante, por lo que ya no es digno de tanta embestida.
fuente
Los modelos de datos internos son fundamentalmente diferentes.
Básicamente, en SVN, cuando miras el historial de una rama, solo ves lo que ha sucedido en esa rama. Entonces, cuando se fusiona de rama
B
en ramaA
, el historial de la ramaA
contendrá una gran confirmación que contiene todos los cambios realizados explícitamenteB
desde que se bifurcó.En las primeras versiones de SVN, si tenía que fusionar una rama
B
enA
otra una vez más, tenía que especificar manualmente qué rango de revisión de la ramaB
quería fusionar para evitar fusionar las mismas revisiones dos veces. El desarrollador inteligente, por supuesto, usaría un mensaje de confirmación como 'Combinado en B: 1234'.SVN 1.5 "solucionó" esto. Pero no cambió cómo se aplican fundamentalmente las fusiones. Simplemente agregó algunos metadatos adicionales a la rama
A
, informando a SVN que la revisión 1234 se había fusionado, permitiendo que SVN elija automáticamente el rango de revisión correcto.Pero esta solución es básicamente una solución para un modelo de datos que fundamentalmente no admite el seguimiento de lo que se ha fusionado.
Fusionar dos ramas es un ejemplo relativamente simple. Pero imaginando este escenario más complejo
A
desde aquítrunk
y realiza algunas confirmaciones aquíB
deA
y hacer algunos hace aquítrunk
yA
B
entrunk
A
enB
A
entrunk
B
entrunk
(esto en realidad no debería hacer nada)Manejar esto correctamente usando el modelo de metadatos se vuelve extremadamente complejo (no sé si SVN realmente maneja este escenario correctamente, y no me siento inclinado a probarlo).
Manejar este escenario en git es extremadamente simple.
En git, cada vez que confirma, el objeto interno que representa esa confirmación contiene una referencia al encabezado anterior. Cuando se fusiona en una rama, la confirmación contiene referencias al encabezado anterior de todas las ramas que se fusionan (puede fusionar más de una rama a la vez en git)
Por lo tanto, cuando examina el historial de una sola confirmación en git, puede ver todo el historial, puede ver cuándo se ramificó, cuándo se fusionó y puede ver el historial de ambas ramas entre la ramificación y la fusión.
Por lo tanto, cuando se fusiona en una rama que se ha fusionado parcialmente, es extremadamente simple determinar qué se ha fusionado y qué no.
No tengo experiencia con Mercurial, pero sospecho que su funcionamiento interno es similar al de git.
Básicamente, para SVN, era un objetivo de diseño hacer que la ramificación fuera barata. Pero en git, era un objetivo de diseño hacer que la fusión fuera barata.
Por último, la última vez que utilicé SVN, no fue capaz de manejar fusiones, donde se cambió el nombre de un archivo en una rama y se modificó en otra.
fuente
He realizado una buena combinación de SVN, incluida una rama de desarrollo y lanzamiento de larga duración. En general sobreviví. La fusión siempre es complicada, pero con DCVS la desventaja no es terriblemente mala: todo es local, así que solo actualice a una buena revisión conocida y continúe. Mientras que con SVN sucedió mucho en el lado del servidor, la recuperación fue fea, por lo general, implicaba borrar la copia local y luego revisar una nueva rama limpia para volver a intentarlo. No fue malo en mi caso: una conexión gigabit a la caja SVN ayuda. Pero tuvimos algunos contratistas que tuvieron muchos problemas con esto ya que estaban en conexiones lentas, por lo que todo tomó una eternidad, incluidas las fusiones.
fuente
Aquí yace una de las cosas más bonitas de git. No es heredar sobre DVCS, es algo en lo que Git sobresale. Puede combinar revisiones específicas de cualquier rama en otra rama. Básicamente solo toma el diff y lo aplica a la otra rama, pero realiza el seguimiento y es mucho más automático.
Entonces, si tiene branch 2.0 y branch 3.0 y descubre un error en 2.0, puede solucionarlo en 2.0 y tomar el conjunto de revisiones que lo resuelven y fusionar solo esas revisiones en la rama 3.0. No creo que SVN tenga otra forma de hacerlo que no sea tomar manualmente los diferenciales para cada revisión y aplicarlos
Por supuesto, el algoritmo de fusión automática también parece funcionar mucho más suavemente y git se creó desde cero en el modelo "hacer una rama para todas las cosas", por lo que la ramificación es realmente suave y fácil. Parece natural ramificarse a menudo con lo livianas que son sus ramas.
fuente