Pregunta Cómo revertir un repositorio de Git a una confirmación previa


¿Cómo revertir desde mi estado actual a una instantánea realizada en una determinada confirmación?

Si lo hago git log, entonces obtengo el siguiente resultado:

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <me@me.com>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <me@me.com>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <me@me.com>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <me@me.com>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

Cómo revertir a la confirmación a partir del 3 de noviembre, es decir, confirmar 0d1d7fc?


6011
2017-11-06 16:58


origen


Respuestas:


Esto depende mucho de lo que quiere decir con "revertir".

Cambiar temporalmente a un compromiso diferente

Si quieres regresar temporalmente a él, tontear, y luego volver a donde estás, todo lo que tienes que hacer es verificar el compromiso deseado:

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32

O si desea realizar commits mientras está allí, siga adelante y cree una nueva sucursal mientras esté en ello:

git checkout -b old-state 0d1d7fc32

Para volver a donde estabas, simplemente mira la rama en la que estabas de nuevo. (Si ha realizado cambios, como siempre al cambiar de rama, tendrá que lidiar con ellos según corresponda. Puede restablecerlos para descartarlos, puede guardarlos, pagarlos, guardarlos para llevarlos con usted; a una rama allí si quieres una rama allí).

Duro eliminar confirmaciones no publicadas

Si, por otro lado, desea realmente deshacerse de todo lo que ha hecho desde entonces, hay dos posibilidades. Uno, si no ha publicado ninguno de estos commits, simplemente reinicie:

# 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.

Si te equivocas, ya has descartado tus cambios locales, pero al menos puedes volver a donde estabas antes reiniciando de nuevo.

Deshacer commits publicados con nuevos commits

Por otro lado, si ha publicado el trabajo, probablemente no quiera restablecer la rama, ya que eso efectivamente reescribe el historial. En ese caso, podría revertir los commits. Con Git, revertir tiene un significado muy específico: crea una confirmación con el parche inverso para cancelarla. De esta forma no reescribes ningún historial.

# This will create three separate revert commits:
git revert a867b4af 25eee4ca 0766c053

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

#Similarly, you can revert a range of commits using commit hashes:
git revert a867b4af..0766c053 

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use `rebase -i` to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

los git-revert página de manual en realidad cubre mucho de esto en su descripción. Otro enlace útil es esta sección de git-scm.com discutiendo git-revert.

Si decide que no desea revertir después de todo, puede revertir la reversión (como se describe aquí) o reiniciar de nuevo antes de revertir (consulte la sección anterior).

También puede encontrar esta respuesta útil en este caso:
¿Cómo mover HEAD a una ubicación anterior? (Cabeza separada)


7825
2017-11-06 17:04



Revertir copia de trabajo al compromiso más reciente

Para volver a una confirmación anterior, ignorando los cambios:

git reset --hard HEAD

donde HEAD es el último compromiso en su rama actual

Revertir la copia de trabajo a un compromiso anterior

Para volver a una confirmación que sea anterior a la confirmación más reciente:

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

Los créditos van a una pregunta similar sobre desbordamiento de pila, ¿Volver a una confirmación mediante un hash SHA en Git?.


1260
2017-08-21 06:19



Muchas respuestas complicadas y peligrosas aquí, pero en realidad es fácil:

git revert --no-commit 0766c053..HEAD
git commit

Esto revertirá todo desde HEAD hasta el hash de confirmación, lo que significa que volverá a crear ese estado de confirmación en el árbol de trabajo como si cada compromiso desde que se había retrocedido. A continuación, puede confirmar el árbol actual y creará un compromiso nuevo esencialmente equivalente al compromiso "revertido".

(Los --no-commit flag le permite a git revertir todas las confirmaciones de una vez; de lo contrario, se le pedirá un mensaje para cada confirmación en el rango, dejando su historial con nuevas confirmaciones innecesarias).

Esto es un manera segura y fácil de revertir a un estado anterior. No se destruye ningún historial, por lo que se puede usar para confirmaciones que ya se han hecho públicas.


1221
2018-02-12 04:18



La mejor opción para mí y probablemente para otros es la opción de reinicio de Git:

git reset --hard <commidId> && git clean -f

¡Esta ha sido la mejor opción para mí! ¡Es simple, rápido y efectivo!


Nota :  Como se menciona en los comentarios, no haga esto si comparte su sucursal con otras personas que tienen copias de las confirmaciones anteriores.

También de los comentarios, si quisieras un método menos "balbuciente" podrías usar

git clean -i 


153
2017-10-22 11:53



Si desea "confirmar", borrar el último mensaje de confirmación y volver a poner los archivos modificados en la etapa de transición, debería usar el comando:

git reset --soft HEAD~1
  • --soft indica que los archivos no confirmados deben conservarse como archivos de trabajo opuestos a --hard que los descartaría.
  • HEAD~1 es el último compromiso. Si quiere deshacer 3 commits, puede usar HEAD~3. Si desea retroceder a un número de revisión específico, también puede hacerlo utilizando su hash SHA.

Este es un comando extremadamente útil en situaciones en las que cometió un error y desea deshacer ese último compromiso.

Fuente: http://nakkaya.com/2009/09/24/git-delete-last-commit/


102
2018-03-04 17:25



Antes de responder, agreguemos algunos antecedentes, explicando qué HEAD es.

First of all what is HEAD?

HEAD es simplemente una referencia a la confirmación actual (más reciente) en la rama actual. Solo puede haber un solo HEAD en cualquier momento dado (excluyendo git worktree)

El contenido de HEAD se 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 HEAD está apuntando a una confirmación previa en la historia que se llama detached HEAD.

Enter image description here

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

Enter image description here


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 buscará una nueva rama que apunte a la confirmación deseada. Este comando se transferirá a un compromiso determinado.

En este punto, puede crear una rama y comenzar a trabajar desde este punto:

# 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 reflog también. git reflog mostrará cualquier cambio que actualizó la HEAD y verificar la entrada de reflog deseada establecerá HEAD de vuelta a este compromiso.

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

git reflog
git checkout HEAD@{...}

Esto te devolverá a tu compromiso deseado

Enter image description here


git reset HEAD --hard <commit_id>

"Mueva" la cabeza 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 git rebase --no-autostash también.

Este esquema ilustra qué comando hace qué. Como puedes ver allí reset && checkout modificar el HEAD.

Enter image description here


101
2018-02-05 21:56



He intentado muchas formas de revertir cambios locales en Git, y parece que esto funciona mejor si solo quieres volver al último estado de confirmación.

git add . && git checkout master -f

Breve descripción:

  • NO creará ningún commit como git revert hace.
  • NO separe su CABEZA como git checkout <commithashcode> hace.
  • ANULARÁ todos sus cambios locales y ELIMINARÁ todos los archivos agregados desde la última confirmación en la rama.
  • Solo funciona con nombres de ramas, por lo que puede revertir solo a la última confirmación en la rama de esta manera.

Encontré una forma mucho más conveniente y simple de lograr los resultados anteriores:

git add . && git reset --hard HEAD

donde HEAD apunta al último compromiso en su sucursal actual.

Es el mismo código de código que boulder_ruby sugirió, pero he agregado git add . antes de git reset --hard HEAD para borrar todos los archivos nuevos creados desde la última confirmación, ya que esto es lo que la mayoría de la gente espera que yo crea al volver a la última confirmación.


96
2017-07-29 11:01