Tengo un repositorio git que se ve así:
A -> B -> C -> D -> HEAD
Quiero que la cabeza de la rama apunte a A, es decir, quiero que B, C, D y HEAD desaparezcan y quiero que cabeza sea sinónimo de A.
Parece que puedo intentar cambiar la base (no se aplica, ya que he introducido cambios en el medio) o revertir. Pero, ¿cómo revierto las confirmaciones múltiples? ¿Revierto uno a la vez? ¿Es importante el orden?
git
commit
git-revert
Cuenta
fuente
fuente
git push -f HEAD~4:master
(suponiendo que la rama remota es master). Sí, puedes empujar cualquier commit así.git revert
.Respuestas:
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 (cambia) el historial, tendrás problemas para fusionar sus cambios y actualizarlos.
Entonces, la solución es crear una nueva confirmación que revierta los cambios de los que desea deshacerse. Puede hacer esto usando el comando git revert .
Tienes la siguiente situación:
(las flechas aquí se refieren a la dirección del puntero: la referencia "principal" en el caso de commits, el commit superior en el caso de branch head (branch ref) y el nombre de branch en el caso de HEAD reference).
Lo que necesita crear es lo siguiente:
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 utilizando los siguientes comandos:
La solución alternativa sería retirar el contenido de la confirmación A y confirmar este estado:
Entonces tendría la siguiente situación:
La confirmació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 :
fuente
git checkout -f A -- .
no los eliminará, deberá hacerlo manualmente. Apliqué esta estrategia ahora, gracias Jakubgit checkout foo
puede significar la rama de pagofoo
(cambiar a rama) o el archivo de pago foo (del índice).--
se utiliza para desambiguar, por ejemplo,git checkout -- foo
siempre se trata del archivogit revert --no-commit D C B
git revert
no aceptaba múltiples confirmaciones; Es una adición bastante nueva.Manera limpia que encontré útil
Este comando revierte los últimos 3 commits con solo un commit.
Tampoco reescribe la historia.
fuente
git commit
a partir de ahí en realidad hará el commit.HEAD~3..
es lo mismo queHEAD~3..HEAD
Para hacerlo, solo tiene que usar el comando revertir , especificando el rango de confirmaciones que desea revertir.
Teniendo en cuenta su ejemplo, tendría que hacer esto (suponiendo que esté en la rama 'maestro'):
Esto creará una nueva confirmación en su local con la confirmación inversa de B, C y D (lo que significa que deshacerá los cambios introducidos por estas confirmaciones):
fuente
git revert --no-commit HEAD~2..
es una forma un poco más idiomática de hacerlo. Si está en la rama maestra, no es necesario especificarla nuevamente. La--no-commit
opción le permite a git intentar revertir todas las confirmaciones a la vez, en lugar de llenar el historial con variosrevert commit ...
mensajes (suponiendo que eso sea lo que desea).master~3
.--no-commit
(para obtener una confirmación por separado para cada reversión), y luego juntarlos todos en una nueva versión interactiva. El mensaje de confirmación combinado contendrá todos los SHA, y usted puede organizarlos como quiera usando su editor de mensajes de confirmación favorito.Similar a la respuesta de Jakub, esto le permite seleccionar fácilmente confirmaciones consecutivas para revertir.
fuente
B^..HEAD
, de lo contrario B está excluido.git revert --no-commit B^..HEAD
ogit revert --no-commit A..HEAD
Eso actuará como una reversión para todos ellos a la vez. Dar un buen mensaje de compromiso.
fuente
HEAD
lucir asíA
, probablemente quiera que el índice coincida, porgit reset --soft D
lo que probablemente sea más apropiado.git checkout A
entoncesgit commit
arriba no funcionó para mí, pero esta respuesta sí.git reset --mixed D
requiere? Específicamente por quéreset
? ¿Es porque, sin reiniciar a D, que HEAD apuntaría a A, haciendo que B, C y D se "cuelguen" y recojan basura, que no es lo que él quiere? Pero entonces ¿por qué--mixed
? Usted ya respondió "--soft
restablecer no mueve el índice ..." Entonces, al mover el índice, esto significa que el índice contendrá los cambios de D, mientras que el directorio de trabajo contendrá los cambios de A, de esta manera agit status
ogit diff
(que compara el índice [D] con El Directorio de trabajo [A]) mostrará la sustancia; ese usuario va de D a A?Primero asegúrese de que su copia de trabajo no esté modificada. Entonces:
y luego solo comprometerse. No olvide documentar cuál es el motivo de la reversión.
fuente
error: cannot apply binary patch to 'some/image.png' without full index line error: some/image.png: patch does not apply
git diff --binary HEAD commit_sha_you_want_to_revert_to | git apply
git revert A..Z
obtendríaserror: commit X is a merge but no -m option was given.
Estoy tan frustrado que esta pregunta no puede ser respondida. Cualquier otra pregunta está relacionada con cómo revertir correctamente y preservar la historia. Esta pregunta dice "Quiero que la cabeza de la rama apunte a A, es decir, quiero que B, C, D y HEAD desaparezcan y quiero que cabeza sea sinónimo de A."
Aprendí mucho leyendo la publicación de Jakub, pero un tipo de la compañía (con acceso para enviar a nuestra rama de "prueba" sin Pull-Request) presionó como 5 errores cometidos tratando de arreglar y corregir y corregir un error que cometió hace 5 compromisos. 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 buen commit (abc1234) y simplemente ejecuté el script básico:
Les dije a los otros 5 muchachos que trabajan en este repositorio que mejor tomen nota de sus cambios en las últimas horas y que borren / vuelvan a ramificar de las últimas pruebas. El final de la historia.
fuente
git push --force-with-lease
, que reescribirá el historial solo si nadie más se ha comprometido con la sucursal después o dentro del rango de los compromisos de vaporización. Si otras personas han usado la rama, entonces su historia nunca debe reescribirse, y la confirmación simplemente debe revertirse visiblemente.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 los commits que necesitaba revertir eran algo complejos, con varios de los commits siendo commits de fusión, y necesitaba evitar reescribir el historial. No pude usar una serie de
git revert
comandos porque finalmente encontré conflictos entre los cambios de reversión que se agregaban. Terminé usando los siguientes pasos.Primero, verifique el contenido de la confirmación de destino mientras deja HEAD en la punta de la rama:
(El - se asegura de que
<target-commit>
se interprete como una confirmación en lugar de un archivo; el. Se refiere al directorio actual).Luego, determine qué archivos se agregaron en las confirmaciones que se están deshaciendo y, por lo tanto, deben eliminarse:
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 algún archivo, organice estos archivos para su eliminación:
Finalmente, comete la reversión:
Si lo desea, asegúrese de volver al estado deseado:
No debería haber diferencias.
fuente
git
CABEZA solo con la punta de la rama?La manera fácil de revertir un grupo de confirmaciones en el repositorio compartido (que la gente usa y desea preservar el historial) es usarlo
git revert
junto con gitrev-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:
esto revertirá un grupo de confirmaciones que necesita, pero deje todos los cambios en su árbol de trabajo, debe confirmarlos como de costumbre.
Otra opción es tener una única confirmación por cambio revertido:
Por ejemplo, si tiene un árbol de confirmación como
para revertir los cambios de eee a bbb , ejecute
fuente
Ninguno de esos funcionó para mí, así que tenía tres commits para revertir (los últimos tres commits), así que hice:
Trabajado como un encanto :)
fuente
En mi opinión, una forma muy fácil y limpia podría ser:
volver a A
señalar la cabeza del maestro al estado actual
salvar
fuente
git checkout master; git reset --hard A
? O si no, ¿podría explicar un poco más sobre lo que hace?Si desea revertir temporalmente las confirmaciones de una función, puede usar la serie de comandos siguientes.
Así es como funciona
git log --pretty = en línea | grep 'nombre_característica' | cortar -d '' -f1 | xargs -n1 git revert --no-edit
fuente