2012-01-26 21 views
12

Supongamos que mi repositorio de Git inicialmente tiene dos ramas: Foo y Bar.Rebase a merge commit

 
... ─ Foo 

... ─ Bar 

Creo una tercera rama, FooBar en la que me comprometo la fusión de las otras dos ramas.

 
... ─ Foo ──┐ 
      FooBar 
... ─ Bar ──┘ 

FooBar es ahora un compromiso por delante tanto de Foo como de Bar. A continuación, trabajo un poco más, comprometiéndome solo un par de veces en Foo.

 
... ── A ───┬── B ── C ── D ── Foo 
      FooBar 
... ─ Bar ──┘ 

La pregunta es: ya que el primer padre de la rama FooBar ya no es Foo, puedo rebase la fusión comprometerse en la rama FooBar tener de nuevo Foo y Bar como sus dos padres? En otras palabras, ¿puedo incorporar el desarrollo en Foo en el FooBar combinado previamente junto con el Bar sin cambios?

 
... ── A ── B ── C ── D ── Foo ──┐ 
           FooBar 
... ─ Bar ───────────────────────┘ 
+0

Consulte también [utilizando git-replace para cambiar un puntero principal] (http://stackoverflow.com/a/3811217/90527), aunque esto tiene otras consecuencias. – outis

+0

Ver también [¿Cómo uso git rebase -i después de la fusión de git sin estropear las cosas?] (Http://stackoverflow.com/q/4152936/90527) – outis

Respuesta

1

No se podía reajustar bajo rama FooBar sin cambiar lo que define FooBar. Lo que podría hacer es fusionar FooBar y Foo. Eso tendría los mismos contenidos que deseas.

+0

Sí, pero el punto es evitar las confusiones de fusión. Es por eso que quiero volver a establecer la base 'BranchFooBar'. – nccc

+0

Quizás estoy confundido con lo que quieres. Dices que quieres evitar las asignaciones de fusión, pero interpreto tu pregunta como si quisieras que los resultados finales sean una combinación de fusión entre 'branchFoo' y' branchBar'. – Andy

+0

Tienes razón, esto no fue lo suficientemente claro. Quiero evitar un * 2º * compromiso de fusión. 'BranchFooBar' siempre será un commit de fusión, pero quiero que sea * el * merge commit con' BranchFoo' y 'BranchBar' como padres. – nccc

0

Básicamente, está tratando de borrar todos los rastros de la fusión realizada anteriormente.

Si realmente quiere deshacerse de todas las confirmaciones que sólo existe en FooBar (y en el directorio de trabajo), a continuación, proceder de la siguiente manera: en primer lugar hacer git checkout FooBar, a continuación, hacer git olvidarse de su historia y hacer git reset --hard Foo (si la intención de fusionar Bar en Foo). A continuación, vuelve a crear la combinación con git merge Bar.

12

Me doy cuenta de que este es un tema bastante antiguo, pero dado que encontré esta pregunta al enfrentar una situación similar, podría decir lo que usé al final.

git checkout FooBar 
git rebase -p --onto Foo A 

He intentado utilizar los nombres de la pregunta original. Tenga en cuenta especialmente que A significa la confirmación que está marcada como A en el arte ascii. Probablemente usaría el hash del commit en su lugar o de otra manera para apuntar al commit donde las ramas Foo y FooBar se separaron originalmente.

La bandera -p también se conoce como --preserve-merges y hace más o menos lo que dice.

Tenga en cuenta que la rama Bar no desempeña un papel aquí, por lo que la línea de confirmaciones puede ser una rama con nombre o no, no hace ninguna diferencia.

+3

Tenga en cuenta que esto no mantendrá los cambios realizados en la confirmación de fusión. – Tgr

+2

Gracias, esto nos ayudó mucho. De hecho, es importante tener en cuenta que 'A' es la última confirmación de la rama de destino que todavía estaba incluida en la fusión original. – Dibbeke

+1

¡esta debería ser la respuesta aceptada! – wutzebaer