Deshacer git pull, cómo llevar repos al estado anterior

1006

¿Hay alguna forma de revertir o deshacer git pull para que mi fuente / repos recupere el estado anterior que tenía antes de hacer git pull? Quiero hacer esto porque fusionó algunos archivos que no quería, pero solo fusionó otros archivos restantes. Entonces, quiero recuperar esos archivos, ¿es eso posible?

EDITAR: Quiero deshacer git merge para aclaraciones. Después de ver algunas respuestas, hice esto

git reflog
bb3139b... HEAD@{0}: pull : Fast forward
01b34fa... HEAD@{1}: clone: from ...name...

Y ahora que debo hacer ? ¿Hacer git reset --hard está bien? No quiero volver a atornillarlo, ¿así que pide pasos detallados?

seg.server.fault
fuente
23
Parece que solo tienes dos cosas en tu historial: un clon y una búsqueda. Simplemente restablezca el clon: git reset --hard 01b34faen este caso, podría haber hecho lo git reset --hard HEAD^que se restablece a un commit antes de HEAD.
jkp
2
- duro es necesario si desea modificar archivos en su directorio de trabajo
William Pursell
3
@ seg.server.fault: si funcionó, siempre puede aceptar la respuesta;)
jkp
77
git reset --hard HEAD ^
funroll
77
git reflogmostrará todo lo que se ha hecho con git. Existe una preocupación que git reset --hard [sha1 of something from reflog]revertirá todo lo que se muestra reflog, que a veces no es un objetivo, por ejemplo. desea revertir la fusión en la rama maestra extraída del origen con datos incorrectos (sucede), y después de esa fusión ha trabajado en otras ramas. reflogmostrará cada cambio en otras ramas. Pero git checkout mastery git reset --hard [SH1 of commit on master branch just before merge]restablecerá solo la rama maestra actual eliminando la fusión extraída del origen.
Vladimir Vukanac

Respuestas:

1427

Running git pullejecuta las siguientes tareas, en orden:

  1. git fetch
  2. git merge

El paso de combinación combina ramas que se han configurado para fusionarse en su configuración. Desea deshacer el paso de fusión , pero probablemente no sea la búsqueda (no tiene mucho sentido y no debería ser necesario).

Para deshacer la fusión , use git reset --hardpara restablecer el repositorio local a un estado anterior; use git-reflog para encontrar el SHA-1 del estado anterior y luego reinícielo.

Advertencia

Los comandos enumerados en esta sección eliminan todos los cambios no confirmados, lo que puede conducir a una pérdida de trabajo:

git reset --hard

Alternativamente, restablezca a un punto particular en el tiempo, como:

git reset --hard master@{"10 minutes ago"}
jkp
fuente
325
Una excelente manera de recoger el estado anterior, en lugar de utilizar git-reflog y los hashes de copia, es utilizar un acceso directo al igual master@{1}, que es la posición previa de master, master@{"5 minutes ago"}o master@{14:30}. Los detalles completos sobre la especificación de revisiones de esta manera se pueden encontrar man git-rev-parseen la sección llamada "especificación de revisiones".
Cascabel el
38
En este caso, ORIG_HEAD también debería funcionar ("git reset --hard ORIG_HEAD")
Jakub Narębski el
@Jelfromi: gracias por ese consejo, no sabía que pudieras ser tan detallado sobre las revisiones. Sabía sobre la elección de revisiones en relación con HEAD, pero cuando se planteó la pregunta, no sabía cuánto tiempo atrás quería ir.
jkp
Cuando tiré, dice Updating d2c90a3..035ac4d. Aquí, también puede usar d2c90a3como parámetro para restablecer.
Tailandés
No necesita escribir hashes cuando usa reflog. También puede usar HEAD @ {1} o cualquier número anterior como se define en el registro.
Simon The Cat
338

Igual que la respuesta de jkp, pero aquí está el comando completo:

git reset --hard a0d3fe6

donde a0d3fe6 se encuentra haciendo

git reflog

y mirando el punto en el que desea deshacer.

Jeffrey Sun
fuente
¿Por qué no puedo simplemente hacer git reset HEAD --hard, por ejemplo?
Sung Cho
99
@MikeC Este enfoque le permite retroceder varios tirones, por ejemplo
xji
2
No pude usar los identificadores del lado izquierdo, pero git reset --hard HEAD@{n}funcionó
E. Sundin
1
Deberías haber sugerido una edición de la respuesta de jkp en lugar de casi replicarla aquí después de tantos años.
Abhishek Anand
Si tengo esto en git reflog: dab04ec HEAD @ {0}, aaaaaaa HEAD @ {1} y bbbbbbb HEAD @ {2}. Si lo hago git reset --hard bbbbbbb, ¿perderé el HEAD 0 y 1?
pmiranda
115

Una forma más moderna de deshacer una fusión es:

git merge --abort

Y la forma un poco más antigua:

git reset --merge

La forma de la vieja escuela descrita en respuestas anteriores (advertencia: descartará todos los cambios locales):

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 el comando git help for merge.

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

Después de una fusión fallida, cuando no existe MERGE_HEAD, la fusión fallida se puede deshacer git reset --mergepero no necesariamente con git merge --abort, por lo que no solo son sintaxis antiguas y nuevas para la misma cosa . Es por eso que encuentro git reset --mergemucho más útil en el trabajo diario.

Martin G
fuente
20
git merge --abortfunciona DURANTE una fusión, no después de que git pullhaya terminado. Entonces esta respuesta parece irrelevante para la pregunta.
Abhishek Anand
1
git reset --mergeelimina todos los cambios no organizados para la confirmación. Descubrí esto de la manera difícil.
theadriangreen
62

funciona primer uso: git reflog

encuentre su SHA de su estado anterior y haga (HEAD @ {1} es un ejemplo)

git reset --hard HEAD@{1}
Ezequiel García
fuente
40

Si tiene gitk (intente ejecutar "gitk --todos desde su línea de comando git"), es simple. Simplemente ejecútelo, seleccione la confirmación a la que desea revertir (haga clic con el botón derecho) y seleccione "Restablecer la rama maestra aquí". Si no tiene cambios no confirmados, elija la opción "difícil".

Samuel Carrijo
fuente
8
Vale la pena correrlo si no lo has visto. Aparece una GUI loca.
Evan Moran
35

Supongamos que $COMMITfue la última identificación de confirmación antes de realizar git pull. Lo que necesitas para deshacer el último tirón es

git reset --hard $COMMIT

.

Prima:

Al hablar de atracción, me gustaría compartir un truco interesante,

git pull --rebase

Este comando anterior es el comando más útil en mi vida git que ahorró mucho tiempo.

Antes de enviar su nueva confirmación al servidor, pruebe este comando y sincronizará automáticamente los últimos cambios del servidor (con una búsqueda + fusión) y colocará su confirmación en la parte superior en el registro de git. No necesita preocuparse por la extracción / fusión manual.

Encuentre detalles en: http://gitolite.com/git-pull--rebase

Sazzad Hissain Khan
fuente
17

Esta es la forma más fácil de revertir los cambios de extracción.

** Warning **

Realice una copia de seguridad de sus archivos modificados porque eliminará los archivos y carpetas recién creados .

git reset --hard 9573e3e0

¿Dónde 9573e3e0está tu {Commit id}

Goswami Manish
fuente
esta respuesta es muy útil, porque si hacemos una rama de origen git pull y obtenemos algo como esto Updating ffce65bd..e929e884, lo hacemosgit reset --hard ffce65bd
Ernesto Alfonso
15

tu puedes hacer git reset --hard ORIG_HEAD

desde "pull" o "merge" establezca ORIG_HEAD para que sea el estado actual antes de realizar esas acciones.

Orlando
fuente
5

git pull hacer debajo de la operación.

yo. git fetch

ii) git merge

Para deshacer pull, haga cualquier operación:

yo. git reset --hard --- revierte todos los cambios locales también

o

ii) git reset --hard master@{5.days.ago} (como 10.minutes.ago, 1.hours.ago, 1.days.ago..) para conseguir cambios locales.

o

iii) git reset --hard commitid

Mejora:

La próxima vez use en git pull --rebaselugar de git pull... su servidor de sincronización cambia haciendo (buscar y fusionar).

GolamMazid Sajib
fuente
4

Si hay una fusión fallida, que es la razón más común para querer deshacer una git pull, la ejecución git reset --mergehace exactamente lo que uno esperaría: mantener los archivos recuperados, pero deshacer la fusión que git pullintentó fusionar. Entonces uno puede decidir qué hacer sin el desorden que a git mergeveces genera. Y no necesita uno para encontrar la ID de confirmación exacta que se --hardmenciona en todas las demás respuestas.

Davide
fuente