Pregunta

Tengo un repositorio git que tiene este aspecto:

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

Quiero la cabeza de la rama para que apunte a A, es decir, quiero B, C, D, y la cabeza a desaparecer y quiero cabeza a ser sinónimo de A.

Parece que puedo o bien tratar de rebase (no es pertinente, ya que me he empujado cambios en el medio), o volver. Pero, ¿cómo puedo volver múltiples confirmaciones? No puedo volver uno a la vez? Es importante el orden?

¿Fue útil?

Solución

La ampliación de lo que escribí en un comentario

La regla general es que no se debe volver a escribir (cambiar) la historia que ha publicado, porque alguien podría haber basado su trabajo en él. Si se vuelve a escribir la historia (cambio), que haría problemas con la fusión de sus cambios y con la actualización para ellos.

Así que la solución es crear un nueva cometer que revierte los cambios que desea eliminar. Esto se puede hacer usando

Usted tiene la siguiente situación:

A <-- B  <-- C <-- D                                               <-- master <-- HEAD

(flechas se refiere aquí a la dirección del puntero: la referencia "padre" en el caso de confirmaciones, la parte superior cometen en el caso de la cabeza de la rama (rama ref), y el nombre de la sucursal en el caso de referencia CABEZA ).

Lo que hay que crear es la siguiente:

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

donde "[(BCD) ^ - 1]" significa el commit que revierte los cambios en comete B, C, D. Matemáticas nos dice que (BCD) ^ - 1 = D ^ -1 C ^ -1 B ^ - 1, para que pueda obtener la situación requerida mediante los siguientes comandos:

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

Solución alternativa sería la de pago y envío contenido de cometer a, y comprometerse este estado:

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

A continuación, usted tendría la siguiente situación:

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

El cometer A' tiene el mismo contenido que cometer A, pero es una confirmación diferente (mensaje de confirmación, los padres, fecha cometer).

La solución href="https://stackoverflow.com/questions/1463340/revert-multiple-git-commits/1463390#comment1312779_1463390"> se basa en el misma idea, pero utiliza git reset :

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

Otros consejos

Para hacerlo sólo hay que utilizar el revert comando, especificando el rango de confirmaciones que desea obtener revertido.

Teniendo en cuenta su ejemplo, usted tendría que hacer esto (asumiendo que usted está en la rama 'master'):

git revert master~3..master

Esto creará un nuevo commit en su local con el inverso de cometer B, C y D (lo que significa que va a deshacer los cambios introducidos por estas confirmaciones):

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

Limpio manera que me pareció útil

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

Este comando revierte los 3 últimos compromete con una sola comprometerse.

Además no reescribir la historia.

Al igual que en la respuesta de Jakub, esto le permite seleccionar fácilmente compromete consecutivos de 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

que actuará como una reversión de todos ellos a la vez. Dar un mensaje bueno comprometerse.

En primer lugar asegúrese de que su copia de trabajo no se modifica. A continuación:

git diff HEAD commit_sha_you_want_to_revert_to | git apply

y luego simplemente comprometerse. No se olvide de documentar lo que es la razón de reversión.

Estoy tan frustrado que esta cuestión no sólo puede ser contestada. Cada otra pregunta es en relación a la forma de revertir correctamente y conservar la historia. Esta pregunta dice "Quiero la cabeza de la rama para que apunte a A, es decir que quiero B, C, D, y la cabeza a desaparecer y quiero que la cabeza sea sinónimo de A."

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

He aprendido mucho leer el post de Jakub, pero un tipo en la empresa (con acceso a empujar a nuestra "prueba" rama sin Pull-Request) empujado como 5 mala compromete tratar de arreglar y reparar y arreglar un error que cometió 5 hace compromete. sólo eso, sino uno o dos Solicitudes Tire no fueron aceptadas, que ahora estaban mal. Así que olvidarlo, encontré la última buena cometen (abc1234) y apenas corría el guión básico:

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

Le dije a los otros 5 chicos que trabajan en este repo que hacen mejor nota de sus cambios de las últimas horas y limpie / Re-Rama de la última prueba. Final de la historia.

Esta es una ampliación de una de las soluciones previstas en la respuesta de Jakub

Me encontré con una situación en la que las confirmaciones que necesitan para hacer retroceder eran algo complejo, con varios de los seres confirmaciones de combinación se compromete, y que tenía que evitar volver a escribir la historia. Yo no era capaz de utilizar una serie de comandos git revert porque me encontré con el tiempo los conflictos entre los cambios que se añade la reversión. Terminé usando los siguientes pasos.

En primer lugar, echa un vistazo a los contenidos de la meta comprometerse, dejando CABEZA en la punta de la rama:

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

(El - se asegura <target-commit> se interpreta como una confirmación en lugar de un archivo, el se refiere al directorio actual.).

A continuación, determinar qué archivos se agregaron en las confirmaciones de ser cancelada, y por lo tanto necesitan ser eliminado:

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

Los archivos que se han añadido debe aparecer con una "A" al principio de la línea, y no debe haber ninguna otra diferencia. Ahora bien, si los archivos deben ser eliminados, organizar estos archivos para la desinstalación:

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

Por último, confirmar la reversión:

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

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

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

No debe haber diferencias.

La forma más fácil de revertir un grupo de confirmaciones sobre repositorio compartido (que usa la gente y desea conservar la historia) es utilizar git revert conjuntamente con rev-list git. Este último le proporcionará una lista de confirmaciones, el primero será hacer la operación de revertir en sí.

Hay dos maneras de hacerlo. Si desea que el múltiple de reversión se compromete en un solo uso comprometerse:

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

este revertirá un grupo de confirmaciones que necesita, pero deje todos los cambios en su árbol de trabajo, se debe comprometer a todos ellos como de costumbre.

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

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

Por ejemplo, si usted tiene un árbol comprometerse como

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

para revertir los cambios de eee a bbb , ejecute

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

Ninguna de las trabajadas para mí, así que tuve tres confirmaciones para revertir (los últimos tres commits), 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:)

En mi opinión una manera muy fácil y limpia podría ser:

volver a A

git checkout -f A

cabeza punto de maestro para el estado actual

git symbolic-ref HEAD refs/heads/master

Guardar

git commit

Si desea revertir temporalmente las confirmaciones de una característica, a continuación, puede utilizar la serie de comandos siguientes.

Aquí es cómo funciona

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top