Deshacer una fusión Git que aún no se ha presionado

3945

Dentro de mi rama maestra, hice un git merge some-other-branchlocal, pero nunca empujé los cambios al maestro de origen. No quise fusionarme, así que me gustaría deshacerlo. Cuando git statushice una después de mi fusión, recibí este mensaje:

# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.

Según algunas instrucciones que encontré , intenté ejecutar

git revert HEAD -m 1

pero ahora recibo este mensaje con git status:

# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.

No quiero que mi sucursal esté por delante de ninguna cantidad de confirmaciones. ¿Cómo vuelvo a ese punto?

Matt Huggins
fuente
3
Si necesita preservar la historia, en otras palabras, hay un cambio que alguien ha sacado de usted o lo ha empujado a alguna parte, ¡use la solución en la respuesta de Yuri Ushakov a continuación!
Sedrik
66
Anule la selección de la respuesta ganadora actual, es insegura (como muchos señalaron) aunque aún reúne votos. Para mí, "MBO" se ve mejor, aunque tiene muchos menos puntos.
Inger
55
¡Si necesita preservar el historial , use la solución de Yuri a continuación ! (solo agregando un enlace al comentario de @Sedrik)
cregox
3
Este es un gran recurso directamente de Github: Cómo deshacer (casi) cualquier cosa con Git
jasonleonhard 03 de

Respuestas:

4461

Con git reflogcomprobar qué confirmación es una antes de la fusión ( git reflogserá una mejor opción que git log). Luego puede restablecerlo usando:

git reset --hard commit_sha

También hay otra forma:

git reset --hard HEAD~1

Te devolverá 1 commit.

Tenga en cuenta que los archivos modificados y no confirmados / sin reiniciar se restablecerán a su estado no modificado . Para mantenerlos alejados de los cambios o ver la --mergeopción a continuación.


Como @Velmont sugirió a continuación en su respuesta, en este caso directo usando:

git reset --hard ORIG_HEAD

podría producir mejores resultados, ya que debería preservar sus cambios. ORIG_HEADseñalará una confirmación directamente antes de que se produzca la fusión, por lo que no tiene que buscarla usted mismo.


Un consejo adicional es usar el --mergeinterruptor en lugar de, --hardya que no restablece los archivos innecesariamente:

git reset --merge ORIG_HEAD

--unir

Restablece el índice y actualiza los archivos en el árbol de trabajo que son diferentes entre <commitir> y HEAD, pero mantiene aquellos que son diferentes entre el índice y el árbol de trabajo (es decir, que tienen cambios que no se han agregado).

Marcin Gil
fuente
129129
No creo que esto funcione (¿siempre?): El "uno antes de la fusión" será la confirmación más reciente que se fusionó desde la otra rama; no será la confirmación más reciente en la rama actual . ¿Derecha? (Esto podría ser el resultado de lo que git logelige mostrar de forma predeterminada; tal vez haya una salida diferente git logo git reflogpodría usarse para esto)
John Bachir
66
Creo que podría depender si fusionas la calabaza.
Marcin Gil
29
@JohnBachir tiene razón. En el git logresultado, desea ver las dos confirmaciones principales. Una es la última confirmación en su rama, otra es la última confirmación en la rama en la que se fusionó. Desea que git reset --hardel padre se comprometa en la rama en la que se fusionó.
Justin
77
@JohnBachir: Mientras la "fusión" no sea realmente un avance rápido, dará como resultado una nueva confirmación que se encuentra en la parte superior del registro, y esta confirmación tiene dos padres (o más de 2 si haces un pulpo) unir). Si elimina esta confirmación de fusión, también desaparecerán todas las confirmaciones anteriores que vinieron de la fusión. Sin embargo, para estar seguro, después de un reinicio, git le dirá dónde está el nuevo encabezado: "HEAD ahora está en 88a04de <mensaje de confirmación>". Siempre miro eso para asegurarme de que terminé donde esperaba estar. Mi proyecto utiliza un esquema estándar de nombres de sucursales para mantener las cosas memorables.
Mark E. Haase
44
Lo que encontré útil fue mirar "git reflog" y buscar el último commit que hice en master. Entonces hazlogit reset --hard <commit_sha>
Max Williams
1456

Suponiendo que su maestro local no estuviera por delante del origen / maestro, debería poder hacer

git reset --hard origin/master

Entonces su mastersucursal local debería ser idéntica a origin/master.

randomguy3
fuente
71
@Carter en realidad no es la mejor respuesta. Es posible que el origen / maestro esté por delante de su maestro local justo antes de la fusión por parte de algunos commits, en ese caso esto podría no dar los resultados deseados
Dhruva Sagar
15
@ dhruva-sagar Sí, pero mientras git no diga que estás atrasado y no buscas, deberías estar bien.
Kelvin
3
¡Gracias! Esto es perfecto si (y solo si) tiene un repositorio remoto.
tomc
2
No, no es el perfecto para esta pregunta, vea la cláusula "asumir". La respuesta de MBO en realidad cubre este caso, y el caso donde la fusión no es la única confirmación local.
Inger
2
Una vez más, tal vez esta advertencia debería ir a la respuesta en sí: ¡ siempre evita reescribir el historial de git!
cregox
1175

Ver capítulo 4 en el libro de Git y la publicación original de Linus Torvalds .

Para deshacer una fusión que ya fue empujada :

git revert -m 1 commit_hash

Asegúrese de revertir la reversión si está volviendo a comprometer la rama, como dijo Linus.

Yuri Geinish
fuente
10
@perfectionist estuvo de acuerdo :) Espero que hubiera una manera de migrar esta respuesta a otra pregunta-- (¿tal vez sí?)
mikermcneil
para obtener más información sobre revertir: enlace
assaqqaf
1
Para estar seguro de que esta reversión ha funcionado, puede hacer git diff hash1 hash2 donde hash1 es la reversión comprometida, y hash2 es la confirmación anterior a cuyo estado estaba tratando de volver. Sin salida == éxito! Pude revertir varias confirmaciones haciendo esto varias veces, comenzando por revertir la fusión más reciente y trabajando hacia atrás. git diff me mostró que terminé en el estado que quería.
Robert Sinton
66
Tenga en cuenta que esto en realidad no resuelve la pregunta del póster original . El póster original ya usado git revert -m 1 <commit>. El problema es que hacer eso no borra la fusión accidental que hizo (y aún no ha presionado). Las otras respuestas que involucran reinicios duros son mejores para el problema del póster original.
Este es un gran recurso directamente de Github: cómo deshacer (casi) cualquier cosa con Git
jasonleonhard 03 de
986

Es extraño que faltara el comando más simple. La mayoría de las respuestas funcionan, pero deshaciendo la fusión que acaba de hacer, esta es la manera fácil y segura :

git reset --merge ORIG_HEAD

El árbitro ORIG_HEADapuntará al commit original antes de la fusión.

(La --mergeopción no tiene nada que ver con la fusión. Es igual git reset --hard ORIG_HEAD, pero más segura, ya que no toca los cambios no confirmados).

odinho - Velmont
fuente
17
Si ha ensuciado su árbol de trabajo desde entonces, git reset --merge ORIG_HEADconserva esos cambios.
gritó el
1
Esta es la única respuesta correcta (no digo que esta sea la mejor respuesta, tenga en cuenta la diferencia). Digamos, en master, hice 3 commits en t1, t3 y t5. Digamos, en la rama 1, hice 3 comentarios en t2, t4 y t6 (supongamos que t1, t2, t3, t4, t5 y t6 están en orden cronológico). Cualquier comando similar a git reset --hard HEAD~5solo restablecerá HEAD (puede eliminar confirmaciones tanto en maestro como en branch1). Solo la --mergeopción elimina el merge.
Manu Manjunath
@Manu La --mergeopción en realidad no elimina la fusión, puede usarla --hardtambién funcionará bien. Es la referencia ORIG_HEAD que es la pista aquí, se establece antes de hacer una fusión en el punto en el que se encuentra. :)
odinho - Velmont
@yingted, ¿qué quieres decir con "si has ensuciado tu árbol de trabajo desde entonces, git reset --merge ORIG_HEAD conserva esos cambios". ¿Quiso decir cambiar los archivos después de la fusión? De todos modos hice la fusión y luego resolví algunos conflictos. Pero luego quise restablecer la fusión e hice lo que se indica en esta respuesta. Todo estuvo bien y no ha conservado mis cambios realizados después de la fusión. Mi repositorio local es similar a la posición anterior a la fusión.
Samitha Chathuranga
El git reset --hard ORIG_HEADcomando funcionó perfectamente para mí: puede haber sido ayudado por el hecho de que no hice ningún otro cambio en el repositorio después del local git mergeque estaba tratando de deshacer. El comando simplemente restablece el estado del repositorio a su estado anterior a la fusión. Gracias por el gran consejo!
bluebinary
391

Con las versiones más nuevas de Git, si aún no ha comprometido la fusión y tiene un conflicto de fusión , simplemente puede hacer:

git merge --abort

De man git merge:

[Esto] solo se puede ejecutar después de que la fusión haya generado conflictos. git merge --abortabortará el proceso de fusión e intentará reconstruir el estado previo a la fusión.

Travis Reeder
fuente
8
Su fusión está comprometida pero no empujada (ver título), ya se ha fusionado, su comando funciona solo cuando todavía está en medio de una fusión
JBoy
135

Debe restablecer la confirmación anterior. Esto debería funcionar:

git reset --hard HEAD^

O incluso HEAD^^ revertir ese compromiso de reversión. Siempre puede dar una referencia SHA completa si no está seguro de cuántos pasos debe dar.

En caso de que tenga problemas y su rama maestra no haya tenido cambios locales, puede restablecerla origin/master.

MBO
fuente
55
La mejor respuesta en mi humilde opinión, incorpora el propio OP (suponiendo solo 1 paso para revertir, que parecía ser el caso en la Q), así como el acceso directo de randomguy3 (que funciona cuando "su rama maestra no tuvo ningún cambio local") ")
inger
44
Ustedes comentaristas, @Inger y @Konstantin, ¿por qué? Viniste aquí después de que se creó mi respuesta, y es más correcto. Simplemente subir la CABEZA un paso a menudo es incorrecto, y tendrías que contar qué tan lejos debes llegar. Git ya está configurado ORIG_HEADpara ti, ¿por qué no usarlo?
Odinho - Velmont
¿restablecerá también los cambios locales? #Por favor actualice.
Cód.
Esto funcionó perfectamente para mí, restablecer la cabeza de esa manera tiene mucho más sentido que la mitad de las respuestas aquí.
Varda Elentári
HEAD ^ es igual a commit antes que HEAD? y ^^ son dos commits anteriores? ¿Supongo que esto no funcionará con las fusiones de avance rápido?
Marcus Leon
87

Últimamente, he estado usando git reflogpara ayudar con esto. Esto en su mayoría solo funciona si la fusión SÓLO ocurrió, y estaba en su máquina.

git reflog podría devolver algo como:

fbb0c0f HEAD@{0}: commit (merge): Merge branch 'master' into my-branch
43b6032 HEAD@{1}: checkout: moving from master to my-branch
e3753a7 HEAD@{2}: rebase finished: returning to refs/heads/master
e3753a7 HEAD@{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830e
b41ea52 HEAD@{4}: reset: moving to HEAD^
8400a0f HEAD@{5}: rebase: aborting

La primera línea indica que se produjo una fusión. La segunda línea es el tiempo antes de mi fusión. Simplemente forzo git reset --hard 43b6032a esta rama a rastrear antes de la fusión, y continuar.

Parris
fuente
Gran respuesta, gracias! Necesitaba deshacer una fusión, pero las otras respuestas simplemente lo estropearon más, usando reflogpara obtener el SHA y pasarlo a git resetfuncionar.
Lankymart
51

Con Git moderno, puedes:

git merge --abort

Sintaxis anterior:

git reset --merge

Vieja escuela:

git reset --hard

Pero en realidad, vale la pena notar que git merge --abortsolo es equivalente a lo git reset --mergedado que MERGE_HEADestá presente. Esto se puede leer en la ayuda de Git para el comando de fusión.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

Después de una fusión fallida, cuando no hay MERGE_HEAD , la fusión fallida se puede deshacer git reset --merge, pero no necesariamente con git merge --abort, por lo que no solo son sintaxis antiguas y nuevas para la misma cosa .

Personalmente encuentro git reset --merge mucho más poderoso y útil en el trabajo diario, así que ese es el que siempre uso.

Martin G
fuente
Funcionó muy bien para mí. Cada otra publicación dice que esto es muy complicado, pero esto hizo exactamente lo que se espera. Supongo que solo funcionó porque hubo conflictos, lo que no responde exactamente a la pregunta original.
Jeremy
Esta respuesta no se centra en la situación del OP y deja fuera un contexto importante.
Ben Wheeler
37

De acuerdo, las respuestas que otras personas me dieron fueron cercanas, pero no funcionó. Esto es lo que hice.

Haciendo esto...

git reset --hard HEAD^
git status

... me dio el siguiente estado.

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.

Luego tuve que escribir el mismo git resetcomando varias veces más. Cada vez que hice eso, el mensaje cambió en uno, como puede ver a continuación.

> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 2 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

En este punto, vi que el mensaje de estado cambió, así que intenté hacer un git pull, y eso pareció funcionar:

> git pull
Updating 2df6af4..12bbd2f
Fast forward
 app/views/truncated |    9 ++++++---
 app/views/truncated |   13 +++++++++++++
 app/views/truncated |    2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)
> git status
# On branch master

En resumen, mis órdenes se redujeron a esto:

git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git pull
Matt Huggins
fuente
19
o podrías haber usadoHEAD^^^^
hasen
17
tal vez incluso restablecer a origin/master;)
hasen
23

Podrías usar git reflogpara encontrar el pago anterior. A veces es un buen estado al que quieres volver.

Concretamente

$ git reflog
$ git reset --hard HEAD@{0}
stephjang
fuente
1
¡Gracias! Ahorraste medio día de mi trabajo. Sin embargo, no pude salir del modo de registro con ningún comando.
Katarzyna
1
@Katarzyna usa la tecla "q" para salir del reflog
Amjed Baig
21

Si está en medio de la fusión, siempre puede abortarlo git merge --abort

llioor
fuente
2
gracias hermano y estaba a punto de hacer esa respuesta correcta de miedo. Por suerte me desplacé hacia abajo. solo quiero eliminar la fusión de cabeza
Nyuu
15

Pude resolver este problema con un solo comando que no implica buscar una identificación de confirmación.

git reset --hard remotes/origin/HEAD

La respuesta aceptada no funcionó para mí, pero este comando logró los resultados que estaba buscando.

Ralph Ritoch
fuente
¡Exactamente! ¡Restablece tus cambios a la CABEZA de la rama! No hacer uno por uno
Carlos Zinato
No funcionó para mí. en realidad terminó enviando una sucursal local de vuelta uno o dos meses. Afortunadamente, todo esto es local, por lo que siempre puedo destruir la rama y recuperarla nuevamente. Solo quería señalar eso en caso de que otros intentaran esto.
Matt Pengelly
@MattPengelly, este método no está documentado en gran medida y, por lo general, funciona si su rama está sincronizada con la rama remota antes de realizar la fusión. ¿Han pasado meses desde que su sucursal estaba sincronizada con la sucursal remota?
Ralph Ritoch
@MattPengelly también depende de a qué rama apunta la CABEZA. Estoy usando gitflow en uno de mis proyectos, y aunque estoy en la rama de desarrollo, los controles remotos / origen / CABEZA apuntan a origen / maestro, por lo que si necesito deshacer una fusión, probablemente deba restablecer los controles remotos / origen / desarrollo
Ralph Ritoch
14

Si aún no lo ha confirmado, solo puede usar

$ git checkout -f

Deshacerá la fusión (y todo lo que hiciste).

Mente ideal
fuente
Probé esto y en realidad aumentó el número de confirmaciones que mi sucursal local está por delante.
Barclay
14

Llegué a esta pregunta también buscando volver a coincidir con el origen (es decir, NO se compromete antes del origen). Investigando más, descubrí que hay un resetcomando para exactamente eso:

git reset --hard @{u}

Nota: @{u}es la abreviatura de origin/master. (Y, por supuesto, necesita ese repositorio remoto para que esto funcione).

leanne
fuente
14

Tienes que cambiar tu CABEZA, no la tuya, por supuesto, sino git HEAD ...

Entonces, antes de responder, agreguemos algunos antecedentes, explicando qué es esto HEAD.

First of all what is HEAD?

HEADes simplemente una referencia a la confirmación actual (más reciente) en la rama actual.
Solo puede haber una sola HEADen un momento dado. (excluyendo git worktree)

El contenido de HEADse almacena dentro .git/HEADy contiene los 40 bytes SHA-1 de la confirmación actual.


detached HEAD

Si no está en la última confirmación, lo que significa que HEADapunta a una confirmación previa en la historia se llama detached HEAD.

ingrese la descripción de la imagen aquí

En la línea de comando, se verá así: SHA-1 en lugar del nombre de la rama ya HEADque no apunta a la punta de la rama actual

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Algunas opciones sobre cómo recuperarse de un HEAD separado:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Esto verificará la nueva rama que apunta a la confirmación deseada.
Este comando pagará a un commit dado.
En este punto, puede crear una rama y comenzar a trabajar desde este punto en adelante.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Siempre puedes usar el reflogtambién.
git reflogmostrará cualquier cambio que haya actualizado HEADy revisando la entrada de reflog deseada establecerá el HEADrespaldo de este commit.

Cada vez que se modifique el HEAD habrá una nueva entrada en el reflog

git reflog
git checkout HEAD@{...}

Esto lo llevará de regreso a su compromiso deseado

ingrese la descripción de la imagen aquí


git reset --hard <commit_id>

"Mueva" su CABEZA de nuevo a la confirmación deseada.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Nota: ( desde Git 2.7 )
    también puedes usar el git rebase --no-autostash.

git revert <sha-1>

"Deshacer" el compromiso o rango de compromiso dado.
El comando reset "deshacerá" cualquier cambio realizado en el commit dado.
Se confirmará una nueva confirmación con el parche de deshacer, mientras que la confirmación original también permanecerá en el historial.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Este esquema ilustra qué comando hace qué.
Como puede ver allí reset && checkoutmodifique el HEAD.

ingrese la descripción de la imagen aquí

CodeWizard
fuente
Esto es un tesoro 🐱‍👤🐱‍👤🐱‍👤
Jawand Singh
12

La respuesta más simple es la dada por odinho - Velmont

Primero hacer git reset --merge ORIG_HEAD

Para aquellos que buscan restablecer después de presionar los cambios, haga esto (porque esta es la primera publicación vista para cualquier pregunta de combinación de restablecimiento de git)

git push origin HEAD --force

Esto se restablecerá de manera que no recupere los cambios combinados nuevamente después de extraer.

Harsha
fuente
10

Solo para ver una opción adicional, he seguido principalmente el modelo de ramificación descrito aquí: http://nvie.com/posts/a-successful-git-branching-model/ y, como tal, me he estado fusionando con--no-ff (no avance rápido) generalmente.

Acabo de leer esta página porque accidentalmente fusioné una rama de prueba en lugar de mi rama de lanzamiento con master para la implementación (sitio web, master es lo que está en vivo). La rama de prueba tiene otras dos ramas fusionadas y totaliza alrededor de seis confirmaciones.

Entonces, para revertir todo el commit, solo necesitaba uno git reset --hard HEAD^y revirtió toda la fusión. Dado que las fusiones no se reenviaron rápidamente, la fusión fue un bloqueo y un paso atrás es "rama no fusionada".

Damien Byrne
fuente
10

Puede usar solo dos comandos para revertir una fusión o reiniciar mediante una confirmación específica:

  1. git reset --hard commitHash (debe usar la confirmación que desea reiniciar, por ejemplo, 44a587491e32eafa1638aca7738)
  2. git push origin HEAD --force (Envío de la nueva rama maestra local a origen / maestro)

Buena suerte y adelante!

Matheus Abreu
fuente
10

Se puede hacer de múltiples maneras.

1) Abortar fusión

Si está en medio de una fusión incorrecta (por error, con una rama incorrecta), y desea evitar la fusión para volver a la última rama como se muestra a continuación:

git merge --abort

2) Restablecer HEAD a rama remota

Si está trabajando desde la rama de desarrollo remoto, puede restablecer HEAD a la última confirmación en la rama remota de la siguiente manera:

git reset --hard origin/develop

3) Eliminar la rama actual y volver a pagar desde el repositorio remoto

Teniendo en cuenta que está trabajando en la sucursal de desarrollo en el repositorio local, que se sincroniza con la sucursal remota / de desarrollo, puede hacer lo siguiente:

git checkout master 
##to delete one branch, you need to be on another branch, otherwise you will fall with the branch :) 

git branch -D develop
git checkout -b develop origin/develop
Amit Kaneria
fuente
que "1) Abortar combinación" era bastante bonita. Votación a favor.
CodeToLife
1
¡Ten cuidado! git merge --abort "solo se puede ejecutar después de que la fusión haya generado conflictos. git merge --abort abortará el proceso de fusión e intentará reconstruir el estado previo a la fusión"
Pedro García Medina
8

Si su fusión y las confirmaciones correspondientes aún no se enviaron, siempre puede cambiar a otra rama, eliminar la original y volver a crearla.

Por ejemplo, fusioné accidentalmente una rama de desarrollo en maestro y quería deshacer eso. Usando los siguientes pasos:

git checkout develop
git branch -D master
git branch -t master origin/master

Voila! El Maestro está en la misma etapa que el origen, y tu estado mal fusionado se borra.

Stephan
fuente
1
Nota: Esto no solo deshace la fusión, sino también cualquier confirmación local que se haya realizado desde el último envío al origen.
Martijn Heemels
4

Si desea una solución de línea de comandos, le sugiero que vaya con la respuesta de MBO.

Si eres un novato, puede que te guste el enfoque gráfico:

  1. Patada inicial gitk (desde la línea de comando, o haz clic derecho en el explorador de archivos si tienes eso)
  2. Puede detectar fácilmente la confirmación de fusión allí: el primer nodo desde arriba con dos padres
  3. Siga el enlace al primer padre / izquierdo (el que está en su rama actual antes de la fusión, generalmente rojo para mí)
  4. En la confirmación seleccionada, haga clic con el botón derecho en "Restablecer rama aquí", seleccione el restablecimiento completo allí
inger
fuente
4

Estrategia: crear una nueva sucursal desde donde todo estaba bien.

Razón fundamental: Revertir una fusión es difícil. Hay demasiadas soluciones, dependiendo de muchos factores, como si se ha comprometido o empujado su fusión o si hubo nuevas confirmaciones desde su fusión. Además, aún debe tener una comprensión relativamente profunda de git para adaptar estas soluciones a su caso. Si sigue ciegamente algunas instrucciones, puede terminar con una "fusión vacía" donde nada se fusionará, y los intentos de fusión adicionales harán que Git le diga "Ya actualizado".

Solución:

Digamos que desea combinar deven feature-1.

  1. Encuentre la revisión en la que desea recibir la fusión:

    git log --oneline feature-1
    a1b2c3d4 Merge branch 'dev' into 'feature-1' <-- the merge you want to undo
    e5f6g7h8 Fix NPE in the Zero Point Module <-- the one before the merge, you probably want this one
    
  2. Compruébalo (retrocede en el tiempo):

    git checkout e5f6g7h8
    
  3. Crea una nueva sucursal desde allí y échale un vistazo:

    git checkout -b feature-1
    

Ahora puede reiniciar su fusión:

  1. Unir: git merge dev

  2. Arregla tus conflictos de fusión.

  3. Cometer: git commit

  4. Cuando esté satisfecho con los resultados, elimine la rama anterior: git branch --delete feature-1

pyb
fuente
2

Simplemente cree una nueva rama, luego seleccione las confirmaciones deseadas.

Es más simple y ahorrador, y luego se reinicia como se describe en muchas respuestas anteriores

devi
fuente
1
Estoy de acuerdo con esta sugerencia, especialmente si no está completamente cómodo con los comandos git enumerados. Esto puede ser más lento con más "trabajo duro", pero si no surge mucho y le preocupa perder su trabajo, vale la pena el esfuerzo.
Greg
1

Creo que puede hacer git rebase -i [hash] [branch_name] dónde [hash]está el hash de identificación por el tiempo que desee rebobinar más uno (o por la cantidad de confirmaciones que desee ir) y luego elimine las líneas para las confirmaciones en el editor que ya no desea. . Guarda el archivo. Salida. Orar. Y debe ser rebobinado. Puede que tenga que hacer un git reset --hard, pero debería ser bueno en este punto. También puede usar esto para extraer confirmaciones específicas de una pila, si no desea mantenerlas en su historial, pero eso puede dejar su repositorio en un estado que probablemente no desee.

Tychoish
fuente
1

Si cometió la fusión:

git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard
dorio
fuente
1
  1. Primero, asegúrate de haber comprometido todo.

  2. Luego restablezca su repositorio al estado de trabajo anterior:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

    o usando --hard( esto eliminará todos los cambios locales, no confirmados ):

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

    Use el hash que estaba allí antes de su commit incorrectamente fusionado.

  3. Comprueba qué confirmaciones te gustaría volver a confirmar en la parte superior de la versión correcta anterior:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    ...
    
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    
    ...
    
  4. Aplique sus confirmaciones correctas en la parte superior de la versión correcta de su repositorio de la siguiente manera:

    • Mediante el uso de cherry-pick (los cambios introducidos por algunos commits existentes)

          git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
      
    • O seleccionando el rango de confirmaciones por:

      • Primero verifique los cambios correctos antes de fusionarlos:

        git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        
      • Primero verifique los cambios correctos antes de fusionarlos:

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        

        donde este es el rango de las confirmaciones correctas que ha comprometido (excluyendo la combinación erróneamente comprometida).

kenorb
fuente
1
  1. git stash

  2. git branch -d the_local_branch

  3. git checkout -t <name of remote>

  4. git stash apply

Esto funcionó para mí .. !!

Siva Kumar
fuente
0

Si nota que necesita revertir inmediatamente después de la fusión y no ha hecho nada más después del intento de fusión, puede emitir este comando: git reset --hard HEAD@{1} .

Esencialmente, su fusión shaseñalará HEAD@{0}si no se cometió nada más después de la fusión y también lo HEAD@{1}será el punto anterior antes de la fusión.

Deber A.
fuente
0

La más simple de las posibilidades más simples, mucho más simple de lo que se dice aquí:

Elimine su sucursal local (local, no remota) y vuelva a tirar de ella. De esta forma, deshacerá los cambios en su rama maestra y cualquiera se verá afectado por el cambio que no desea impulsar. Comience de nuevo.

Luis
fuente
0

En este caso, querrá restablecer su rama con git reset --hard <branch_name>. Si desea guardar sus cambios antes de reiniciarlos, asegúrese de crear una nueva rama y git checkout <branch_name>.

También puede restablecer el estado a una confirmación específica con git reset --hard <commit_id>.

Si se han introducido los cambios, puede usarlos git revert <branch_name>. Asegúrese de consultar cómo usar git revert y git checkout en otros escenarios también.

Nesha Zoric
fuente