Cómo arreglar las twigs en cascada rebasando el lío

Tenemos un flujo de trabajo donde solo un miembro del equipo trabaja en varias twigs de características. El trabajo es tal que cada twig siguiente depende de la anterior. La twig pnetworkingeterminada es develop .

Digamos este escenario:

  1. Él crea featureA branch, hace el trabajo, empuja la twig y crea un RP en GitHub
  2. Él crea la twig featureB (basada en featureA one), hace el trabajo y las relaciones públicas que
  3. Él crea la twig featureC , (basado en featureB ) hace el trabajo y lo featureB en featureB
  4. él crea la twig featureD , (basado en featureC ) hace el trabajo y las relaciones públicas

Ninguno de los RP se ha fusionado todavía.

Ahora, el gerente de proyecto interviene y comienza a fusionarse. Fusiona ir de esta manera:

  1. El gerente de proyecto fusiona la característica A para desarrollar
  2. Desarrollador de su lado hace:

     git checkout develop git fetch origin git rebase origin/develop git checkout featureB git rebase origin/develop git push origin featureB 

En este punto del time, obtenemos un error:

 machine /c/Work/ (featureB) $ git push origin featureB To https://github.com/x.git ! [rejected] featureB -> featureB (non-fast-forward) error: failed to push some refs to 'https://github.com/x.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes (eg hint: 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. 

¿Por qué pasó esto?

Pensamos que la function de rebase featureB en origin/develop (que ahora después de la fusión contiene la característica A) haría que la function featureB esté list para enviar. pero obviamente vemos algo mal.

La forma más fácil de explicar lo que sucedió es mirar la historia de su repository. Esto es lo que (una versión abreviada de) su historial parecía pre-fusionar:

 *--*--*--* [develop, origin/develop] \ *--*--* [featureA, origin/featureA] \ A--B--C [featureB, origin/featureB] 

Y post-fusión:

 *--*--*--*---------* [develop, origin/develop] \ / *--*--* \ A--B--C [featureB, origin/featureB] 

Luego, se featureB en el develop :

 *--*--*--*---------* [develop, origin/develop] \ / \ *--*--* A'--B'--C' [featureB] \ A--B--C [origin/featureB] 

Aquí, A' , B' y C' , contienen los mismos cambios que A , B y C , respectivamente, pero no son los mismos commits , porque A' tiene un compromiso principal diferente.

Por lo tanto, después de cada rebase, debes forzar-empujar la twig rebasada:

 git push --force-with-lease origin featureB 

(La --force-with-lease garantiza que no se hayan enviado nuevos commits desde la última vez que lo hayas comprado. Aunque puede no ser estrictamente necesario aquí, es bueno tener el hábito de usar esa --force ).

Como se ve en mi último gráfico, cada vez que una twig (como la function featureB ) y su twig de seguimiento remoto (como origin/featureB ) divergen, debe forzar la fuerza. Por lo tanto, tendrá que hacer eso cada vez que haya vuelto a establecer una twig que ya haya sido empujada al control remoto.