Cambiar la base de un commit de Git merge
Tomemos el siguiente caso:
Tengo algo de trabajo en una rama temática y ahora estoy listo para fusionar de nuevo con master:
* eb3b733 3 [master] [origin/master]
| * b62cae6 2 [topic]
|/
* 38abeae 1
Realizo la fusión desde master, resuelvo los conflictos y ahora tengo:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | eb3b733 3 [origin/master]
|/
* 38abeae 1
Ahora, la fusión me llevó algún tiempo, así que hago otra búsqueda y me doy cuenta de que la rama maestra remota tiene nuevos cambios:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
| | * e7affba 4 [origin/master]
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Si intento 'git rebase origin / master' desde master, me veo obligado a resolver todos los conflictos de nuevo, y también pierdo la fusión commit:
* d4de423 2 [master]
* e7affba 4 [origin/master]
* eb3b733 3
| * b62cae6 2 [topic]
|/
* 38abeae 1
¿Hay una forma limpia de cambiar la base de la confirmación de fusión para que termine con un historial como el que muestro a continuación?
* 51984c7 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | e7affba 4 [origin/master]
* | eb3b733 3
|/
* 38abeae 1
5 answers
Hay dos opciones aquí.
Una es hacer una rebase interactiva y editar la confirmación de fusión, rehacer la fusión manualmente y continuar la rebase.
Otra es usar la opción -p
en git rebase
, que se describe como sigue en el manual: "En lugar de ignorar las fusiones, intente recrearlas."Esta pregunta lo explica aún más: ¿Qué hace exactamente" rebase preserve preserve-merges " de git (y por qué?)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:36
Ok, esa es una vieja pregunta y ya han aceptado respuesta por @siride
, pero esa respuesta no fue suficiente en mi caso, ya que --preserve-merges
te obliga a resolver todos los conflictos por segunda vez. Mi solución basada en la idea de @Tobi B
pero con instrucciones exactas paso a paso
Así que vamos a empezar en tal estado basado en el ejemplo en la pregunta:
* 8101fe3 Merge branch 'topic' [HEAD -> master]
|\
| * b62cae6 2 [topic]
| |
| | * f5a7ca8 5 [origin/master]
| | * e7affba 4
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Ten en cuenta que tenemos 2 commits por delante master, así que cherry-pick no funcionaría.
-
En primer lugar, vamos a crear la historia correcta que queremos:
git checkout -b correct-history # create new branch to save master for future git rebase -s ours -p origin/master
-p
significa--preserve-merges
, lo usamos para guardar nuestra confirmación de fusión en el historial-s ours
significa--strategy=ours
, lo usamos para ignorar todos los conflictos de fusión ya que no nos importa qué contenido habrá en esa confirmación de fusión, solo necesitamos un buen historial ahora.La historia se verá así (ignorando al maestro):
* 51984c7 Merge branch 'topic' [HEAD -> correct-history] |\ | * b62cae6 2 [topic] * | f5a7ca8 5 [origin/master] * | e7affba 4 * | eb3b733 3 |/ * 38abeae 1
-
Vamos a obtener el índice correcto ahora.
git checkout master # return to our master branch git merge origin/master # merge origin/master on top of our master
Podemos obtener algunos conflictos de fusión adicionales aquí, pero eso solo sería conflictos de archivos cambiados entre
8101fe3
yf5a7ca8
, pero no incluye conflictos ya resueltos detopic
La historia se verá así (ignorando la historia correcta):
* 94f1484 Merge branch 'origin/master' [HEAD -> master] |\ * | f5a7ca8 5 [origin/master] * | e7affba 4 | * 8101fe3 Merge branch 'topic' | |\ | | * b62cae6 2 [topic] |/ / * / eb3b733 3 |/ * 38abeae 1
-
La última etapa es combinar nuestra rama con historial correcto y rama con índice correcto
git reset --soft correct-history git commit --amend
Usamos
reset --soft
para restablecer nuestra rama (e historial) a correct-history, pero dejamos el índice y el árbol de trabajo como están. Luego usamoscommit --amend
para reescribir nuestra confirmación de fusión, que solía tener un índice incorrecto, con nuestro buen índice de master.Al final tendremos tal estado (note otro id de la confirmación superior):
* 13e6d03 Merge branch 'topic' [HEAD -> master] |\ | * b62cae6 2 [topic] * | f5a7ca8 5 [origin/master] * | e7affba 4 * | eb3b733 3 |/ * 38abeae 1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-15 10:36:36
Dado que acabo de perder un día tratando de resolver esto y en realidad encontré una solución con la ayuda de un compañero de trabajo, pensé que debería intervenir.
Tenemos una base de código grande y tenemos que lidiar con 2 ramas fuertemente modificadas al mismo tiempo. Hay una rama principal y una rama secundaria si usted cuál.
Mientras combino la rama secundaria en la rama principal, el trabajo continúa en la rama principal y para cuando termine, no puedo empujar mis cambios porque son incompatible.
Por lo tanto necesito "rebase" mi "merge".
Así es como finalmente lo hicimos:
1) toma nota del SHA. ex.: c4a924d458ea0629c0d694f1b9e9576a3ecf506b
git log -1
2) Cree el historial apropiado pero esto romperá la fusión.
git rebase -s ours --preserve-merges origin/master
3) toma nota del SHA. ex.: 29dd8101d78
git log -1
4) Ahora vuelve a donde estabas antes
git reset c4a924d458ea0629c0d694f1b9e9576a3ecf506b --hard
5) Ahora fusiona el maestro actual en tu rama de trabajo
git merge origin/master
git mergetool
git commit -m"correct files
6) Ahora que usted tener los archivos correctos, pero el historial incorrecto, obtener el correcto historia en la parte superior de su cambio con:
git reset 29dd8101d78 --soft
7) Y luego amend modifique los resultados en su confirmación de fusión original
git commit --amend
Voila!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-14 16:53:25
Parece que lo que quieres hacer es eliminar tu primera fusión. Puede seguir el siguiente procedimiento:
git checkout master # Let's make sure we are on master branch
git reset --hard master~ # Let's get back to master before the merge
git pull # or git merge remote/master
git merge topic
Eso te daría lo que quieres.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-24 18:10:57
- Desde tu confirmación de fusión
- Cherry-elige el nuevo cambio que debería ser fácil
- copia tus cosas
- rehaga la fusión y resuelve los conflictos simplemente copiando los archivos de tu copia local;)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-30 16:26:45