Cómo deshacer el último compromiso de git sin empujar sin perder los cambios

541

¿Hay alguna forma de revertir una confirmación para que mi copia local mantenga los cambios realizados en esa confirmación, pero se conviertan en cambios no confirmados en mi copia de trabajo? Revertir una confirmación lo lleva a la confirmación anterior: quiero mantener los cambios realizados, pero los confirmé en la rama incorrecta.

Esto no ha sido empujado, solo cometido.

Señor chico
fuente
66
git reset --softy git reset --mixedambos hacen esto (un poco diferente), vea git-reset
torek

Respuestas:

933

Hay muchas formas de hacerlo, por ejemplo:

en caso de que aún no haya presionado el compromiso públicamente:

git reset HEAD~1 --soft   

Eso es todo, sus cambios de confirmación estarán en su directorio de trabajo, mientras que la ÚLTIMA confirmación se eliminará de su rama actual. Ver git reset man


En caso de que haya presionado públicamente (en una rama llamada 'maestro'):

git checkout -b MyCommit //save your commit in a separate branch just in case (so you don't have to dig it from reflog in case you screw up :) )

revertir comprometer normalmente y presionar

git checkout master
git revert a8172f36 #hash of the commit you want to destroy
# this introduces a new commit (say, it's hash is 86b48ba) which removes changes, introduced in the commit in question (but those changes are still visible in the history)
git push origin master

ahora, si desea tener esos cambios a medida que cambia localmente en su copia de trabajo ("para que su copia local mantenga los cambios realizados en esa confirmación"), simplemente revierta la --no-commitopción revertir confirmación con la opción:

git revert --no-commit 86b48ba (hash of the revert commit).

He creado un pequeño ejemplo: https://github.com/Isantipov/git-revert/commits/master

Isantipov
fuente
55
muchas gracias, en mi caso tuve dos confirmaciones que quería cancelar, y ejecutar 'git reset HEAD ~ 1 --soft' dos veces seguidas me llevó a donde necesitaba estar.
Geoff Gunter
2
para agregar un poco de claridad si no está usando CLI, el primer resetcomando mencionado es restablecer "suavemente" a 1 rev antes de la cabeza, lo que preserva todos los cambios locales. Esto no fue inmediatamente evidente para mí para su uso en SourceTree. solo asegúrate de que estás reiniciando la revisión anterior, no la que estás intentando restablecer
Jon B
1
Probé el enfoque "ya empujado" y no funciona para mí, con git 2.14.1: dice "Already up to date"al hacer la fusión.
Fabio A.
1
@FabioA. , He actualizado la respuesta con una versión funcional. ¡Gracias por notar esto!
Isantipov
1
Esto no funciona Me salteé el reinicio y el compromiso, y solo git se revertió y expulsó ... ahora tal vez los cambios se perdieron aún no estoy seguro ... afortunadamente hice una copia de seguridad de la manera fácil, espero que todavía funcione;) de lo contrario, puedo copiar los cambios de ese .
Skybuck Flying
13

Si presionó los cambios, puede undohacerlo y mover los archivos nuevamente al escenario sin usar otra rama.

git show HEAD > patch
git revert HEAD
git apply patch

Creará un archivo de parche que contiene los últimos cambios de rama. Luego revierte los cambios. Y finalmente, aplique los archivos de parche al árbol de trabajo.

Aminadav Glickshtein
fuente
es posible que rm patchtambién quieras
Max Coplan
6

Para el caso: "Esto no ha sido empujado, solo cometido ". - si usa IntelliJ (u otro IDE de JetBrains) y aún no ha introducido cambios , puede hacer lo siguiente.

  1. Vaya a la ventana Control de versiones ( Alt + 9 / Comando + 9 ) - pestaña "Registro".
  2. Haga clic derecho en una confirmación antes de su última.
  3. Restablecer la rama actual aquí
  4. recoger suave (!!!)
  5. presione el botón Restablecer en la parte inferior de la ventana de diálogo.

Hecho.

Esto "confirmará" sus cambios y devolverá su estado de git al punto anterior a su última confirmación local. No perderá ningún cambio que haya realizado.

Eduard Streltsov
fuente
2
Me encanta aprender a la manera de JetBrains, ¡gracias! Eso es equivalente a git reset --soft "HEAD^"en Windows, por cierto. :)
Payne
3

La mayoría de las veces sucede cuando empujo los cambios a la rama incorrecta y me doy cuenta más tarde. Y los siguientes trabajos en la mayoría de las veces.

git revert commit-hash
git push

git checkout my-other-branch
git revert revert-commit-hash
git push
  1. revertir el commit
  2. (crear y) pagar otra sucursal
  3. revertir el revertir
Mubashar
fuente
1
Probé esto. Su enfoque también funciona si no ha presionado al control remoto. $ git revert <commit-hash> ... luego verifique alguna otra rama, luego escriba $ git revert <revert-commit-hash> (sin los empujes). ¡Gracias por compartir este enfoque simple!
Natalie Cottrill
2

2020 forma simple:

git reset <commit_hash>

Compite el hash del último compromiso que deseas mantener.

Xys
fuente
1

Asegúrese de hacer una copia de seguridad de sus cambios antes de ejecutar estos comandos en una carpeta separada

git checkout branch_name

Pago en su sucursal

git merge --abort

Abortar la fusión

estado git

Verifique el estado del código después de abortar la fusión

git reset: origen duro / nombre_de_ rama

estos comandos restablecerán sus cambios y alinearán su código con el código branch_name (branch).

Mohit Singh
fuente