Trabajando en una rama con una dependencia en otra rama que se está revisando

47

¿Cómo ayuda Git a lidiar con el siguiente escenario?

Tengo una tarea dividida en 2 partes: tarea de backend y tarea de frontend. Realizo una solicitud de extracción para fusionar los cambios del backend y esperar a que se fusionen (y enviar comentarios). Mientras espero, realmente no puedo trabajar en los cambios de frontend porque depende de los cambios de backend y todavía no están disponibles en la rama maestra.

¿Cuál es la mejor manera de introducir cambios en la rama de cambios de frontend de la rama de cambios de backend mientras aún se está revisando?

    
pregunta sul4bh 28.06.2017 - 02:18

7 respuestas

38

También tengo este problema a veces. Git es muy flexible. Aquí hay una forma de hacerlo.

Su primera sucursal featureA está lista para revisión.

Su segunda rama featureB está en desarrollo y depende del código en la rama featureA .

Combine la rama featureA en la rama featureB .

Si realiza cambios en la rama featureA , debe combinar la rama featureA en la rama featureB nuevamente para incorporar los cambios.

También debe asegurarse de fusionar featureA en el tronco principal, de lo contrario, cuando fusione featureB en el tronco principal, inadvertidamente también fusionará featureA . Una vez que featureA se fusiona en el tronco principal, puede deshacerse de la rama featureA , ya que featureB solo depende del tronco principal ahora.

Prefiero que mis ramas de características no dependan unas de otras, pero a veces lo hacen y tienes que rodar con ellas.

    
respondido por el Matt 28.06.2017 - 02:43
28

Ya tienes una rama de la que dependen todas y cada una de las funciones y que sigue cambiando. Se llama master .

La forma típica de que una rama de función se mantenga sincronizada con master es permanecer en la parte superior de ella. Cuando master cambia, normalmente git fetch origin master:master && git rebase master en el directorio de trabajo de su sucursal.

Puedes hacer lo mismo con otra rama de función: sigue buscándola y volviendo a establecer una base de datos sobre ella.

Si, por alguna razón, necesita mover sus cambios a una rama diferente, puede seleccionar sus confirmaciones, que nunca se mezclan con las confirmaciones de otras sucursales.

    
respondido por el 9000 28.06.2017 - 05:17
20

Espera, omite la fusión

Para este enfoque, no desea combinar su feature_a en feature_b repetidamente.

Rebasar se ha mencionado en otras respuestas, pero solo para rebasar las cosas en master . Lo que quieres hacer en tu caso es:

  • Comience su feature_b desde feature_a , es decir:

    git checkout feature_a
    git checkout -b feature_b
    
  • Siempre que feature_a cambie mientras espera ser fusionado en master , usted rebase feature_b :

    ... commit something onto feature_a ...
    git checkout feature_b
    git rebase feature_a
    
  • Finalmente, tan pronto como feature_a se haya fusionado en master , simplemente obtendrás las nuevas master y rebase feature_a en la última vez:

    git checkout master
    git pull origin master
    git checkout feature_b
    git rebase --onto master feature_a feature_b
    

    Este rebase final injertará todas las confirmaciones que están colgando de la confirmación feature_a (que ahora es irrelevante, ya que se ha fusionado en master ) directamente en master . Su feature_b ahora es una rama simple y estándar que va directamente desde master .

EDIT: inspirado en los comentarios, un poco de atención: si necesita realizar algún cambio que afecte a ambas características, entonces asegúrese de hacerlo en feature_a (y luego vuelva a hacer una fase como se muestra ). No no conviértalo en dos confirmaciones diferentes en ambas ramas, aunque sea tentador; Como feature_a es parte del historial de feature_b , tener el único cambio en dos confirmaciones diferentes será semánticamente incorrecto y posiblemente dará lugar a conflictos o "resurrecciones" de código no deseado, más adelante.

    
respondido por el AnoE 28.06.2017 - 21:31
5

En este caso donde la tarea de frontend tiene una dependencia crítica con el código de backend, y desea comenzar a trabajar en el frontend antes de que se finalice el backend y se acepte en el maestro, simplemente comenzaría la tarea de frontend como una rama de características que viene fuera de la rama de backend, en lugar de bifurcar el frontend en el maestro.

Una rama de función que vive el tiempo suficiente debe fusionarse con los cambios del maestro ocasionalmente (para asegurarse de que se reconcilien los conflictos de fusión o semánticos como parte del trabajo de desarrollo en la rama de la función, en lugar de como parte de la "revisión, qa , proceso de fusionar a maestro ". Entonces, haga eso en su rama de front-end, y cuando el trabajo de back-end haya sido aceptado como maestro, obtendrá cualquier cambio menor que se haya realizado en el back-end como parte de su revisión / aceptación automáticamente, por la misma ruta que obtener cualquier otro cambio de código en el maestro.

Si resulta que la rama de fondo necesita mucho más trabajo y continúa cambiando durante un período de tiempo antes que se fusiona con el maestro (diga si se encuentran problemas importantes durante la revisión), entonces probablemente querrá realizar fusiones periódicas directamente desde la rama de backend a la rama de frontend (para no seguir basando todo su trabajo de frontend en un código de backend obsoleto). Esto es fácil si usted es el único desarrollador que realiza ambas funciones (ya que sabe si usted mismo realiza cambios importantes), pero incluso si ambas funciones terminan siendo trabajadas en paralelo por diferentes desarrolladores, debería estar bien; solo tienes que mantenerte en comunicación (lo que necesitarías de todos modos, si estás trabajando en tareas en paralelo donde una tiene una dependencia crítica de la otra).

Si resulta que toda la rama de fondo debe abandonarse y nunca se fusionará (parece que esto sería un acuerdo bastante importante que rara vez sucedería), entonces puede elegir sus compromisos con una nueva rama. saliendo del maestro sin el trabajo de backend, o si aplica las confirmaciones inversas que eliminan todo el código de backend a la rama de frontend. Pero, como puedo ver, es más probable que detenga el trabajo de frontend hasta que descubras qué es lo que reemplazará al backend que estás desechando y luego decides qué hacer.

    
respondido por el Ben 28.06.2017 - 07:50
2

No veo el problema aquí.

Ya tienes esto cada vez con tu rama master , que cambia constantemente mientras las funciones se desarrollan y luego se combinan.

Entonces, en su ejemplo concreto, primero crea la rama feature_xxx_backend y desarrolla los cambios de backend. Cuando se haga esto, la rama estará lista para revisión y se fusionará en master una vez que se complete la revisión.

Entonces, simplemente inicie otra rama, feature_yyy_frontend . Probablemente querrás pasar de feature_xxx_backend , para que ya tengas esos cambios en tu branc. luego simplemente desarrolle la función de interfaz de usuario si la rama fuera master .

Cuando la rama feature_xxx_backend cambia, por ejemplo, Debido a que hay cosas que surgen durante la revisión que deben ser dirigidas, simplemente haga estos cambios y combínelos en la rama feature_yyy_frontend . Luego continúe en la rama del frontend.

Una vez que se completa la revisión de la rama de back-end, se fusiona en master . En este punto, sería prudente reajustar la rama feature_yyy_frontend en master , de modo que los revisores solo tengan que revisar los cambios nuevos a los que contribuye esta rama master , y no es necesario volver a revisar los cambios realizados para el backend (que ya han sido aprobados).

Esto también se puede hacer cuando tienes dos, tres o más ramas dependientes. Si tiene dos ramas de características de las que depende, simplemente cree una rama derivada que tenga ambas características fusionadas. Rama desde allí, desarrolle la tercera característica, combine ambas ramas de características en el camino cuando cada una de ellas cambie. Cuando ambas funciones se completan y se fusionan en la rama derivada, se vuelve a establecer en eso, o si se combinan en maestro, se vuelve a convertir en maestro.

Rebasar (como se sugirió anteriormente) es realmente poderoso y ayuda a mantener un registro limpio de los cambios, lo que facilita las revisiones.

    
respondido por el Polygnome 28.06.2017 - 12:56
2

Como mencionó Polygnome, puedes fusionar tu rama de frontend con tu rama de backend en lugar de los maestros. Incluso con la configuración de rama actual que tiene ahora, simplemente puede hacer:

git checkout frontend
git merge backend

o simplemente

git merge backend frontend

Tenga en cuenta que si no se aceptan los cambios del backend y se necesita más trabajo, tendrá que combinar las actualizaciones del backend con el frontend para evitar conflictos. Una vez que se acepten los cambios en el maestro, puede volver a ajustar su interfaz en el maestro para deshacerse de las confirmaciones de fusión del servidor.

Técnicamente, también puedes hacer todo con rebase, pero eso arruinará el historial de confirmaciones de tu rama de frontend. De donde vengo, esto se considera una mala práctica. YMMV

    
respondido por el Joris Meys 28.06.2017 - 15:30
0

La mayoría de las respuestas aquí describen correctamente el proceso de fusión de los cambios de la segunda rama a la primera, pero no abordan cómo minimizar la cantidad de conflictos que puede que necesite resolver.

Siempre que tenga dos conjuntos de grandes cambios que desee revisar individualmente (como featureA y featureB ), cree una RP que NO esté destinada a fusionarse, sino que recopile comentarios iniciales sobre un PoC de featureA .

La gente podrá revisarlo rápidamente (solo es un PoC), y el objetivo es validar el diseño o enfoque general.

Luego, puedes seguir trabajando en la función A, crear una solicitud de extracción y derivar y trabajar en la función B.

La gran diferencia es que ahora puede esperar que featureA no cambie radicalmente: el diseño y el enfoque ya se validaron. La revisión del código y los cambios requeridos pueden ser sutiles y locales en lugar de "woops, necesitas un enfoque diferente". Esto minimizará la cantidad de trabajo que debe hacer para más adelante fusionar featureB en el código de featureA , independientemente del método que elija.

    
respondido por el Alpha 03.07.2017 - 19:58

Lea otras preguntas en las etiquetas