2008-11-29 13 views
15

He estado usando TortoiseSVN, svn y subclipse y creo que entiendo lo básico, pero hay una cosa que me ha estado molestando por un tiempo: la fusión introduce código no deseado. Aquí están los pasos.Subversion: ¿Cómo fusionar solo revisiones específicas en trunk cuando se hacen múltiples cambios consecutivos en una rama?

trunk/[email protected]. Un archivo de prueba fue creado con 'A' y un retorno:

A 
[EOF] 

branches/TRY-XX-Foo/[email protected]. Diversificado la trunk a TRY-XX-Foo:

A 
[EOF] 

branches/TRY-XX-Foo/[email protected]. Hecho un cambio no deseado en TRY-XX-Foo y cometido:

A 
B (unwanted change) 
[EOF] 

branches/TRY-XX-Foo/[email protected]. Hecho una importante corrección de errores en TRY-XX-Foo y cometido:

A 
B (unwanted change) 
C (important bug fix) 
[EOF] 

Ahora, me gustaría fusionar sólo el fallo importante fijar nuevo en el tronco. Por lo tanto, ejecuto merge para la revisión 4:5. Lo que termino en mi directorio de trabajo es un conflicto.

trunk/test.txt:

A 
<<<<<<< .working 
======= 
B (unwanted change) 
C (important bug fix) 
>>>>>>> .merge-right.r5 
[EOF] 

En contra de mi voluntad, Subversion ahora ha incluido "cambio no deseado" en el código tronco, y tengo que eliminar a cabo de forma manual. ¿Hay alguna forma de fusionar solo las revisiones especificadas cuando se realizan varios cambios consecutivos en la rama?

La parte del problema es que B (cambio no esperado) está incluido en .merge-right y no puedo distinguir la diferencia de la revisión de la que proviene. Usualmente uso TortoiseMerge y así es como se ve.

text.txt.working

+2

Para hacer una prueba más realista, debe agregar un poco de 'contexto' entre las líneas que cambia. Las herramientas textuales diff y merge necesitan unas pocas líneas de contexto entre los cambios para realizar fusiones automáticas. Cuando el contexto no es lo suficientemente grande, verá el conflicto como se muestra en su último ejemplo. –

+0

@Bert: por favor ponlo como respuesta, para que pueda ser votado. Creo que tienes un punto aquí. –

+0

puede editar el ancho de su imagen, está tirando del texto de las preguntas. –

Respuesta

5

El problema es que tanto svn

A 
<<<<<<< .working 
======= 
B (unwanted change) 
C (important bug fix) 
>>>>>>> .merge-right.r341 

y TortoiseSVN es tratar la situación como de 2 vías de mezcla. He oído hablar del término fusión de 3 vías, así que di una oportunidad al Beyond Compare. Con la configuración rápida con TortoiseSVN, Editar Conflicto ahora muestra la siguiente pantalla. Esto no es perfecto, ya que todavía requiere la intervención humana, pero al menos puedo decir qué cambios vienen de dónde.

See screenshot.

+0

Al utilizar la vista de fusión de subclipse, puede habilitar la vista original, que le brindará la vista de combinación de tres vías. Verifique la esquina superior derecha. –

+0

Por favor, ponga esta información en su pregunta, porque esta es una respuesta. – guerda

+1

@guerda, estoy publicando el uso de la herramienta de combinación de 3 vías como una respuesta. –

35

La fusión sólo revisiones 4,7 y 11-15 con svnmerge:

svnmerge.py merge -r4,7,11-15 

Y con SVN normal:

svn merge -c4,7 -r10:15 http://.../branches/TRY-XX-Foo 
+0

Ejecutar desde la línea de comandos todavía produce el mismo resultado que TortoiseSVN, causando conflictos y tirando de cambios no deseados. –

+0

Lo siento, supongo que no entiendo tu situación. Selecciones de cosecha de cerezas para fusionar trabajos tal como lo muestro (y evidentemente, como lo intentó), no estoy seguro de cuál es el problema. – orip

+0

La respuesta de Orips debe ser correcta y le dará el resultado que desea. Tal vez no dejaste la revisión 5 en tu declaración de línea de comandos. Entonces, obviamente, llevarías el cambio a la fusión. – boutta

0

Si no quieren los no deseados cambie, no combine la revisión 4: 5, pero solo la revisión 5. Significa que fusiona el cambio cometido en la revisión 5.

+0

4: 5 significa tomar la diferencia entre 4 y 5 y aplicarla al directorio de trabajo. He intentado con la opción de línea de comando -c5, pero el resultado es el mismo. –

1

Otra cosa que podría hacer sería deshacer manualmente la confirmación incorrecta en la rama, lo que le permitiría fusionar la rama nuevamente en el tronco como lo haría normalmente.

TortoiseSVN

utilizando TortoiseSVN se abre la vista de registro en un archivo, seleccione la versión infractor, y elija "Revertir cambios de esta revisión" en el menú del botón derecho. Confirme los cambios que realiza en su copia de trabajo y luego puede fusionar la rama fácilmente.

línea de comandos

Para hacer esto con el cliente de línea de comandos se realiza una fusión inversa, (Esto se toma del control de origen pragmático usando el libro de Subversion), donde se fusionan los cambios entre la versión de la delincuencia y la versión anterior en la copia de trabajo del archivo. Entonces, como arriba, comprometerías los cambios y luego puedes ramificar normalmente. En el ejemplo, usted haría algo como:

svn merge -r 4:3 test.txt 
+0

Deshacer no es una opción ya que los cambios no deseados en las ramas/TRY-XX -Foo/representa características medio cocidas, no listas para fusionarse en el tronco. –

2

Creo que está incluyendo las revisiones que desea correctamente, pero el algoritmo de combinación está fallando para encontrar el lugar para insertar el cambio deseado y por lo que incluir la línea anterior también . Aquí son los mismos pasos, pero con un conjunto diferente de los cambios, y creo que funciona como se esperaba originalmente:

 
$ svnadmin create repo 
$ svn mkdir -m '' file://`pwd`/repo/trunk 

Committed revision 1. 
$ svn mkdir -m '' file://`pwd`/repo/branches 

Committed revision 2. 
$ svn co file://`pwd`/repo/trunk co.trunk 
Checked out revision 2. 
$ cat > co.trunk/test.txt << EOF 
> A 
> B 
> C 
> EOF 
$ svn add co.trunk/test.txt 
A   co.trunk/test.txt 
$ svn commit -m '' co.trunk 
Adding   co.trunk/test.txt 
Transmitting file data . 
Committed revision 3. 
$ svn copy -m '' file://`pwd`/repo/trunk file://`pwd`/repo/branches/testbr 

Committed revision 4. 
$ svn co file://`pwd`/repo/branches/testbr co.testbr 
A co.testbr/test.txt 
Checked out revision 4. 
$ cat > co.testbr/test.txt << EOF 
> A 
> A1 unwanted 
> B 
> C 
> EOF 
$ svn commit -m '' co.testbr 
Sending  co.testbr/test.txt 
Transmitting file data . 
Committed revision 5. 
$ cat > co.testbr/test.txt << EOF 
> A 
> A1 unwanted 
> B 
> B1 wanted 
> C 
> EOF 
$ svn commit -m '' co.testbr 
Sending  co.testbr/test.txt 
Transmitting file data . 
Committed revision 6. 
$ svn merge -r 5:6 file://`pwd`/repo/branches/testbr co.trunk 
--- Merging r6 into 'co.trunk': 
U co.trunk/test.txt 
$ cat co.trunk/test.txt 
A 
B 
B1 wanted 
C 
1

como se ha señalado por otros usuarios (no voy a tomar el crédito para darse cuenta de ello, porque yo no' t), puede ser la naturaleza trivial de esta fusión (es decir, la falta de contexto en torno al cambio) lo que confunde las herramientas.

Hago mucha fusión y, como descubriste, la herramienta de fusión proporcionada por Tortoise es horrible. Una herramienta de combinación de tres vías es una necesidad absoluta si haces esto muy a menudo. Beyond Compare es mi favorito personal, pero hay otros que son gratuitos (Meld, KDiff3) y otros que no (Araxis).

Notarás que Beyond Compare hizo lo correcto al final, incluso si hace que verifiques manualmente su corrección.

+0

La falta de contexto es sin duda la clave, por lo tanto, "múltiples cambios consecutivos". –

2

Bueno, para aclarar algo acerca de la fusión es que en realidad tiene 2 pasos.

  1. Combinar
  2. Commit

Por lo que significa que después de su fusión se lleva a cabo, se puede hacer un diff Manual contra la cabeza y la otra rama para asegurarse de que la fusión era correcta. Y si algo anda mal con él, como en su caso, , puede corregirlo manualmente antes de la confirmación.

/Johan

2

En TortoiseSVN, sólo debe especificar las revisiones que desea fusionar. A diferencia del cliente de línea de comando donde debe especificar, p. -r4: 5 para fusionar los cambios entre r4 y r5, solo tiene que especificar '5' como el número de revisión para combinar en el diálogo de fusión de TortoiseSVN. Si no está seguro, utilice siempre el diálogo de registro en el cuadro de diálogo de fusión y seleccione las revisiones que desea fusionar en ese diálogo de registro (luego haga clic en Aceptar y las revisiones seleccionadas se establecerán automáticamente en el cuadro de diálogo de fusión).

En cuanto a la resolución de su conflicto en TortoiseMerge: De acuerdo con la captura de pantalla en su pregunta, TortoiseMerge le muestra dos líneas en conflicto (las que se muestran como '????' en la vista inferior). Lo que quiere es incluir el cambio 'C' pero no 'B'?

  • haga clic en la primera '???' línea para seleccionarlo, luego haga clic derecho, elija 'usar bloque de' mina '' desde el menú contextual
  • haga clic izquierdo sobre el segundo '???' línea para seleccionarlo, luego haga clic derecho, elija 'usar bloque de' ellos '' del menú contextual
  • Haga clic en el botón Guardar (o Archivo-> Guardar)
  • Opcionalmente haga clic en el botón "Marcar como resuelto"
+0

Antes que nada, gracias por la gran herramienta. He estado al día con las actualizaciones de TortoiseSVN, así que sé que debes especificar 5, en vez de 4-5. –

+0

En este ejemplo simplificado, es fácil decir la parte "no deseada", pero Subversion no debería haber provocado ningún cambio desde r4. En realidad, es difícil decir qué parte proviene de la revisión no deseada que no especifiqué. Frecuentemente fusiono cambios de ramas escritos por otros. –

+0

Bueno, Subversion en realidad no fusionó r4. El problema que está viendo aquí es que Subversion encontró un conflicto, y para indicar ese conflicto, no solo marca las líneas en conflicto, sino también una línea alrededor de las líneas en conflicto (es decir, líneas de contexto). Si tuviera una línea D, esa línea también se incluiría – Stefan

Cuestiones relacionadas