Modificar el historial de una twig de tema git que utilizó fusiones para usar rebases

Nuestro flujo de trabajo de desarrollo git es que las twigs temáticas se actualizan continuamente en el último máster hasta que se fusionen.

Sin embargo, un nuevo desarrollador ha creado twigs temáticas en las que ha realizado varias fusiones maestras en sus twigs temáticas para mantenerlas al día.

A---B---C---D---E topic / / / F---G---H---I master 

Si bien la fusión de esta twig de tema a principal sería perfectamente correcta, da como resultado una historia muy desorderada. Quiero convertir estas twigs de tema en un historial lineal limpio que se puede fusionar limpiamente en el maestro con un solo --no-ff merge commit ie:

  A'---B'---E' topic / F---G---H---I master 

Idealmente, habría algo de git-fu que me permitiera hacer la rebase, tomando las confirmaciones en la twig de temas tal como está, mientras aplicaba automáticamente la información de resolución de conflictos de fusión ya disponible en las asignaciones de fusión de temas como C y D.

Sé que puedo simplemente aplicar el parche de "git diff master..topic" y luego usar rebase para trabajar hacia atrás y dividir manualmente el único parche en commits individuales, pero ¿hay un enfoque más simple y más elegante?

He intentado directamente git rebase y git rebase -p commands sin suerte.

Descubrí que el siguiente process parece funcionar razonablemente bien, aunque no perfectamente. Es posible que se requieran algunas resoluciones de conflictos menores, ver abajo.

  1. Asegúrese de que la twig de temas esté actualizada con el último maestro haciendo una fusión final desde el maestro, si no se ha hecho ya:

     git checkout topic git merge master 
  2. Simplifique el historial de la twig de tema excluyendo las fusiones:

     git log --no-merges 
  3. Del logging anterior, determine el punto de ramificación (la confirmación en el maestro antes de la primera confirmación de la twig de tema, que debe confirmarse en F).

  4. Rebase la twig del tema en el maestro, ignorando las fusiones (que es el valor pnetworkingeterminado, es decir, no use la --preserve-merges / -p ), resolviendo cualquier conflicto.

     git checkout master git rebase --onto HEAD F topic 

    Descubrí que durante el rebase, a menudo un conflicto daba como resultado que un file estuviera en un estado conflictivo "Ambos modificados", pero no contenía marcadores de conflicto, por lo que bastaba con un simple git add y git rebase --continue para resolver el conflicto y continuar. Creo que git estaba usando la resolución anterior para resolver los conflictos.

    Además, en algunas twigs más complejas, se git rebase --onto HEAD ... múltiples git rebase --onto HEAD ... o alternativamente se puede usar git cherry-pick para seleccionar compromisos individuales. Simplemente trabaje a través del logging que se proporciona en el Paso 2, vuelva a establecer los ranges en HEAD y / o haga una selección especial de tareas individuales según sea necesario.

  5. El HEAD actual debería representar ahora la twig de tema rebasada. Verifique que el resultado coincida con la twig de tema original comprobando que la diferencia no da como resultado:

     git diff topic..HEAD 
  6. Nombre HEAD al nombre de twig de tema rebasado:

     git checkout -b rebased-topic 

La respuesta de Raman funcionó bastante para mí, pero pensé que agregaría más detalles sobre el paso 4, lo que fue complicado para mí.

Tenía un repository que era más complicado, era como esto

  QRSTUVWX / / / / ABCDEFGHIJK 

Yo quería esto:

  Q'-R'-S'-T'-U'-V'-W'-X' / ABCDEFGHIJK 

Lo que funcionó fue hacer git rebase --onto HEAD QR , luego git rebase --onto HEAD SU , así que básicamente agarrando los ranges de commits entre los lugares donde fundí el master en el topic . Todo el time que estuve haciendo esto, estaba en un estado de cabeza separada, así que no te preocupes si ves eso. Hubo algunas veces en que tuve conflictos de fusión, pero todos eran conflictos legítimos que esperaba ver.

Finalmente, tenía una twig que parecía correcta (Paso 6 en la respuesta de Raman), pero por alguna razón tuve que volver a trabajar con el maestro para mover las confirmaciones. No sé por qué tuve que hacer eso, pero fue sin problemas.

Creo que hacerlo de esta manera es básicamente equivalente al "cherry picking", por lo que podría ser más simple hacerlo en su lugar.