versiones usar tortoise subversion que informatica español control como svn version-control merge mergeinfo

usar - ¿Cuál es el uso real de SVN de mergeinfo?



tortoise svn server (3)

Hay dos tipos de fusión en Subversion:

  1. Combinación de tres puntos
  2. Combinación de dos puntos (también conocida como fusión de reintegración)

Digamos que estás trabajando en trunk, y tienes una característica particular que debe hacerse. Usted crea una rama de Característica A. A medida que trabaja en la función, desea que el trabajo que realiza en el tronco se incluya en la Característica A , para que pueda mantenerse al día con lo que hacen los demás. Subversion utilizará una fusión de tres puntos.

Subversion verá la diferencia entre la característica A del tronco y la sucursal desde el punto en que ocurrió la bifurcación. El ancestro común más reciente. A continuación, considera todos los cambios en la Característica A que se realizó (que no desea tocar), así como los cambios en el código hecho en el enlace troncal.

Subversion fusionará los cambios en el enlace troncal sin sobrescribir los cambios realizados en la sucursal. Procedimiento de fusión estándar, y Subversion lo hace bastante bien.

¿Dónde entra svn:mergeinfo ? No desea fusionar dos veces los mismos cambios, por lo que Subversion realiza un seguimiento de los cambios con la propiedad svn:mergeinfo . Si Subversion ve que el cambio en el tronco de la Revisión 5 ya se ha fusionado, no volverá a cambiar ese cambio. Es muy bueno con esto.

Ahora ha terminado con su función y desea que esos cambios se vuelvan a fusionar en el enlace troncal. Realiza una última fusión de enlace a enlace, confirma esos cambios y ahora se fusiona de la rama de funciones de nuevo en el enlace troncal.

Aquí hay un pequeño problema. Rastreamos lo que fusionamos desde el svn:mergeinfo troncal en la rama Característica a través de svn:mergeinfo . Sin embargo, dado que no hemos fusionado desde la rama Feature a trunk, no hay allí svn:mergeinfo . Si intentamos una combinación normal de tres puntos desde la rama de características en el enlace troncal, el enlace troncal supondrá que todos los cambios en la rama de características se fusionarán nuevamente en el enlace troncal. Sin embargo, muchas de esas características son en realidad cambios de troncales que se han fusionado.

A decir verdad, en este punto, queremos hacer una fusión de dos puntos. Queremos que el tronco y la rama de características coincidan exactamente una vez que hacemos la fusión. Después de todo, hemos estado fusionando trunk en la rama Feature de forma regular ahora. Lo que queremos hacer es incorporar esas características de nuevo en el maletero. Por lo tanto, el tronco será el mismo que la rama de características.

Antes de Subversion 1.8, tendrías que forzar una fusión de reintegración ejecutando svn merge --reintegration . Ahora, Subversion analizará el historial de fusiones y descubrirá cuándo se debe realizar una fusión de reintegración.

Ahora aquí está la parte difícil. Eche un vistazo cuidadoso a los números de revisión. ¡Estos serán muy, muy importantes!

  • Revisión 10 : Hice mis cambios finales en Trunk, y necesito fusionarlos en la rama Feature.
  • Revisión 11 : fusiono el tronco en la rama Característica. svn:mergeinfo mostrará que todo el troncal de la Revisión 1 a la Revisión 10 se encuentra en la rama de Característica. Como el último cambio en el baúl es la Revisión 10, tiene mucho sentido.
  • Revisión 12 : fusiono la revisión 11 de la rama de características en el enlace troncal. Esta es una fusión de reintegración . Después de esto, lo que está en la rama de características y lo que está en el tronco debe estar perfectamente de acuerdo.

Ahora, aquí está el pateador!

  • Revisión 13 : hago otro cambio en el maletero.

Ahora, quiero fusionar esto en mi rama de funciones (creando la Revisión 14). Ahora, ¿qué dice svn:mergeinfo en la rama de características? Dice que el tronco de la Revisión 1 a la Revisión 10 se ha fusionado en la rama de Característica. Sin embargo, la Revisión 12 y la Revisión 13 del tronco no han sido. Por lo tanto, Subversion querrá fusionar la revisión 12 y la revisión 13 de nuevo en la rama de características.

¡Pero espera un segundo!

¡La revisión 12 en el enlace troncal fue mi combinación de todos los cambios en mi rama de funciones de vuelta al tronco! Es decir, la Revisión 12 ya contiene todos los cambios de revisión que hice en mi rama de funciones. Si fusiono la Revisión 12 en mi rama de Funciones, diré que todos estos cambios en la Revisión 12 en el enlace troncal (que en realidad fueron cambios realizados en la rama de características y se fusionaron en el enlace troncal) deben fusionarse en la rama de características. Pero estos cambios también se realizaron en la rama de características. ¿Puedes decir Merge Conflict? ¡Sabía que podrías!

Hay dos formas de manejar esto:

  • La forma recomendada : una vez que reintegre la rama de su función nuevamente en el tronco, elimine la rama. Ciérralo. Nunca lo vuelvas a usar No toques! Esto no es tan malo como parece. Después de la fusión de reintegración, su troncal y esa rama de características coincidirán de todos modos. Eliminar y volver a crear la rama del tronco no será tan malo.
  • La manera engañosa que funciona : lo que tenemos que hacer es engañar a Subversion para que piense que la Revisión N. ° 12 (o los cambios de fusión de reintegración) ya se había fusionado en nuestra rama de Funciones. Podríamos jugar con la propiedad svn:mergeinfo . Y, yo solía hacer eso. Donde dice trunk:1-11 , lo cambiaría manualmente a trunk:1-12 .

    Esto es complicado, pero demasiado complicado y arriesgado porque Subversion ya te permite manipular el svn:mergeinfo sin cambiarlo manualmente.

Se llama fusión de registro único .

$ svn co svn://branches/feature_a $ cd feature_a $ svn merge --record-only -c 12 svn://trunk $ svn commit -m "Adding in the reintegration merge back into the feature branch."

Esto cambia el svn:mergeinfo en la rama de características sin afectar el contenido real de los archivos. No se realiza una fusión real, pero ahora Subversion sabe que la Revisión 12 de trunk ya se encuentra en la rama de características. Una vez que lo hagas, puedes reutilizar la rama de características.

Ahora mira tu diagrama: cuando fusionaste la Rama B en la Rama A, fusionaste todos los cambios de B a A, y svn:mergeinfo rastreó eso. Cuando fusiona la Rama B de nuevo en la Rama A, ya tiene todos los cambios de la Rama B en la Rama A, y no desea que estos cambios sean devueltos a la rama B. Debería haber usado una fusión de reintegración :

$ cd $branch_a_working_dir $ svn merge $REPO/branches/B $ svn commit -m "Rev 7: All of my changes on Branch B are now in A" $ vi d.txt $ svn add d.txt $ svn commit -m"Rev 8: I added d.txt" $ cd $branch_b_working_dir $ svn merge --reintegrate svn://branch/A # Note this is a REINTEGRATION merge! $ svn commit -m"Rev 9: I''ve reintegrated Branch A into Branch B

Ahora, si queremos continuar usando la rama A para más cambios:

$ cd $branch_a_working_dir $ svn merge -c 9 --record-only $REPO/branches/b $ svn commit -m"I''ve reactivated Branch A and can make further changes"

Espero que esto explique un poco sobre cómo funciona svn:mergeinfo , por qué tienes que saber si estás usando la fusión normal de tres puntos vs. la fusión de reintegración de dos puntos, y cómo ser capaz de reactivar una rama después de que '' he hecho una fusión de reintegración.

Siempre que tengas esto en cuenta, la fusión de Subversion funciona bastante bien.

Hace tiempo que oigo hablar de los problemas de conflicto de combinación de svn.

Me sentí aliviado, pensé, cuando supe que svn hace un par de lanzamientos implementó una función llamada mergeinfo . Casi parecía como si su introducción le permitiera a svn tener suficiente información para resolver sus problemas de fusión cada vez que aparecían. Hasta que llegué a la siguiente situación:

Ejemplo con guiones del gráfico anterior:

SVN=${SVN:-svn} SVNADMIN=${SVNAMDIN:-svnadmin} rm -rf repo wc $SVNADMIN create repo $SVN co file://$PWD/repo wc cd wc # r1 $SVN mkdir trunk branches $SVN ci -m ''structure'' $SVN up # r2 echo 2 > trunk/t.txt $SVN add trunk/t.txt $SVN ci -m ''add t.txt'' $SVN up # r3 $SVN cp trunk branches/A $SVN ci -m ''create branch A'' $SVN up # r4 echo 4 > branches/A/a.txt $SVN add branches/A/a.txt $SVN ci -m ''add a.txt'' $SVN up # r5 $SVN cp trunk branches/B $SVN ci -m ''create branch B'' $SVN up # r6 echo 6 > branches/B/b.txt $SVN add branches/B/b.txt $SVN ci -m ''add b.txt'' $SVN up # r7 $SVN merge ^/branches/B branches/A $SVN ci -m ''merge branch B into A'' $SVN up # r8 echo 8 > branches/A/d.txt $SVN add branches/A/d.txt $SVN ci -m ''add d.txt'' $SVN up # r9 $SVN merge ^/branches/A branches/B

Si svn está guardando el historial del origen de cada rama, ¿por qué no puede entender que b.txt se haya tocado en la branch A ?

si no puede resolver esto, ¿qué uso real hace svn de mergeinfo ?

Si svn no puede resolver este problema, ¿no sería posible crear una herramienta para ayudarme (es decir, resolver automáticamente este tipo de problemas obvios ...) en este frente? ¿Supongo que quizás uno ya existiría?

Gracias


Usted malinterpretó el significado y el uso de mergeinfo: solo contiene ya (para este nodo) revisiones combinadas y orígenes de fusión para no fusionar la revisión dos veces, nada sobre el contenido


La respuesta de David W. es bastante buena, pero voy a proporcionar mi propia respuesta que responda a esto desde un enfoque más moderno. Lo que David te dice es verdad y es útil entender su respuesta al leer mi respuesta, por lo que deberías leer la primera si aún no lo has hecho. Mi respuesta proporciona una comprensión más moderna del problema y las soluciones a los problemas que David señala.

Entonces, ante todo, la respuesta simple es que la situación que presentas funciona bien si usas Subversion 1.8. El script de ejemplo que agregué a la pregunta no tiene un conflicto cuando se ejecuta con Subversion 1.8. Solo el cliente necesita ser actualizado para obtener esta funcionalidad.

La respuesta más larga aquí es que con versiones anteriores de Subversion necesita saber cuándo usar la opción mal llamada --reintegrate (1.8 se da cuenta de esto por usted). A pesar del nombre, --reintegrate no es solo para cuando reinsertas una rama a tu tronco.

Uno de los problemas recurrentes que tienen las personas cuando utilizan ramas de características es que desean fusionar la rama de características de nuevo a su troncal y luego continuar utilizando la rama. Como sugiere la respuesta de David en el pasado, había dos métodos para lidiar con eso. Antes que nada borre la rama y luego vuelva a hacerla fresca. En segundo lugar, solo registra fusiones. Julian Foad, uno de mis compañeros desarrolladores de Subversion, cuando trabajaba para 1.8 se dio cuenta de que ninguna de estas dos técnicas era necesaria. Cubrió esto en su presentación sobre la fusión en la conferencia Subversion Live 2012 . Las diapositivas para su presentación están disponibles en línea aquí (tenga en cuenta que este es un PDF de todas las diapositivas para la conferencia, por lo que no es exactamente pequeño), la parte sobre este problema comienza en la página 123.

Para resumir su presentación, el flujo de trabajo típico de la rama de características es crear una ramificación fuera del tronco. Realice confirmaciones en su rama de características y fusione periódicamente desde el enlace troncal a su rama de características para sincronizar con lo que está en el svn merge ^/trunk $BRANCH_WC troncal, por ejemplo, svn merge ^/trunk $BRANCH_WC . Luego, cuando esté listo para fusionarse de nuevo con el tronco, usted svn merge --reintegrate ^/branches/myfeature $TRUNK_WC . Ahora está en el punto en que la sabiduría tradicional era que tenía que eliminar su rama de características o hacer una fusión de solo registro. En cambio, Julian descubrió que simplemente podía continuar usando la sucursal si seguía estas reglas.

  • Cada vez que se fusiona en la misma dirección que la última combinación entre las dos ramas, NO usa la opción --reintegrate . Trate la creación de la rama como una fusión de esa ubicación creadora.

  • Cada vez que cambias las direcciones que estás fusionando entre las dos ramas, utiliza --reintegrate para esa combinación.

En su caso específico, está cambiando las direcciones de las que se ha estado fusionando. r7 se está fusionando de la rama B a la rama A. r9 se fusiona de la rama A a la rama B. Por lo tanto, cuando vaya a hacer la fusión r9, debe usar --reintegrate . Esta lógica es exactamente lo que Subversion está haciendo por usted con 1.8.

Finalmente, no recomiendo fusionarse entre ramas hermanas como lo está haciendo aquí. Una gran cantidad de casos simples como lo que estás haciendo aquí van a funcionar bien. Sin embargo, si, por ejemplo, divide un archivo (archivo svn cp file file2 , elimina parte del archivo1 y una parte diferente del archivo2), entonces se encontrará con problemas cuando intente fusionar la última de las dos ramas características en el tronco. (suponiendo que haya combinado la división con ambas ramas de hermanos). Lo mejor es restringir la fusión para que esté entre dos ramas (hijo y padre). Puede hacer que las ramas se separen de otras ramas y fusionarse de nuevo con sus padres antes de ir al padre de los padres, y así sucesivamente y estar bien. Nos gustaría hacer que incluso este tipo de cosas funcionen correctamente en el futuro, pero esta es la situación actual en 1.8 (mucho mejor que en el pasado pero no tan buena como nos gustaría).