visual studio mac for version-control tfs

version-control - studio - tfvc



TFS: fusionar las mejores prácticas (2)

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.

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 compromiso individualmente, copiar la descripción del compromiso original y vincularlo 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.


Siempre solo he fusionado un rango de commits 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 resumiéndolo no veo ninguna razón para no ir con fusiones masivas.


  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. Use la rama fuente (Dev # 2 en nuestro caso) para incorporar, reaccionar y estabilizar completamente estos cambios.
    4. Fusionar en la dirección deseada (p. Ej. 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 sucursal de Dev está aceptando fusionarse temprano ya menudo, como debería ser, entonces no debería ser una carga bloquear la rama de destino durante este proceso con esperanza de cortocircuito. 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 fusiona 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 conjunto de cambios que omita el número 10 se conoce como "selección de cereza". Una vez que comienzas a hacer cherry picking te encuentras con algunos peligros:
    1. No puede utilizar el modelo de fusión hacia abajo y copiado descrito anteriormente. Solo por eso, Laura Wingerd diría que estás saltando sobre un bordillo.
    2. Si también tocaste alguno de los archivos tocados en tu rango, tendrás que hacer una fusión de contenido de 3 vías para que solo difundan los diffs escogidos. Ninguna herramienta de diferencias es perfecta; está agregando un riesgo distinto de cero de traer más código de lo previsto, sobrescribiendo accidentalmente los cambios realizados en el objetivo, introduciendo errores lógicos donde las dos ramas divergen, etc.
    3. El conjunto de cambios que está promocionando en la rama supuestamente más estable representa una configuración que nunca se ha desarrollado o probado antes. Puede hacer una suposició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 de 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 y una nueva eliminación, obtendrá archivos "fantasmas" que aparecerán en el destino, incluso si no incluye el borrado automático. Si fusiona Moves con todos los ámbitos de ruta y versión 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 haz un Get en la rama objetivo antes de fusionarte. 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. Al hacerlo, evita algunos problemas potenciales:
    1. Fusionando en código obsoleto, produciendo confusas diferencias de 3 vías que parecen eliminar los cambios de lo que ves en Tip. [eventualmente los recuperarías luego de Checkin + Resolve, pero no hay razón para pasar por dos diffs arriesgados cuando puedes 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 una fusión segura y consistente.
    1. Las etiquetas pueden representar múltiples puntos en el tiempo. Si una etiqueta representa una instantánea consistente del VCS, y siempre fue intencionada como tal, entonces no tiene ninguna 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, combinar por etiqueta puede conducir a:
      1. Inadvertida selección de cerezas, si el rango comienza con una etiqueta que apunta a un artículo @ a tiempo antes de su primer candidato
      2. Exclusión inadvertida, si el rango comienza con una etiqueta que apunta a un artículo @ a tiempo antes del final del rango
      3. Exclusión inadvertida, si el rango finaliza con una etiqueta que apunta a un artículo @ a una vez antes del inicio del rango
    2. Las versiones de las 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 nuevamente, si no necesita esta habilidad, está incurriendo en los siguientes riesgos sin obtener nada sobre las fechas y los conjuntos de cambios).
      1. Los elementos que no están en la etiqueta serán simplemente ignorados, 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. Recolección inadvertida de cerezas, si agrega un elemento a la etiqueta que ha estado presente por un tiempo, pero que se excluyó de las fusiones anteriores debido a uno de los efectos secundarios mencionados anteriormente.
      3. Intencional selección de cerezas. 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" a nivel de archivo , lo que es aún más peligroso que el "ordinario" cherry picking por conjunto de cambios.
    3. Las etiquetas tienen nombres personalizables amigables, 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 fusiona 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. Plan a seguir. 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 crees ramas dentro de las ramas. Por ejemplo, la bifurcación y la fusión a veces se recomiendan 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 fueron 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 todavía está algo degradada, solo se requiere 1 checkin, se preserva el contenido del elemento, pero el historial del nombre está en esa rama y en todas las ramas posteriores)
  10. No use la bandera / force a menos que sepa lo que está 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. Te pierdes las eliminaciones, de forma similar a las etiquetas, excepto que los cambios de nombre siempre se transforman en ramas en lugar de simplemente en los casos de desafortunados bordes. 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, viejo con una nueva relación o viejo con una relación existente)
  12. Evitar / descartar (y, de manera equivalente, AcceptYours Resoluciones) cuando sea posible. Descartar algunos conjuntos de cambios solo para aceptar los siguientes es otro nombre para escoger a la perfección :)
  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 manera rápida y poderosa de obtener una fusión de "copia", como se defendió en la primera guía. Si también lo usa en otros escenarios, recuerde que no solo le está diciendo 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 sean idénticos al archivo fuente se considerará un AcceptTheirs por parte del servidor. No hay diferenciación en el protocolo Checkin webservice.
    3. Usar AcceptYours cuando los cambios de nombre están involucrados puede torcer tu 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 deben estar vinculados al conjunto de cambios donde se realizó realmente la correcció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, se trata de 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. Instrucciones y capturas de pantalla en MSDN.