2011-01-12 14 views
16

Digamos que tengo una rama llamada master y una rama llamada upstream_lib.¿Cómo forzar a un ancestro común en una fusión de git?

La ramificación master tiene un subdirectorio lib que se basa en el código que está en la rama upstream_lib; los cambios en upstream_lib se fusionan (con la estrategia de subárbol) a la rama master periódicamente. El directorio lib en master tiene algunas modificaciones propias que no están en upstream_lib.

Sin embargo, digamos que las dos ramas no tienen un historial en común (porque el repositorio se migró a git, por ejemplo) o la base de combinación es incorrecta porque las fusiones en upstream_lib han sido aplastadas, ha habido alguna modificación o lo que sea.

La pregunta es: dado un nuevo conjunto de cambios en upstream_lib, ¿cómo forzar la fusión para considerar como antepasado común una revisión específica de upstream_lib?

Respuesta

9

nunca he utilizado la estrategia subtree, así que tal vez esta es una solución subóptima (y tal vez no va a funcionar ^^), pero se podría aplicar todas las nuevas confirmaciones en upstream_lib a una rama temporal fuera de la master línea y luego fusionar eso. Lo que tengo en mente no fundamentalmente arreglar su situación, por lo que tendrá que hacer este tipo de "fusión manual" cada vez que desee para tirar en los nuevos cambios, pero aquí es como funciona:

  1. Determinar el ancestro común falso en la línea de ascendencia master, digamos master~100.
  2. Determine el ancestro común falso en la línea upstream_lib, digamos upstream_lib~150.
  3. Haga una copia de usar y tirar de la rama upstream_lib: git branch --no-track new_upstream_lib upstream_lib
  4. Rebase new_upstream_lib en master~100 utilizando la estrategia recursiva con la opción subárbol. (No creo que sólo puede utilizar la estrategia subárbol porque, como se dice, el directorio lib en master tiene cambios de su propio.) Aquí hay un comando, no está comprobado para esto:

    git rebase -s recursive -X subtree=lib --onto master~100 upstream_lib~150 new_upstream_lib 
    

    Tenga en cuenta que new_upstream_lib ahora tiene todo el árbol master, aunque solo le importa el directorio lib.

  5. Combínalo: git checkout master && git merge new_upstream_lib && git branch -d new_upstream_lib.
+0

Funcionó perfectamente, gracias! – Artefacto

+1

Supongo que el único problema es que no hay historial compartido o confirmaciones con la rama upstream_lib, pero puedo soportarlo. – Artefacto

+0

¡Me alegra oír eso! Si quisieras forzar el ancestro compartido, podrías crear un commit inicial vacío y rebase tanto 'master' como' upstream_lib' sobre eso. Suponiendo por supuesto que 'upstream_lib' es tu propia rama en lugar de remota. Sin embargo, si la importación inicial de 'upstream_lib' en el directorio' lib' era solo 'cp' en lugar de una fusión (como se describe en http://www.kernel.org/pub/software/scm/git/docs/ howto/using-merge-subtree.html), aún tendrá los problemas que describe. –

Cuestiones relacionadas