2009-07-03 11 views
134

Me he encontrado con un pequeño problema aquí: tenía una rama específica del problema 28s en Git, que me fusioné en la rama general develop. Resulta que lo había hecho demasiado rápido, así que utilicé git-revert para deshacer la fusión. Ahora, sin embargo, ha llegado el momento de fusionar 28s en develop, pero el comando git-merge ve la fusión original, y felizmente anuncia que todo está bien y las ramas ya se han fusionado. ¿Qué hago ahora? Crear un "Revertir" Revertir "28s -> desarrollar" "'confirmar? No parece ser una buena manera de hacerlo, pero no puedo imaginarme otro en este momento.Rehaciendo una fusión revertida en Git

Lo que la estructura de árbol que parece:

Git log output

+0

¿Qué GUI es esa? –

+3

Es GitX (http://gitx.frim.nl). –

Respuesta

110

Usted tiene que "revertir la reversión". Depende de cómo revertiste eso, puede que no sea tan fácil como parece. Mira el official document on this topic.

---o---o---o---M---x---x---W---x---Y 
      /
     ---A---B-------------------C---D 

para permitir:

---o---o---o---M---x---x-------x-------* 
      /     /
     ---A---B-------------------C---D 

Pero lo hace todo el trabajo? Claro que sí. Puede revertir una fusión, y desde un ángulo puramente técnico , git lo hizo de forma muy natural y no tuvo problemas reales .
Simplemente lo consideró un cambio de "estado antes de la fusión" a "estado después de la fusión", y eso fue todo.
Nada complicado, nada extraño, nada realmente peligroso. Git lo hará sin siquiera pensarlo.

lo tanto, desde un punto de vista técnico, no hay nada malo con revirtiendo una fusión, pero desde un ángulo de flujo de trabajo es algo que por lo general debe tratar de evitar .

Si es posible, por ejemplo, si usted encuentra un problema que quedó fusionó en el árbol principal, en lugar de revertir la fusión, tratar realmente difícil:

  • bisect el problema hacia abajo en la rama que se fusionó, y simplemente solucionarlo,
  • o intente revertir la confirmación individual que lo causó.

sí, es más complejo, y no, no siempre va a trabajar (a veces la respuesta es: "Vaya, realmente no debería haber fusionado, porque no era listo todavía, y Realmente necesito deshacer todos de la fusión "). Entonces, usted realmente debería revertir la combinación, pero cuando quiera volver a hacer la fusión, usted ahora necesita hacerlo invirtiendo la reversión.

+5

Buen enlace (+1). Me tomé la libertad de copiar parte del documento en su respuesta para permitir que los lectores vean de inmediato las opciones relevantes en este caso. Si no está de acuerdo, siéntase libre de revertir. – VonC

+3

Acabamos de encontrarnos con un caso en el que necesitábamos hacer esto y descubrimos que la diversión no termina aquí. Era una rama de larga ejecución que se fusionó, por lo que necesitábamos continuar actualizándola. Mi enfoque aquí: http://tech.patientslikeme.com/2010/09/29/dealing-with-git-merge-revisions/ – jdwyah

+0

seguí la publicación de blog de @ jdwyah y fue gloriosa (en serio, fue increíble que solo trabajó). – hellatan

2

En lugar de utilizar git-revert que podría haber utilizado este comando en un saque de banda devel rama en distancia (deshacer) la combinación equivocada cometen (en lugar de simplemente volviendo él).

git checkout devel 
git reset --hard COMMIT_BEFORE_WRONG_MERGE 

Esto también ajustará los contenidos del directorio de trabajo en consecuencia. Tenga cuidado:

  • Guarde los cambios en la rama de desarrollo (ya que la combinación de mal) porque también serán borrados por el git-reset. Todos los commits después del que especifique como ¡el argumento git reset desaparecerá!
  • Además, no haga esto si sus cambios ya fueron extraídos de otros repositorios porque el reinicio reescribirá el historial.

Recomiendo estudiar la página de manual git-reset cuidadosamente antes de intentar esto.

Ahora, después de la restauración que se puede volver a aplicar los cambios en devel y luego hacer

git checkout devel 
git merge 28s 

Esta será una verdadera fusión de 28s en devel como la inicial (que es ahora borrado de git de historia).

+5

Para cualquiera que no esté muy familiarizado con git y quiera seguir estas instrucciones: tenga cuidado al combinar 'reset --hard' y' push origin'. También tenga en cuenta que un empuje de fuerza hacia el origen puede realmente arruinar las relaciones públicas abiertas en GitHub. – funroll

+0

Muy útil para solucionar algunos problemas de fusión en un servidor privado de git. ¡Gracias! – mix3d

+2

cambiando la historia. – njzk2

29

Supongamos que usted tiene una historia tan

---o---o---o---M---W---x-------x-------* 
      /      
     ---A---B 

Donde A, B fallaron confirmaciones y W - se revertirá de M

Así que antes de empezar a arreglar encontró problemas Yo cherry-pick de W se comprometen a mi sucursal

git cherry-pick -x W 

Entonces puedo volver W cometer en mi rama

git revert W 

Después de que puedo continuar arreglando.

La historia final podría ser:

---o---o---o---M---W---x-------x-------* 
      /     / 
     ---A---B---W---W`----------C---D 

Cuando envío un PR que se muestra claramente que PR es deshacer Revert y añade algunas nuevas confirmaciones.

+1

Parece que podría ser útil, pero es tan escaso en los detalles (lo que son C, D en el último diagrama) que es más frustrante que útil – Isochronous

+0

@Isochronous C y D parecen ser compromisos que solucionan los problemas presentados por A y B. – Thomas

+0

@Thomas exactamente –

2

Para revertir la operación de revertir sin atornillar su flujo de trabajo demasiado:

  • Crear una copia de basura locales de desarrollar
  • revertir la reversión cometen en la copia local de desarrollar
  • Combinar que copiar en su función de rama, y ​​empuje su rama de características a su servidor de git.

Su rama de características ahora debería poder combinarse normalmente cuando esté listo para ello. El único inconveniente aquí es que tendrás algunos commit/revert extra en tu historial.

1

Acabo de encontrar esta publicación cuando se enfrentan el mismo problema. Por encima de todo, me da miedo poner remedios, etc. Terminaré borrando algo que no quiero y no podré recuperarlo.

En cambio, verifiqué la confirmación a la que quería que la rama volviera, p. git checkout 123466t7632723. Luego se convirtió en una rama git checkout my-new-branch. Luego borré la rama que no quería más. Por supuesto, esto solo funcionará si puedes tirar la rama que arruinaste.

+0

El 'git reflog' lo protegerá en un restablecimiento completo durante un par de meses en caso de que más tarde descubra que necesita los commits perdidos. El reflog está limitado a su repositorio local. – Todd

Cuestiones relacionadas