2009-12-07 18 views
46

Tenemos una arquitectura de rama estándar donde tenemos una rama de desarrollo para cada equipo, una rama de integración común (desde donde todas las ramas de desarrollo están ramificadas) y una rama de producción ramificada desde Integración.TFS: mejores prácticas de combinación

Durante la fase de desarrollo hago muchos commits en la rama de desarrollo. Al final de la fase, fusiono mis cambios a la integración y luego a la producción.

¿Tiene sentido fusionar cada confirmación individualmente, copiar la descripción original de confirmación y vincularla a la tarea original? Otra opción es, por supuesto, fusionar todas las confirmaciones a la vez, con una sola operación de fusión. El motivo de mi pregunta es que la primera forma lleva mucho tiempo. No veo ninguna herramienta de automatización en TFS que vincule el enlace en otra rama con la confirmación original.

Me gustaría conocer su opinión sobre las mejores prácticas.

Respuesta

73
  1. Fusiona desde Dev * -> Integración e integración -> La producción siempre debe ser de "copia". Esta es la forma más segura de preservar la estabilidad de las ramas descendentes.
    1. Primero combine en la otra dirección (por ejemplo, Integración -> Dev2) para recoger los últimos cambios de la rama de destino.
    2. Si hay conflictos, maneje los diffs caso por caso. Por lo general, AcceptMerge (ya sea automático o manual) es el resultado deseado, pero a veces querrá tomar sin cambios la copia de una o de la otra rama.
    3. Utilice la rama de fuente (Dev # 2 en nuestro caso) para incorporar, reaccionar y estabilizar completamente estos cambios.
    4. Combínelo en la dirección deseada (por ejemplo, Dev2 -> Integración). Resuelva todos los conflictos como AcceptTheirs [aka "copy from source"].
    5. Asegúrese de que no haya cambios en la rama de destino entre los pasos 1 a 4. Si la rama Dev está aceptando se fusiona temprano & a menudo, como debería ser, entonces no debería ser una carga para bloquear la rama de destino durante este proceso con esperanza de corto. Si anticipa una fusión del "Big Bang" de la muerte por la razón que sea, existe una probabilidad decente de bloquear a otros equipos que hagan lo mismo en paralelo, por lo que es posible que tenga que repetir repetidamente los pasos 1 a 4 hasta que esté listo .
  2. Hacer "ponerse al día" se funde siempre que sea posible. Es decir, combine las cosas en el mismo orden en que fueron registradas. Si los conjuntos de cambios 10, 20 y 30 son candidatos para fusionarse de A -> B, entonces cualquiera de estos intervalos de fusión es un "catch-up": 10 ~ 10, 10 ~ 20, 10 ~ 30. Cualquier rango de conjuntos de cambios que omita el número 10 se conoce como "selección de cereza"."Una vez que comience cherry picking se encuentra con unos riesgos:.
    1. No se puede utilizar el modelo descrito anteriormente merge down, copy up Sólo por eso, Laura Wingerd diría que está saltando por encima de un bordillo
    2. Si cualquiera. de los archivos tocados en su rango también se tocaron anteriormente, tendrá que hacer una fusión de contenido de 3 vías para que solo se propaguen los difficios escogidos. Ninguna herramienta de diferencias es perfecta; está agregando un riesgo distinto de cero de traer más de código de lo previsto, sobrescribiendo accidentalmente los cambios realizados en el destino, introduciendo errores de lógica donde divergen las dos ramas, etc.
    3. El conjunto de cambios que promociona en la rama supuestamente más estable representa una configuración que t tiene nunca ha sido construido o probado antes. Puede hacer una aproximación decente sobre el estado final de la rama objetivo. "Estoy fusionando todos los cambios que afectan a Module Foo, y probé la nueva versión de Foo en Dev, así es como se comportará Foo en Integration, ¿verdad?" Claro ... tal vez ... si puedes rastrear cada dependencia en tu cabeza (incluyendo todo lo que puede haber cambiado en Integración mientras probabas Dev). Pero estas suposiciones de ninguna manera son conocidas o validadas por su cadena de herramientas SCM.
    4. En TFS específicamente, la selección de cerezas donde los cambios del espacio de nombres están involucrados es solo pedir que se queme. Si su alcance de versión y/o alcance de ruta excluye el origen de un cambio de nombre, en su lugar aparecerá como una bifurcación. Si excluye el objetivo, colgará una eliminación. Si el alcance de tu ruta no incluye la raíz de una recuperación, obtendrás errores crípticos. Si su rango abarca un tiempo entre un borrado de &, obtendrá archivos "fantasmas" que aparecerán en el destino, incluso si no incluye el propio borrado. Si fusiona Moves con todos los accesos de versión de ruta & correctos, pero lo hace fuera de orden, es posible terminar con un nombre de destino diferente al nombre de origen incluso después de que se hayan agotado todos los conjuntos de cambios candidatos. Estoy seguro de que hay más maneras de que este combo salga mal y que ahora mismo no me venga a la mente ... solo confía en mí.
  3. Siempre haga un Get en la rama de destino antes de la fusión. Versión avanzada para máxima seguridad: sincronice el espacio de trabajo donde se fusionará con un número de conjunto de cambios específico que esté en o cerca de la propina, y luego [catch-up] se fusione con ese mismo conjunto de cambios. Si lo hace, evita algunos problemas potenciales:
    1. fusionando en código rancio, dando confusas diferenciaciones de 3 vías que parecen eliminar cambios de lo que ves en la punta. [eventualmente los recuperaría con Checkin + Resolve, pero no hay razón para pasar por dos riesgos arriesgados cuando puede evitar ambos]
    2. Tener que pasar por el proceso de resolución de conflictos dos veces: una vez en Merge, una vez en Checkin. No hay forma de evitar esto en el caso general, pero la mayoría de las veces el número de cambios simultáneos realizados mientras fusiona + resuelve es pequeño en comparación con el número de cambios que encontraría en un área de trabajo que podría durar días o semanas. fecha.
  4. No combine por etiqueta (o espacio de trabajo) a menos que realmente sepa realmente lo que está haciendo. Repasemos las características ofrecidas por las etiquetas TFS y luego analicemos por qué cada una es inapropiada para la fusión segura &.
    1. Las etiquetas pueden representar varios puntos en el tiempo. Si una etiqueta representa una instantánea consistente del VCS, y siempre fue diseñada como tal, entonces no tiene ventaja técnica sobre una fecha o un conjunto de cambios #. Desafortunadamente, es bastante difícil saber si una etiqueta es consistente a lo largo del tiempo.Si no es así, la fusión por etiqueta puede llevar a:
      1. inadvertida cherry picking, si el rango comienza con una etiqueta que apunta a un elemento @ un momento antes de su primer candidato
      2. exclusión inadvertida, si se inicia la gama con una etiqueta que señala a un elemento @ a tiempo por delante del extremo de la gama
      3. exclusión inadvertida, si el rango termina con una etiqueta que apunta a un elemento @ a tiempo antes del comienzo de la gama
    2. Las versiones de etiquetas representan un conjunto específico de elementos. Se pueden usar para excluir deliberadamente archivos y carpetas que, de lo contrario, verían una consulta recursiva pura. Esta función también es una mala combinación para las operaciones de fusión. (Y de nuevo, si no lo hace necesita esta capacidad, que está incurriendo el siguiente riesgo sin ganar nada sobre fechas & conjuntos de cambios.)
        serán simplemente ignorados
      1. Los productos que no están presentes en la etiqueta, en lugar de fusionarse como eliminaciones pendientes A diferencia de algunos de los casos límite cubiertos hasta el momento, este es un gran problema que es bastante probable que suceda en los escenarios convencionales, sin embargo, la mayoría de la gente se pierde. [Como resultado, TFS 2010 agrega compatibilidad con los elementos eliminados dentro de las etiquetas.]
      2. Recorte inadvertido, si agrega un elemento a la etiqueta que ha estado presente por un tiempo pero fue excluido de las fusiones previas debido a uno de los lados mencionados efectos.
      3. Intencional recolección de cereza. Toda la ventaja que aporta esta característica a Merge es romper una de nuestras directrices, por lo que obviamente no es una buena razón para nada. Además, causa un "cherry picking" en el nivel , que es incluso más peligroso que el picking "ordinario" por changeset.
    3. Las etiquetas tienen nombres personalizables, propietarios, y comentarios. Por lo tanto, tenemos una diferencia de usabilidad pura frente a fechas/conjuntos de cambios; no se concede ninguna ventaja técnica. Pero incluso aquí no es tan atractivo como parece. TFS no hace mucho para que realmente aparezcan las etiquetas en la interfaz de usuario, mientras que puedes ver los comentarios de los conjuntos de cambios en cualquier lugar. La consulta por parte del propietario es rápida (en el lado del servidor), pero la mayoría de las otras búsquedas son lentas (en el lado del cliente) a menos que conozca el nombre exacto de la etiqueta. Las instalaciones de gestión son prácticamente inexistentes. Sin registro de cambios ni auditoría, solo una marca de tiempo. En total, estas son apenas razones para abandonar la garantía proporcionada por los conjuntos de cambios.
  5. Siempre combine toda la rama a la vez. Fusionar archivos o subárboles a veces es tentador, pero en última instancia equivale a un mero guiño bajo un nuevo disfraz.
  6. Planifique con anticipación. Lamentablemente, volver a criar ramas en TFS es un tema doloroso. A veces es arduo, a veces son solo unos pocos pasos, pero nunca es obvio; no hay un comando incorporado (hasta 2010). Retirarlo en 2005/2008 requiere un conocimiento bastante profundo de la estructura de su sucursal actual, la estructura deseada y cómo abusar de los efectos secundarios de varios comandos de TF.
  7. No cree ramas dentro de las ramas. Por ejemplo, la combinación de & de bifurcación a veces se recomienda como una forma de mantener los módulos o binarios comunes entre proyectos poco vinculados. No creo que este sea un buen consejo para empezar, mucho mejor para hacer que su sistema de compilación haga su trabajo principal correctamente, que poner su calzador en su sistema de control de fuente para hacer algo para lo que realmente no está diseñado. De todos modos, esta táctica de "compartir" choca terriblemente con los propios proyectos que viven dentro de una jerarquía de sucursales más amplia para propósitos de SCM. Si no eres súper cuidadoso, TFS te dejará felizmente crear relaciones de ramas arbitrarias de muchos a muchos entre elementos de control de versiones. Buena suerte resolviendo eso (una vez tuve que hacerlo por un cliente, no es bonito.)
  8. No cree archivos con la misma ruta relativa en dos ramas de forma independiente; utilice Merge para ramificarlos o pasará horas persiguiendo conflictos de espacio de nombres. (n/a en 2010)
  9. No vuelva a agregar archivos en la parte superior de una ruta donde solían existir otros elementos. Ya sea que los elementos anteriores hayan sido Renombrados/Movidos, o simplemente Eliminados, se enfrentarán desafíos interesantes en el momento de combinar; como mínimo, requerirá dos Checkins para propagarse por completo. (n/a en 2010, aunque la experiencia es aún algo degradada, solo se requiere 1 checkin, se preserva el contenido del elemento, pero el historial del nombre está en esa rama & todas las ramas descendentes)
  10. No use/force flag a menos que sepas lo que estás haciendo. Todas las fusiones forzadas son efectivamente selecciones cerebrales, lo que genera riesgos muy similares (se pierde el código durante el proceso Resolve, etc.).
  11. No use la bandera/baseless a menos que realmente sepa realmente lo que está haciendo. Se pierden las eliminaciones, de forma similar a las etiquetas, excepto que cambia el nombre a siempre y se transforma en ramas en lugar de solo en los casos poco afortunados. No tiene ninguna protección de débito/crédito. Y lo más aterrador de todo, crearás nuevas relaciones de sucursales. A veces. (No se muestran comentarios al usuario sobre si cada elemento objetivo es nuevo, antiguo con una nueva relación o antiguo con una relación existente)
  12. Evitar/descartar (y, de forma equivalente, Aceptar resoluciones de los objetos) cuando sea posible. Descartar algunos conjuntos de cambios solo para aceptarlos subsiguientes es otro nombre más para la selección de cerezas :)
  13. Tenga cuidado con sus resoluciones en general. Cada uno tiene efectos secundarios únicos aparte de su efecto en la fusión en cuestión.
    1. AcceptTheirs es una forma rápida de & para obtener una fusión de "copia", como se defendió en la primera directriz. Si también lo usa en otros escenarios, recuerde que es y no al decirle a TFS que haga que el contenido del archivo sea el mismo. Le está diciendo que los dos archivos están completamente sincronizados desde un POV de control de versiones. A saber, cualquier cambio anterior en el archivo de destino que podría haberse fusionado en dirección opuesta ya no se considerará candidato una vez que se registre en Aceptar.
    2. Tenga en cuenta que un AcceptMerge (automático o manual) cuyos contenidos resultantes son idénticos al archivo fuente se considerarán como Aceptar por el servidor. No hay diferenciación en el protocolo Checkin webservice.
    3. Usar AcceptYours cuando se trata de cambiar el nombre puede torcer el cerebro. Pronto terminará en una situación en la que "el mismo" elemento tiene diferentes nombres en diferentes ramas. Suponiendo que tiene una buena razón para descartar cambios en primer lugar, este fenómeno no es inseguro en sí mismo; de hecho, probablemente sea necesario evitar las interrupciones de compilación o las personalizaciones únicas para sus archivos make. Es simplemente confuso para los humanos, y es muy probable que rompa cualquier secuencia de comandos de automatización que tenga que suponga que las estructuras de árbol son consistentes de una rama a otra.
    4. AcceptMerge es el valor predeterminado por una razón. A veces conduce a más conflictos de versiones que parecen estrictamente necesarios, pero es la opción más segura cuando se requiere una verdadera fusión. (Por ejemplo, el paso n. ° 1 de la directriz principal "fusionar hacia abajo, copiar hacia arriba"). Mientras siga las otras pautas, la cantidad de fusiones que requieren atención manual debería disminuir, de manera espectacular, si usted viene de una flujo de trabajo que es pesado en la recolección de cerezas.
  14. Los errores se deben vincular al conjunto de cambios donde se realizó la reparación. Si luego necesita explorar en las ramas descendentes para ver cuándo, dónde (y posiblemente cómo) se propagó la corrección de errores, esa es una función de control puramente de origen. No es necesario contaminar el elemento de trabajo con equipaje adicional, y mucho menos alterar la forma en que realiza fundamentalmente las fusiones.En 2005/2008 puede recorrer el historial de fusiones con el comando 'tf merges' o una interfaz de usuario de terceros como Attrice SideKicks. En 2010 obtienes ingeniosas visualizaciones integradas en Visual Studio. Instructions & screenshots on MSDN.
+0

Acabo de ver http://video.google.com/videoplay?docid=-577744660535947210, que recomendó en otro lugar de la red. ¿Qué piensas de reparenting release1.0 al crear release2.0, de modo que Main-Release2.0-Release1.0 es una ruta en tu árbol de bifurcación, como sugiere el video? –

+11

¡Tengo la sensación de que lo mismo explicado con git requeriría un 80% menos de palabras para obtener el mismo resultado! Francamente, no entiendo TFS en comparación con SVN, Git, Mercurial hell incluso CVS parece ir mejor! No me malinterpreten, me encantan los elementos de tarea de TFS, con la plantilla correcta es maravilloso ... pero nunca tuve tantos problemas con un sistema de control de fuente. ¡Implementa esto sobre un wan con VPN y cada commit se convierte en una sesión de S & M que salió mal! – Newtopian

5

Siempre he fusionado solo un rango de confirmaciones en la rama de integración, solo especificando el rango de los conjuntos de cambios que he fusionado.

Los elementos de trabajo relacionados con elementos de trabajo individuales en la etapa de desarrollo son elementos de trabajo de fase de desarrollo. No creo que haya necesidad de transferirlos a integración o lanzamiento.

No ha especificado dónde está registrando las solicitudes de errores/características de los clientes. Si los asigna a la rama de publicación, probablemente esté creando otros elementos de trabajo más detallados para la rama de desarrollo y, al fusionarse, simplemente marcará todos los problemas corregidos como resueltos para la rama en la que se está fusionando.

Así que resumirlo No veo ninguna razón para no ir con fusiones masivas.