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 rama A
, el historial de la rama A
contendrá una gran confirmación que contiene todos los cambios realizados explícitamente B
desde que se bifurcó.
En las primeras versiones de SVN, si tenía que fusionar una rama B
en A
otra una vez más, tenía que especificar manualmente qué rango de revisión de la rama B
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
- Crea una rama
A
desde aquí trunk
y realiza algunas confirmaciones aquí
- Crear rama
B
de A
y hacer algunos hace aquí
- Hacer algunas confirmaciones
trunk
yA
- Fusionarse
B
entrunk
- Fusionarse
A
enB
- Fusionarse
A
entrunk
- Combinar
B
en trunk
(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.