¿Cómo revertir múltiples commit de git?

Tengo un repository git que se ve así:

A -> B -> C -> D -> HEAD 

Quiero que el jefe de la twig apunte a A, es decir, quiero que B, C, D y HEAD desaparezcan y quiero que la cabeza sea sinónimo de A.

Parece que puedo intentar volver a establecer la base (no se aplica, ya que he modificado los cambios) o revertir. ¿Pero cómo revertir múltiples commits? ¿Revertiré uno a la vez? Es importante la orden?

Expandiendo lo que escribí en un comentario

La regla general es que no debe reescribir (cambiar) el historial que ha publicado, porque alguien podría haber basado su trabajo en él. Si reescribe (modifica) el historial, tendría problemas para fusionar sus cambios y actualizarlos.

Entonces, la solución es crear un nuevo compromiso que revierte los cambios de los que desea deshacerse. Puedes hacer esto usando el comando git revert .

Usted tiene la siguiente situación:

 A <- B <- C <- D <- maestro <- CABEZA

(las flechas aquí se refieren a la dirección del puntero: la referencia "principal" en el caso de confirmaciones, la confirmación superior en el caso del encabezado de bifurcación (ref twig) y el nombre de bifurcación en el caso de referencia HEAD).

Lo que necesita crear es lo siguiente:

 A <- B <- C <- D <- [(BCD) ^ - 1] <- master <- HEAD

donde "[(BCD) ^ - 1]" significa la confirmación que revierte los cambios en las confirmaciones B, C, D. Las matemáticas nos dicen que (BCD) ^ - 1 = D ^ -1 C ^ -1 B ^ -1, entonces puede obtener la situación requerida usando los siguientes comandos:

 $ git revert --no-commit D $ git revert --no-commit C $ git revert --no-commit B $ git commit -m "the commit message" 

La solución alternativa sería consultar los contenidos de la confirmación A, y confirmar este estado:

 $ git checkout -f A -- . $ git commit -a 

Entonces tendrías la siguiente situación:

 A <- B <- C <- D <- A '<- maestro <- CABEZA

El compromiso A 'tiene los mismos contenidos que el compromiso A, pero es un compromiso diferente (mensaje de compromiso, padres, fecha de compromiso).

La solución de Jeff Ferland, modificada por Charles Bailey, se basa en la misma idea, pero utiliza el restablecimiento de git :

 $ git reset --hard A $ git reset --soft @{1} # (or ORIG_HEAD), which is D $ git commit 

Para hacerlo, solo tiene que usar el comando de revertir , especificando el rango de confirmaciones que desea revertir.

Teniendo en cuenta tu ejemplo, tendrías que hacer esto (asumiendo que estás en la twig ‘master’):

 git revert master~3..master 

Esto creará una nueva confirmación en su local con la confirmación inversa de B, C y D (lo que significa que deshará los cambios introducidos por estas confirmaciones):

 A <- B <- C <- D <- BCD' <- HEAD 

Manera limpia que encontré útil

 git revert --no-commit HEAD~3.. 

Este comando revierte las últimas 3 confirmaciones con solo una confirmación.

Tampoco reescribe la historia.

Similar a la respuesta de Jakub, esto le permite seleccionar fácilmente compromisos consecutivos para revertir.

 # revert all commits from B to HEAD, inclusively $ git revert --no-commit B..HEAD $ git commit -m 'message' 
 git reset --hard a git reset --mixed d git commit 

Eso actuará como una reversión para todos ellos a la vez. Da un buen mensaje de compromiso.

Primero, asegúrese de que su copia de trabajo no se modifique. Entonces:

 git diff HEAD commit_sha_you_want_to_revert_to | git apply 

y luego solo cometer. No te olvides de documentar cuál es el motivo de la reversión.

Estoy tan frustrado que esta pregunta no puede ser respondida. Todas las demás preguntas están relacionadas con cómo revertir correctamente y preservar el historial. Esta pregunta dice “Quiero que el jefe de la twig apunte a A, es decir, quiero que B, C, D y HEAD desaparezcan y quiero que la cabeza sea sinónimo de A.”

 git checkout  git reset --hard  git push -f 

Aprendí mucho leyendo la publicación de Jakub, pero un chico de la empresa (con acceso a push en nuestra twig de “pruebas” sin Pull-Request) hizo 5 commits malos tratando de arreglar y corregir un error que cometió hace 5 commits. No solo eso, sino que se aceptaron una o dos solicitudes de extracción, que ahora eran malas. Así que olvídalo, encontré el último commit bueno (abc1234) y acabo de ejecutar el script básico:

 git checkout testing git reset --hard abc1234 git push -f 

Les dije a los otros 5 chicos que trabajan en este repository que es mejor que anoten sus cambios en las últimas horas y limpie / vuelva a ramificar de las últimas pruebas. El final de la historia.

Esta es una expansión de una de las soluciones proporcionadas en la respuesta de Jakub

Me enfrenté a una situación en la que las confirmaciones que necesitaba revertir eran algo complejas, con varias de las confirmaciones que eran confusiones de fusión, y necesitaba evitar volver a escribir el historial. No pude usar una serie de comandos de git revert porque finalmente encontré conflictos entre los cambios de reversión que se estaban agregando. Terminé usando los siguientes pasos.

Primero, revisa el contenido del commit del objective mientras dejas HEAD en la punta de la twig:

 $ git checkout -f  -- . 

(El – se asegura de que se interprete como un commit en lugar de un archivo; el. Se refiere al directorio actual).

Luego, determine qué archivos se agregaron en las confirmaciones que se están retrotrayendo y, por lo tanto, deben eliminarse:

 $ git diff --name-status --cached  

Los archivos que se agregaron deberían aparecer con una “A” al comienzo de la línea, y no debería haber otras diferencias. Ahora, si es necesario eliminar algunos archivos, escenifique estos archivos para su eliminación:

 $ git rm [  ...] 

Finalmente, comprometa la reversión:

 $ git commit -m 'revert to ' 

Si lo desea, asegúrese de que volvemos al estado deseado:

 $git diff   

No debería haber diferencias.

La manera fácil de revertir un grupo de commits en el repository compartido (que las personas usan y desea preservar el historial) es usar git revert junto con git rev-list . El último le proporcionará una lista de confirmaciones, el primero hará la reversión.

Hay dos formas de hacer eso. Si desea revertir varias confirmaciones en una única confirmación, use:

 for i in `git rev-list ^..`; do git revert -n $i; done 

esto revertirá un grupo de confirmaciones que necesita, pero deje todos los cambios en su árbol de trabajo, debe enviarlos todos como de costumbre.

Otra opción es tener una única confirmación por cambio revertido:

 for i in `git rev-list ^..`; do git revert --no-edit -s $i; done 

Por ejemplo, si tiene un árbol de commits como

  o---o---o---o---o---o---> fff eee ddd ccc bbb aaa 

para revertir los cambios de eee a bbb , ejecuta

 for i in `git rev-list eee^..bbb`; do git revert --no-edit -s $i; done 

Ninguno de ellos funcionó para mí, así que tuve tres compromisos para revertir (los últimos tres compromisos), así que lo hice:

 git revert HEAD git revert HEAD~2 git revert HEAD~4 git rebase -i HEAD~3 # pick, squash, squash 

Trabajado como un encanto 🙂

Si desea revertir temporalmente las confirmaciones de una característica, puede usar la serie de comandos siguientes.

Así es como funciona

git log –pretty = oneline | grep ‘feature_name’ | cut -d ” -f1 | xargs -n1 git revert –no-edit

    Intereting Posts