2009-09-16 12 views
17

Tenemos una sucursal actual donde ocurre el desarrollo principal. Durante un tiempo he estado trabajando en algo así como experimental en una rama separada. En otras palabras, he ramificado lo que necesitaba de la rama Actual en una rama Experimental. Mientras trabajo, he combinado regularmente Current to Experimental para que tenga los cambios que otros han hecho, de modo que estoy seguro de que lo que hago funcionar con sus cambios.TFS: fusionándose nuevamente en la rama principal

Ahora quiero volver a unirme a Current. Primero fusioné Current en Experimental, compilé y me aseguré de que todo funcionara. Entonces, en mi cabeza, Experimental y Current deberían estar "sincronizados". Pero cuando trato de fusionar Experimental nuevamente en Current, recibo un montón de conflictos. Pero pensé que ya los había solucionado cuando fusioné Current into Experimental.

¿Qué está pasando? ¿He entendido mal algo por completo? ¿Cómo puedo hacer esto sin problemas? Realmente no quiero pasar por todos esos conflictos ...

Respuesta

22

Cuando hace clic en Resolver en un conflicto individual, ¿qué dice el mensaje de resumen? Si sus fusiones de Actual -> Experimental se completaron sin trabajo manual importante, debería ser algo así como "Fuente X, 0 objetivo, Y ambos, 0 en conflicto". En otras palabras, no hay bloques de contenido en el archivo de destino (Actual) que no estén ya en la copia de la rama de origen (Experimental). Puede usar de forma segura el botón AutoMerge All.

Nota: AutoMerge debe sea seguro independientemente. Está optimizado para ser conservador sobre las advertencias tempranas, no para la capacidad de resolver todos los casos. Pero reconozco que a muchos de nosotros, incluido yo mismo, nos gusta activar la herramienta de fusión cuando hay alguna pregunta. En el escenario descrito, IMO, incluso el más asustadizo puede descansar tranquilo.


¿Por qué hay un conflicto en absoluto?¿Y si el mensaje de resumen no es tan corta & seco? Me alegro de que me pregunte :) Respuesta corta: porque el cálculo que determina el ancestro común ("base") de los archivos relacionados depende en gran medida de cómo se resolvieron los conflictos de fusión anteriores entre ellos. Un simple ejemplo:

  1. estableció dos ramas, A y B.
  2. hacer cambios a A \ B \ foo.cs y foo.cs en partes separadas de los autos
  3. fusión A -> B
  4. AutoMerge el conflicto
  5. fusión B -> A

TFS debe marcar esta secuencia de eventos como contradictorios. El ancestro común más cercano entre B \ foo.cs; 4 y A \ foo.cs; 2 se encuentra en el paso 1, y obviamente ambos lados han cambiado desde entonces.

Es tentador decir que A & B están sincronizados después del paso 4. (Más precisamente: que el ancestro común para la fusión del paso 5 es la versión 2). Seguramente, una fusión de contenido exitosa implica que B \ foo.cs contiene todos los cambios realizados hasta la fecha. Por desgracia, hay una serie de razones por las que no se puede asumir esto:

  • Generalidad: no todos los conflictos pueden ser AutoMerged. Necesita criterios que se apliquen a ambos escenarios.

  • Corrección: incluso cuando AutoMerge tiene éxito, no siempre se genera un código válido. Un ejemplo clásico surge cuando dos personas agregan el mismo campo a diferentes partes de una definición de clase.

  • Flexibilidad: todos los usuarios de control de fuente tiene su propio favorito fusionar herramientas. Y necesitan la capacidad de continuar el desarrollo/prueba entre la decisión de resolución inicial ["necesidad de fusionar los contenidos de alguna manera, algún día"] y la comprobación final ["aquí, esto funciona"].

  • Arquitectura: en un sistema centralizado como TFS, el servidor simplemente no puede confiar en nada, pero su propia base de datos + requisitos de validación de la API. En tanto que la entrada cumple con las especificaciones, el servidor no debe tratar de distinguir cómo se realizaron varios tipos de fusiones de contenido. (Si cree que los escenarios hasta el momento se distinguen fácilmente, tenga en cuenta: ¿y si el motor AutoMerge tiene un error ¿Qué pasa si un cliente pícaro llama al servicio web directamente con el contenido del archivo arbitrarias Sólo arañando la superficie aquí ... servidores tienen que ser escépticos? por una razón!) Todo lo que puede calcular con seguridad es me has enviado un archivo resultante que no coincide con la fuente o el destino.

Poner estos requisitos juntos, usted termina con un diseño que agrupa nuestras acciones en el paso 4 en una bastante amplia categoría que también incluye fusiones manuales resultantes de las modificaciones superpuestas, fusiones de contenido [de auto o no] proporcionados por tercera herramientas de fiesta y archivos editados a mano después del hecho. En la terminología TFS, esta es una resolución AcceptMerge. Una vez registrado como tal, las Reglas de Fusión (tm) tienen que asumir lo peor en busca de la integridad histórica y la seguridad de las operaciones futuras. En el proceso, sus intenciones semánticas para el Paso 4 ("incorporar completamente en B cada cambio que se hizo a A en el n. ° 2") se redujeron a unos pocos bytes de lógica pura ("otorgue a B los siguientes nuevos contenidos + crédito por manejo # 2 "). Aunque es desafortunado, es "solo" un problema de UX/educación. La gente se enoja mucho más cuando las Reglas de Fusión crean suposiciones erróneas que conducen a la pérdida de datos y códigos rotos. Por el contrario, todo lo que tienes que hacer es hacer clic en un botón.

FWIW, hay muchas otras terminaciones en esta historia. Si elige Copiar desde la fuente de origen [aka AcceptTheirs] en el paso 4, no habría conflicto en el paso 5. Lo mismo si eligió una resolución de AcceptMerge pero pasó a cometer un archivo con el mismo hash MD5 como A \ foo.cs; 2 . Si elige Mantener objetivo [aka AcceptYours] en su lugar, las consecuencias posteriores cambian una vez más, aunque no puedo recordar los detalles en este momento. Todo lo anterior se vuelve bastante complejo cuando agregas otros tipos de cambios (especialmente Renombrar), fusionas ramas que están mucho más fuera de sincronización que en mi ejemplo, seleccionas ciertos rangos de versiones y te ocupo de los huérfanos más tarde, etc ...


EDITAR: como el destino lo tendría, alguien más acaba de hacer exactamente la misma pregunta en el foro de MSDN. Como tiende a ser mi naturaleza, les escribí otra respuesta larga que salió completamente diferente. (aunque obviamente tocando los mismos puntos clave) Espero que esto ayude: http://social.msdn.microsoft.com/Forums/en-US/tfsversioncontrol/thread/e567b8ed-fc66-4b2b-a330-7c7d3a93cf1a

+0

Woah, explicación buena y completa. No estoy seguro de si lo entiendo completamente, pero supongo que es por eso que no estoy en el equipo de TFS: P De todos modos, tiene sentido que no sea tan simple como yo quería: PI terminó teniendo que pasar por todos ellos . Algunos de ellos fueron conflictos de cambio de nombre, donde simplemente me pidieron que eligiera una de las alternativas. Los otros fueron un poco más complejos. Pero parece estar funcionando ahora :) – Svish

+0

Publiqué otra explicación, con suerte menos confusa :) –

3

Esto me ha pasado antes. Cuando TFS fusiona Experimental con Current, lo hace utilizando los espacios de trabajo en su disco duro. Si su área de trabajo Actual no está actualizada en su computadora local, TFS obtendrá conflictos de combinación.

(Experimental en HD)! = (Actual en TFS)! = (Antiguo actual en HD)

Trate de hacer un encuentro forzado de corriente para refrescar la coppy local actual y tratar la fusión de nuevo.

+0

Intenté eso, pero no pareció ayudar nada. – Svish

+0

Buena conjetura, sin embargo. Esto definitivamente puede causar síntomas como el de Svish. –

0

Es probable que tenga líneas de este tipo antes de empezar la fusión ...

  • rama principal - Contiene código A, B, C
  • rama actual - Contiene código A, B, C, D, E
  • rama experimental - Contiene código a, B, C, D, F, G, H

Cuando se presiona de corriente a Exp, que se están fusionando función E en la rama experimental.

Cuando pase de Exp a Current, aún debe fusionar F, G y H. Aquí es donde sus conflictos probablemente estén enraizados.

---- Respuesta al 1er comentario ---- ¿Se fusiona automáticamente, o usa la herramienta de combinación? ¿Qué es un ejemplo de algo que está "en conflicto"?

+0

Solo tengo dos ramas. Y, para continuar con su ejemplo, ya he combinado Current en Experimental, de modo que Experimental también contenga E. Entonces no debería haber conflictos, solo código nuevo. Si eso tenía sentido ... – Svish

+0

Intenté fusionar automáticamente cuando era posible, pero no fue siempre así. – Svish

Cuestiones relacionadas