Cómo fusionar una twig a otra twig en GIT?

Déjame explicar el problema en detalle.

Tengo una twig principal de git en la que creé un nuevo bug10101010 de twig lateral, ahora quiero fusionar el bug10101010 a main. Hasta ahora todo está bien. Ahora tengo una twig diferente del mismo producto, llamada Legacy. Quiero fusionar el bug10101010 con la twig henetworkingada en GIT.

¿Algunas ideas?

No puedo simplemente fusionarlo directamente, ya que la twig bug10101010 se deriva de la twig principal y en el legado solo necesito la diferencia entre la twig bug10101010 y su twig padre.

Esto es difícil de hacer Git guarda el historial de fusión, y si "cherrypick" apunta a una confirmación en bug10101010 como padre (lo que indica que ha realizado una combinación), Git asumirá que todas las confirmaciones anteriores (hasta el punto en que se dividieron) se combinaron como bien. Te da problemas cuando quieres hacer una fusión "real".

Por otro lado, puede generar manualmente un parche a partir de esa (y solo esa) confirmación específica. Pero eso también le dará problemas cuando más tarde realice la combinación "real", ya que intenta aplicar su confirmación manejada manualmente dos veces.

Pero, una vez más, dado que una twig se llama "Legacy", sospecho que no planea hacer esa fusión real de todos modos, en cuyo caso tiene la libertad de hacerlo de todos modos.

Aquí hay una interesante publicación de blog sobre el tema .

Deberías usar git rebase --onto aquí y especificar un range.
(ver la página de git rebase :

trasplante una twig de tema basada en una twig a otra, para pretender que ha bifurcado la twig de tema de la última twig, utilizando rebase --onto .

)

Por supuesto, esto movería su twig bug10 sobre la twig legacy , que no es lo que quiere / necesita.

Por lo tanto, una solución alternativa sería hacer esa rebase en un repository clonado, luego fusionar esa twig legacy 'mejorada' (la del repository de clonación, con las modificaciones de bug10 encima) en la twig legacy local y actual (la quieres modificar, dejando bug10 solo).

Ahora:

  • esto implica un repository adicional (que puede conducir a la limitación de espacio en el disco)
  • en general, esto es bastante equivalente a definir un parche y aplicarlo a una twig legacy , por lo que las otras respuestas (parche) son válidas (y más simples).
  • la única ventaja que veo en este método es la oportunidad de definir un entorno henetworkingado en el que vuelves a establecer lo que deseas (como commits de bug10 ), antes de bug10 solo ese legacy twig a tu repository original (no bug10 , ya que su historial habría sido completamente reescrito!)

Solo quería ver si funciona, así que … probemos ese enfoque.
(Git1.6.5.1, en un viejo SP2 de XP, con una session de Powershell 1.0 debido al command Start-Transcript )


 PS D:\> mkdir git PS D:\> cd git PS D:\git> mkdir tests PS D:\git> cd tests PS D:\git\tests> git init mainRepo 

Me gusta cómo no tengo más para hacer el directory de git repo primero, luego git init ! Desde 1.6.5 :

" git init " aprendió a mkdir / chdir en un directory cuando se le dio un argumento adicional (es decir, " git init this ").

¡Esto es genial!

Vamos a crear 3 files, para 3 propósitos diferentes.
(Por el bien del ejemplo, mantendré las modificaciones del file separadas por twig: no hay conflicto durante la fusión o la rebase aquí).

 PS D:\git\tests> cd mainRepo PS D:\git\tests\mainRepo> echo mainFile > mainFile.txt PS D:\git\tests\mainRepo> echo contentToBeFixed > toBeFixedFile.txt PS D:\git\tests\mainRepo> echo legacyContent > legacy.txt PS D:\git\tests\mainRepo> git add -A PS D:\git\tests\mainRepo> git ci -m "first commit" PS D:\git\tests\mainRepo> echo firstMainEvol >> mainFile.txt PS D:\git\tests\mainRepo> git ci -a -m "first evol, for making 1.0" PS D:\git\tests\mainRepo> git tag -m "1.0 legacy content" 1.0 

En este punto, un git log --graph --oneline --branches regresa:

 * b68c1f5 first evol, for making 1.0 * 93f9f7c first commit 

Construyamos una twig legacy

 PS D:\git\tests\mainRepo> git co -b legacy PS D:\git\tests\mainRepo> echo aFirstLegacyEvol >> legacy.txt PS D:\git\tests\mainRepo> git ci -a -m "a first legacy evolution" 

Volvemos a master, realizamos otro commit, que labelremos "2.0" (¡un lanzamiento que necesitará corregir algunos errores!)

 PS D:\git\tests\mainRepo> git co -b master PS D:\git\tests\mainRepo> git co master PS D:\git\tests\mainRepo> echo aMainEvol >> mainFile.txt PS D:\git\tests\mainRepo> git ci -a -m "a main evol" PS D:\git\tests\mainRepo> echo aSecondMainEvolFor2.0 >> mainFile.txt PS D:\git\tests\mainRepo> git ci -a -m "a second evol for 2.0" PS D:\git\tests\mainRepo> git tag -m "main 2.0 before bugfix" 2.0 

Tenemos:

 * e727105 a second evol for 2.0 * 473d44e a main evol | * dbcc7aa a first legacy evolution |/ * b68c1f5 first evol, for making 1.0 * 93f9f7c first commit 

Ahora hacemos una bug10 corrección de errores bug10 :

 PS D:\git\tests\mainRepo> git co -b bug10 PS D:\git\tests\mainRepo> echo aFirstBug10Fix >> toBeFixedFile.txt PS D:\git\tests\mainRepo> git ci -a -m "a first bug10 fix" PS D:\git\tests\mainRepo> echo aSecondBug10Fix >> toBeFixedFile.txt PS D:\git\tests\mainRepo> git ci -a -m "a second bug10 fix" 

Vamos a agregar un compromiso final en la twig principal

 PS D:\git\tests\mainRepo> git co master PS D:\git\tests\mainRepo> echo anotherMainEvol >> mainFile.txt PS D:\git\tests\mainRepo> git ci -a -m "another main evol" 

Estado final de nuestro repository principal:

 * 55aac85 another main evol | * 47e6ee1 a second bug10 fix | * 8183707 a first bug10 fix |/ * e727105 a second evol for 2.0 * 473d44e a main evol | * dbcc7aa a first legacy evolution |/ * b68c1f5 first evol, for making 1.0 * 93f9f7c first commit 

En esta etapa, no haré ninguna manipulación adicional en mainRepo. Solo lo clonaré para hacer algunas testings. Si eso falla, siempre puedo volver a este repository y clonarlo nuevamente.

El primer clon es en realidad obligatorio, para realizar nuestro git rebase --onto

 PS D:\git\tests\mainRepo> cd .. PS D:\git\tests> git clone mainRepo rebaseRepo PS D:\git\tests> cd rebaseRepo 

Necesitamos dos de las twigs principales de Repo en nuestro repository clonado:

 PS D:\git\tests\rebaseRepo> git co -b bug10 origin/bug10 PS D:\git\tests\rebaseRepo> git co -b legacy origin/legacy 

Reestructuremos solo bug10 (es decir, todos los commits después de la label 2.0 hasta HEAD of bug10 branch) :

 PS D:\git\tests\rebaseRepo> git co bug10 PS D:\git\tests\rebaseRepo> git rebase --onto legacy 2.0 First, rewinding head to replay your work on top of it... Applying: a first bug10 fix Applying: a second bug10 fix 

En este punto, bug10 se ha reproducido sobre el legacy sin todas las otras confirmaciones intermedias .
Ahora podemos avanzar rápidamente HEAD of legacy a la parte superior de la twig bug10 reproducida.

 PS D:\git\tests\rebaseRepo> git co legacy Switched to branch 'legacy' PS D:\git\tests\rebaseRepo> git merge bug10 Updating dbcc7aa..cf02bfc Fast forward toBeFixedFile.txt | Bin 38 -> 104 bytes 1 files changed, 0 insertions(+), 0 deletions(-) 

El contenido sigue lo que necesitamos:

  • Tenemos todo el contenido henetworkingado:
 PS D:\git\tests\rebaseRepo> type legacy.txt legacyContent aFirstLegacyEvol 

  • el contenido para la twig main solo tiene una label de hasta 1.0 (raíz para la twig legacy ), y no más .
 PS D:\git\tests\rebaseRepo> type mainFile.txt mainFile firstMainEvol 

  • y las correcciones de bug10 están aquí:
 PS D:\git\tests\rebaseRepo> type toBeFixedFile.txt contentToBeFixed aFirstBug10Fix aSecondBug10Fix 

Eso es.
La idea es tirar esa twig legacy 'mejorada' en su repository original, que aún tendrá su bug10 sin cambios (es decir, aún comenzando con la label 2.0 , y no se reproducirá en ninguna parte como lo hicimos en el rebaseRepo .
En este repository clonado, hago un seguimiento de la twig de origin/legacy , para fusionarla con la twig legacy de otra fuente remota: el rebaseRepo .

 PS D:\git\tests\rebaseRepo> cd .. PS D:\git\tests> git clone mainRepo finalRepo PS D:\git\tests> cd finalRepo PS D:\git\tests\finalRepo> git co -b legacy origin/legacy 

En este repository original (solo lo cloné para no interferir con el estado del repository principal, en caso de que tuviera que hacer otros experimentos), declararé rebaseRepo como un control remoto, y searché sus twigs.

 PS D:\git\tests\finalRepo> git remote add rebasedRepo D:/git/tests/rebaseRepo PS D:\git\tests\finalRepo> type D:\git\tests\finalRepo\.git\config [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = D:/git/tests/mainRepo [branch "master"] remote = origin merge = refs/heads/master [branch "legacy"] remote = origin merge = refs/heads/legacy [remote "rebasedRepo"] url = D:/git/tests/rebaseRepo fetch = +refs/heads/*:refs/remotes/rebasedRepo/* PS D:\git\tests\finalRepo> git fetch rebasedRepo remote: Counting objects: 8, done. remote: Compressing objects: 100% (6/6), done. remote: Total 6 (delta 3), reused 0 (delta 0) Unpacking objects: 100% (6/6), done. From D:/git/tests/rebaseRepo * [new branch] bug10 -> rebasedRepo/bug10 * [new branch] legacy -> rebasedRepo/legacy * [new branch] master -> rebasedRepo/master 

Ahora podemos actualizar el legacy sin tocar el bug10 :

 PS D:\git\tests\finalRepo> git merge rebasedRepo/legacy Updating dbcc7aa..4919b68 Fast forward toBeFixedFile.txt | Bin 38 -> 104 bytes 1 files changed, 0 insertions(+), 0 deletions(-) 

Puede repetir el process tantas veces como desee, siempre que bug10 necesario volver a reproducir las nuevas bug10 sobre una antigua twig legacy , sin include todas las confirmaciones intermedias.

Use git-diff y luego git-apply ?