Tengo un cliente que insistió en mantener nuestro nuevo desarrollo separado de las sucursales principales durante todo 2016. Tenían entre 3 y 4 equipos más trabajando en la aplicación en varias capacidades. Se han realizado numerosos cambios importantes (cambio de cómo se realiza la inyección de dependencia, limpieza del código con ReSharper, etc.). Ahora me toca a mí fusionar main en nuestra nueva rama de desarrollo para prepararnos para impulsar nuestros cambios en la cadena.
En mi extracción inicial de fusión, TFS informó ~ 6500 archivos con resolución de conflictos. Algunos de estos serán fáciles, pero algunos serán mucho más difíciles (específicamente algunos de los javascript, los controladores api y los servicios que admiten estos controladores).
¿Hay algún enfoque que pueda tomar que me lo haga más fácil?
Para aclarar, expresé mucha preocupación con este enfoque varias veces en el camino. El cliente era y es consciente de las dificultades con esto. Debido a que eligieron acortar el personal de control de calidad (1 probador para 4 desarrolladores, sin pruebas automatizadas, pruebas de regresión pequeñas), insistieron en que mantengamos nuestra rama aislada de los cambios en la rama principal con el pretexto de que esto reduciría la necesidad de nuestro probador para saber acerca de los cambios que se realizan en otros lugares.
Uno de los problemas más importantes aquí es una actualización de la versión angular y algunos de los otros softwares de terceros; desafortunadamente, no hemos encontrado una buena manera de construir esta solución hasta que todas las piezas vuelvan a estar en su lugar.
fuente
Respuestas:
Hubiera sido una manera simple de mantener su nuevo desarrollo separado de la rama principal sin llevarlo a esta desafortunada situación: cualquier cambio desde la troncal debería haberse fusionado en su rama de desarrollo diariamente . (¿Fue su cliente realmente tan miope que no pudo anticipar que su sucursal necesita volver a estar en la línea principal algún día?)
De todos modos, el mejor enfoque es en mi humilde opinión tratar de rehacer lo que debería haber sucedido de primera mano:
Esto podría funcionar cuando los equipos obedecían estrictamente a las reglas clásicas de control de versiones ("solo confirman estados compilables, probados" y "check in temprano y frecuente").
Después de 365 repeticiones (o 250, si tiene suerte y puede agrupar el trabajo para los cambios de fin de semana), estará casi terminado (casi, porque necesita agregar el número de cambios que sucederán en la línea principal durante el período de integración) ) El paso final será fusionar la rama de desarrollo actualizada nuevamente en el tronco (para que no pierda el historial del tronco). Esto debería ser fácil, porque técnicamente debería ser solo un reemplazo de los archivos afectados.
Y sí, lo digo en serio, probablemente no hay un atajo para esto. Podría resultar que las "porciones diarias" a veces sean demasiado pequeñas, pero no esperaría esto, supongo que es más probable que las porciones diarias resulten ser demasiado grandes. Espero que su cliente le pague realmente bien por esto, y que esto sea tan costoso para él que aprenderá de su fracaso.
Debo agregar que puedes probar esto también con lados cambiados, reintegrando los cambios desde tu rama en pequeñas porciones a la línea principal. Esto podría ser más simple cuando en su rama de desarrollo hubo muchos menos cambios que en la troncal, o la mayoría de los cambios ocurrieron en nuevos archivos fuente que actualmente no son parte de la troncal. Uno puede ver esto como "portar" una característica de un producto A (la rama de desarrollo) a un producto B algo diferente (estado actual de la troncal). Pero si la mayoría de las refactorizaciones transversales se realizaron en la línea principal y afectan su nuevo código (las colisiones de fusión 6500 parecen ser una evidencia de esto), podría ser más fácil de la forma en que lo describí primero.
fuente
En esa etapa de fusión, diría que la fusión automática solo puede complicar demasiado el proceso. He tenido problemas similares con sucursales que se han separado durante más de un año y el método más efectivo que tengo es hacer lo siguiente:
Eventualmente, las advertencias del compilador y los diffs serán sus mejores amigos, siga usando el diff no combinado para ver exactamente qué era diferente y simplemente continúe. Puede haber varias herramientas que podría usar para ayudar, pero eso dependerá de usted para determinar cuál es la mejor.
La clave es seguir adelante.
Editar:
Una advertencia: este enfoque significará que el historial de control de versiones se 'corrompería', ya que perdería la evidencia de la fusión de rama a rama, así como el historial de la rama no fusionada.
Gracias a los comentarios de 'Jack Aidley' y '17 de 26 '
fuente
Hace unos años teníamos un cliente con los mismos requisitos de mantener las sucursales separadas. Entonces lo hicimos.
Nunca fusionamos su rama de nuevo. Tenían allí su propia versión única. Les cobramos extra por los cambios, ya que esencialmente teníamos dos troncos principales en lugar de 1 tronco principal y ramas.
Intentamos fusionarnos nuevamente con el tronco, pero después de 2 semanas decidimos abandonar ese esfuerzo, ya que estaba quemando horas sin beneficios tangibles.
Entonces, no lo fusiones de nuevo. En el futuro, combine las correcciones críticas para esa sucursal del cliente según sea necesario y cualquier mejora sería una de las cargas específicamente cargadas para ese cliente.
fuente
No va a ser divertido, pero lo doloroso que sea dependerá de la naturaleza de los cambios y de lo aislados que estén.
Le sugiero que intente converger las ramas refactorizando tanto como sea posible antes de hacer una fusión real.
La herramienta de combinación es un poco tonta porque solo analiza las diferencias textuales y no entiende el código de ninguna manera. Si la rama principal ha cambiado el nombre de una clase utilizada en toda la aplicación, y la rama característica usa el nombre antiguo en algún código nuevo, entonces la herramienta de fusión no comprenderá que el nombre de la clase también debe cambiarse en el nuevo código. Pero si realiza una refactorización en la rama B para cambiar el nombre de la clase como en la rama A, funcionará tanto en el código antiguo como en el nuevo y la fusión se realizará sin problemas.
En segundo lugar, debe inspeccionar qué tan localizados están los cambios en la rama de desarrollo. Si los cambios en la rama de características se localizan en algunas áreas, no tiene que converger el código no afectado, solo puede copiar y sobrescribir desde la rama principal.
En las áreas de código donde ha habido cambios no triviales en ambas ramas, debe inspeccionar cuidadosamente el código y decidir cómo reescribirlo.
fuente