Revertir un rango de confirmaciones en git

127

¿Cómo puedo revertir un rango de confirmaciones en git? Al mirar la documentación de gitrevisions , no puedo ver cómo especificar el rango que necesito. Por ejemplo:

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

Quiero hacer el equivalente de:

git revert B-D

donde el resultado sería:

A -> B -> C -> D -> E -> F -> HEAD

donde F contiene el reverso de BD inclusive.

Alex Spurling
fuente
Hacia el final de la página gitrevisions (7), hay una sección titulada "ESPECIFICANDO RANGOS". ¿Cómo difiere lo que quieres de lo que se describe allí?
Gareth McCaughan
2
La página gitrevisions sugiere que 'git revert A..D' hará lo que quiera. Sin embargo, cuando trato de obtener el error "fatal: No se puede encontrar 'A..D'"
Alex Spurling

Respuestas:

172

¿Qué versión de Git estás usando?

Para revertir múltiples confirmaciones solo se admite en Git1.7.2 +: consulte " Revertir a una confirmación anterior usando revertir varias veces " para obtener más detalles.
La git revertpágina de manual actual es solo para la versión actual de Git (1.7.4+).


Como el OP Alex Spurling informa en los comentarios:

La actualización a 1.7.4 funciona bien.
Para responder a mi propia pregunta, esta es la sintaxis que estaba buscando:

git revert B^..D 

B^significa "la primera confirmación principal de B": que permite incluir Ben la reversión.
Consulte la git rev-parsesección " ESPECIFICAR REVISIONES " que incluye <rev>^, por ejemplo, laHEAD^ sintaxis: ver más en " ¿Qué significa el carácter caret ( ^)? ")

Tenga en cuenta que cada confirmación revertida se confirma por separado.

Henrik N aclara en los comentarios :

git revert OLDER_COMMIT^..NEWER_COMMIT

Como se muestra a continuación, puede revertir sin comprometerse de inmediato:

git revert -n OLDER_COMMIT^..NEWER_COMMIT
git commit -m "revert OLDER_COMMIT to NEWER_COMMIT"
VonC
fuente
1
Gracias, esa fue la respuesta. La actualización a 1.7.4 funciona bien. Para responder a mi propia pregunta, esta es la sintaxis que estaba buscando: git revert B ^ .. D
Alex Spurling
genio. Gracias. No se me había ocurrido que necesito revertir los commits en orden inverso para que se apliquen los parches, duh. Este comando muestra el camino.
Tim Abell
55
Me refiero a esta respuesta a menudo, y siempre me lleva un tiempo resolver el orden. Entonces, para ayudar a mi futuro:git revert OLDER_COMMIT^..NEWER_COMMIT
Henrik N
2
¿Qué significa ^?
Dustin Getz
1
@DustinGetz primer padre: consulte git-scm.com/docs/gitrevisions : "Un sufijo ^para un parámetro de revisión significa el primer padre de ese objeto de compromiso".
VonC
15

Si desea revertir el rango de confirmación B a D (al menos en la versión 2 de git) en una sola confirmación, puede hacerlo

 git revert -n B^..D

Esto revierte los cambios realizados por los commits del commit padre de B (excluido) al commit D (incluido), pero no crea ningún commit con los cambios revertidos. La reversión solo modifica el árbol de trabajo y el índice.

No olvides confirmar los cambios después

 git commit -m "revert commit range B to D"

También puede revertir múltiples confirmaciones no relacionadas en una única confirmación, utilizando el mismo método. por ejemplo para revertir B y D pero no C

 git revert -n B D
 git commit -m "Revert commits B and D"

Referencia: https://www.kernel.org/pub/software/scm/git/docs/git-revert.html

Gracias Honza Haering por la corrección.

Ramast
fuente
3
git revert -n B..Dno revierte el commit B, solo C y D. git revert -n B^..Drevierte B también.
Honza Haering
de acuerdo con la documentación de git lo hace. referencia en el post
Ramast
1
Si te refieres a este ejemplo (que creo que es un poco confuso) en la referencia: git revert -n master~5..master~2dice el quinto último compromiso incluido. Pero en master~5realidad es el sexto último commit. Vea la selección de revisión en git docs para obtener información detallada sobre la ..notación :-)
Honza Haering
6

Hacer git revert OLDER_COMMIT^..NEWER_COMMITno funcionó para mí.

Solía git revert -n OLDER_COMMIT^..NEWER_COMMITy todo está bien. Estoy usando la versión git 1.7.9.6.

Orlando
fuente
He tenido el mismo problema y lo solucioné usando -n, pero debes dejar ^ con OLDER_COMMIT (git revert -n OLDER_COMMIT ^ .. NEWER_COMMIT).
FeelGood
@FeelGood ¿por qué deberías dejar el ^?
Orlando
Tenía antecedentes A -> B -> C y el objetivo era revertir B y C. Cuando ejecuté 'git revert -n B..C', solo C fue revertido. Cuando usé 'git revert -n B ^ .. C', git revirtió ambas confirmaciones. Tal vez hice algo mal.
FeelGood
genial, bueno, tengo que probarlo, pero creo que en mi caso funcionó bien (a menos que revirtiera un rango de confirmación de 1 jajaja) modificaré la respuesta para incluir el ^. gracias
Orlando
2
La opción -no --no-commitrevertirá todos los cambios en todo el rango en una sola confirmación, en lugar de crear una confirmación de reversión para cada confirmación en el rango. El resultado final es el mismo, ya que en, los mismos cambios se revertirán. Solo depende de cómo quieres que se vea tu historial de git.
Dennis
0

Use git rebase -ipara aplastar los commits relevantes en uno. Entonces solo tiene un compromiso para revertir.

Graham Borland
fuente
77
Si usa git rebase, simplemente puede eliminar los commits. Creo que hay una razón para no volver a redactar, como querer mantener SHA1 de commit F igual.
Paŭlo Ebermann
55
Alternativamente, aplasta los commits revertidos en uno.
aeosynth