Repetir múltiples confirmaciones de git

Tengo un repositorio git que se parece a esto:

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

Quiero que la rama local 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 reinstalarlo (no se aplica, ya que hice clic en los cambios entre ellos), o regresar. Pero, ¿cómo puedo devolver múltiples confirmaciones? ¿Regreso uno a la vez? ¿Es importante el orden?

499
23 сент. fijado por Bill el 23 de septiembre 2009-09-23 03:27 '09 a las 3:27 am 2009-09-23 03:27
@ 11 respuestas

Expansión de lo que escribí en los comentarios.

La regla general es que no debe volver a escribir (cambiar) la historia que publicó, porque alguien podría basar su trabajo en ella. Si reescribe (cambia) una historia, tendrá problemas para fusionar sus cambios y actualizarlos.

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

Tienes la siguiente situación:

 A <- B <- C <- D <- maestro <- HEAD

(Las flechas aquí se refieren a la dirección del puntero: el enlace "principal" en el caso de confirmaciones, la fijación superior en el caso de una rama (respuesta de la rama) y el nombre de la rama en el caso de un enlace HEAD).

Lo que necesitas crear es lo siguiente:

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

donde "[(BCD) ^ - 1]" significa una confirmación, que devuelve los cambios a las confirmaciones de B, C, D. Las matemáticas nos dicen que (BCD) ^ - 1 = D ^ -1 C ^ -1 B ^ - 1, por lo tanto, 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" 

Una solución alternativa sería verificar el contenido de la confirmación A y confirmar este estado:

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

Entonces tendrás la siguiente situación:

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

La terminación A 'tiene el mismo contenido que la confirmación A, pero es una confirmación diferente (mensaje de confirmación, padres, fecha de confirmación).

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

 $ git reset --hard A $ git reset --soft @{1} # (or ORIG_HEAD), which is D $ git commit 
778
24 сент. Respuesta dada por Jakub Narębski 24 sep. 2009-09-24 11:44 '09 a las 11:44 2009-09-24 11:44

Para hacer esto, solo necesita usar el comando revert, especificando el rango de confirmaciones que desea devolver.

Teniendo en cuenta su ejemplo, tendrá que hacer esto (si está en la rama "maestra"):

 git revert master~3..master 
border=0

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

 A <- B <- C <- D <- BCD' <- HEAD 
126
31 июля '12 в 18:00 2012-07-31 18:00 La respuesta es dada por Victor el 31 de julio de 2012 a las 6 pm 2012-07-31 18:00
 git reset --hard a git reset --mixed d git commit 

Esto actuará como un reembolso para todos a la vez. Dar un buen mensaje de fijación.

36
23 сент. Respuesta dada por Jeff Ferland el 23 de septiembre. 2009-09-23 03:45 '09 a las 3:45 am 2009-09-23 03:45

Al igual que la respuesta de Jakub, le permite seleccionar fácilmente compromisos consecutivos para devolver.

 # revert all commits from B to HEAD, inclusively $ git revert --no-commit B..HEAD $ git commit -m 'message' 
34
31 июля '14 в 21:49 2014-07-31 21:49 konyak dio la respuesta el 31 de julio de 2014 a las 21:49 2014-07-31 21:49

Primero asegúrese de que su copia de trabajo no ha cambiado. Entonces

 git diff HEAD commit_sha_you_want_to_revert_to | git apply 

y luego sólo arreglarlo. No olvide documentar el motivo de la devolución.

19
09 сент. la respuesta es dada mateusz.fiolka 09 sep . 2014-09-09 16:13 '14 a las 16:13 2014-09-09 16:13

Pura manera que encontré útil

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

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

Tampoco reescribe la historia.

12
29 марта '17 в 3:00 2017-03-29 03:00 la respuesta se ofrece deepdive el 29 de marzo de 2017 a las 3:00 2017-03-29 03:00

Estoy tan molesta que esta pregunta no puede ser contestada simplemente. Todas las demás preguntas se refieren a cómo devolver y guardar correctamente el historial. Esta pregunta dice: "Quiero que el jefe de la rama apunte a A, es decir, quiero que B, C, D y HEAD desaparezcan , y quiero que el jefe sea sinónimo de A".

 git checkout <branch_name> git reset --hard <commit Hash for A> git push -f 

Aprendí mucho leyendo la publicación de Yakub, pero un tipo de la empresa (con acceso a nuestra sucursal de prueba sin Pull-Request) hizo clic como 5 errores incorrectos tratando de corregir y corregir el error y corregir el error que cometió 5 toma su principio . No solo eso, sino una o dos solicitudes que ahora eran malas. Así que olvídalo, encontré la última solución correcta (abc1234) y simplemente ejecuté el script base:

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

Les dije a los otros 5 muchachos que trabajan en este repositorio que notarán sus cambios mejor en las últimas horas y limpiarán / re-ramificarán desde la última prueba. El final de la historia.

11
12 июля '16 в 2:29 2016-07-12 02:29 La respuesta se le da a Suamere el 12 de julio de '16 a las 2:29. 2016-07-12 02:29

La forma más fácil de devolver un grupo de confirmaciones a un repositorio común (que las personas usan y desea mantener el historial) es usar git revert junto con git rev-list . Este último le proporcionará una lista de confirmaciones, el primero volverá.

Hay dos maneras de hacer esto. Si desea repetir múltiples confirmaciones en una confirmación para usar:

 for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert -n $i; done 

Esto conducirá a la devolución del grupo de confirmaciones requeridas, pero si deja todos los cambios en el árbol de trabajo, debería corregirlos como de costumbre.

Otra opción es tener un compromiso por cada cambio deshecho:

 for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert --no-edit -s $i; done 

Por ejemplo, si tienes un árbol de fijación de tipo

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

para devolver los cambios de eee a bbb, ejecute

 for i in `git rev-list eee^..bbb`; do git revert --no-edit -s $i; done 
4
04 авг. Se da la respuesta a Ruslan Kabalin 04 ago. 2011-08-04 14:29 '11 a las 2:29 pm 2011-08-04 14:29

Esta es una extensión de una de las soluciones provistas en respuesta a Yakub.

Me enfrenté a una situación en la que los compromisos que necesitaba para ser rechazados eran algo complicados, y algunos de los compromisos eran una combinación, y no tenía que volver a escribir la historia. No pude usar una serie de comandos git revert , porque al final me encontré con conflictos entre los cambios de reversión agregados. Terminé de usar los siguientes pasos.

Primero verifique el contenido de la confirmación de destino, dejando HEAD en la punta de la rama:

 $ git checkout -f <target-commit> -- . 

(La confianza se interpreta como un compromiso, no un archivo, pero se refiere al directorio actual).

Luego, determine qué archivos se agregaron a las confirmaciones completadas y, por lo tanto, deben eliminarse:

 $ git diff --name-status --cached <target-commit> 

Los archivos que se han agregado deben aparecer con una "A" al principio de la línea, y no debe haber otras diferencias. Ahora, si es necesario eliminar algún archivo, ejecute estos archivos para eliminarlos:

 $ git rm <filespec>[ <filespec> ...] 

Finalmente, completa la reversión:

 $ git commit -m 'revert to <target-commit>' 

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

 $git diff <target-commit> <current-commit> 

No debe haber diferencias.

3
08 нояб. La respuesta la da Warren Dew 08 nov. 2016-11-08 09:39 '16 a las 9:39 2016-11-08 09:39

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

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

Trabajó como un encanto :)

0
24 янв. La respuesta la da Dorian el 24 de enero. 2017-01-24 03:28 '17 a las 3:28 2017-01-24 03:28

Si desea descomprimir temporalmente una función, puede usar varios de los siguientes comandos.

Así es como funciona.

git log - pretty = oneline | grep 'feature_name' | corte -d '' -f1 | xargs -n1 git revert --no-editar

-1
11 февр. La respuesta es dada por Ajit Singh el 11 de febrero. 2016-02-11 21:47 '16 a las 9:47 pm 2016-02-11 21:47

Otras preguntas sobre tags o Haz una pregunta