Pregunta

Hice un cambio en un guión y lo comprometí.Luego hice algunos otros cambios y los envié a un repositorio remoto y demás.

Luego me di cuenta de que el primer cambio que mencioné era estúpido y quería deshacerlo.¿Puedo "anular la aplicación" de esa confirmación sin copiar/pegar manualmente la diferencia?

Como ejemplo:tengo dos archivos, a.py y b.py:

Commit 1:
I delete a function in a.py

Commit 2:
I change a few lines in b.py

Commit 3:
I change the docstring in a.py

¿Puedo deshacer la eliminación de esa función y hacer que aparezca como "compromiso 4" (en lugar de eliminar el compromiso 1)?

¿Fue útil?

Solución

Sí, puede usar git revert para esto. Consulte la sección del manual de git en este para obtener más información.

La esencia es que puedes decir:

git revert 4f4k2a

Donde 4f4k2a es la identificación de la confirmación que desea deshacer, e intentará deshacerla.

Otros consejos

Solo un comentario:

git revert aCommit

revierte el all commit (como en " todos los archivos parte del commit "):
calcula un parche inverso, lo aplica en HEAD y commit.

Entonces dos problemas aquí (el primero se resuelve fácilmente):

  • siempre se compromete, por lo que es posible que desee agregar la opción -no-commit : " git revert --no-commit aCommit " ;: esto es útil al revertir más de una confirmación ' efecto a su índice en una fila.
  • no se aplica a un archivo específico (¿qué sucede si a.py era parte de una confirmación con otros 1000 cambios que quizás no desee revertir)?
    Para eso, si desea extraer archivos específicos como estaban en otra confirmación, debería ver git-checkout , específicamente la sintaxis git checkout <commit> <filename> (eso no es exactamente lo que necesita en este caso)

Easy Git (Elijah Newren) trató de traer un " más; completa revertir " a la Lista de correo de Git ; pero sin mucho éxito:

  

La gente ocasionalmente quiere " revertir los cambios " ;.

     

Ahora, esto puede ser:

     
      
  • los cambios entre hace 32 y 29 revisiones,
  •   
  • podrían ser todos los cambios desde la última confirmación,
  •   
  • podrían ser los cambios desde hace 3 commits, o
  •   
  • podría ser solo una confirmación específica.
  •   
  • El usuario puede querer subconjuntar tales reversiones a archivos específicos ,
  •   

(eg revert está documentado aquí , pero estoy no estoy seguro de que sea parte de la distribución actual de, por ejemplo, aunque)

  

pero todo se reduce a " revertir los cambios " en el final.

eg revert --since HEAD~3  # Undo all changes since HEAD~3
eg revert --in HEAD~8     # much like git revert HEAD~8, but nocommit by default
eg revert --since HEAD foo.py  # Undo changes to foo.py since last commit
eg revert foo.py               # Same as above
eg revert --in trial~7 bar.c baz.  # Undo changes made in trial~7 to bar.[ch]
  

¿Son estos tipos de & "; revertir datos &"; realmente tan diferente que debería haber diferentes comandos, o que algunas de estas operaciones no deberían ser compatibles con el simple comando revertir?
  Claro, la mayoría de los usuarios probablemente usarán & Quot; eg revert FILE1 FILE2... & Quot;   formulario, pero no vi el daño en soportar las capacidades adicionales.

     

Además ... ¿hay algo fundamental que impida que git core adopte tal comportamiento?

     

Elijah

     

Nota: las confirmaciones por defecto no tienen sentido para el comando revert generalizado, y " git revert REVISION " error con las instrucciones (indicando al usuario que agregue la marca --in).


Digamos que tiene, de 50 archivos comprometidos, 20 se da cuenta de que el antiguo commit X introdujo cambios que no deberían haber tenido lugar.
Un poco de fontanería está en orden.
Lo que necesita es una forma de enumerar todos los archivos específicos que necesita para revertir
(como en " para cancelar los cambios realizados en commit X mientras se mantienen todos los cambios posteriores " ),
y luego, para cada uno de ellos:

git-merge-file -p a.py X X^

El problema aquí es recuperar la función perdida sin borrar todos los cambios posteriores en a.py que desee conservar.
Esa técnica a veces se llama & Quot; fusión negativa & Quot ;.

Desde git merge-file <current-file> <base-file> <other-file> significa :
incorpora todos los cambios que conducen de <base-file> a <other-file> en <current-file>, puede restaurar la función eliminada diciendo que desea incorporar todos los cambios).

  • de: X (donde se ha eliminado la función)
  • a: X ^ (la confirmación anterior antes de X, donde la función todavía estaba allí)

Nota: el argumento '-p' que le permite revisar primero los cambios sin hacer nada en el cursoarchivo de alquiler Cuando esté seguro, elimine esa opción.

Nota : la git merge-file es no es tan simple : no puede hacer referencia a versiones anteriores del archivo así como así.
(habría repetido el mensaje frustrante: error: Could not stat X )
Tienes que:

git cat-file blob a.py > tmp/ori # current file before any modification
git cat-file blob HEAD~2:a.py > tmp/X # file with the function deleted
git cat-file blob HEAD~3:a.py > tmp/F # file with the function which was still there

git merge-file a.py tmp/X tmp/F # basically a RCS-style merge
                                 # note the inversed commit order: X as based, then F
                                 # that is why is is a "negative merge"
diff -u a.py tmp/ori # eyeball the merge result
git add a.py 
git commit -m "function restored" # and any other changes made from X are preserved!

Si esto se va a hacer para una gran cantidad de archivos dentro de un commit anterior ... algunos scripts están en orden;)

Para revertir los cambios a un solo archivo dentro de una confirmación, como VonC señaló, yo checkout la rama (maestra o troncal o lo que sea) y luego diff la versión del archivo que quería revertir y tratarla como una nueva confirmación:

$ git checkout trunk
$ git checkout 4f4k2a^ a.py
$ git add a.py
$ git diff              #verify I'm only changing what I want; edit as needed
$ git commit -m 'recover function deleted from a.py in 4f4k2a'

Probablemente haya un comando de plomería que lo haría directamente, pero no lo usaría si lo supiera. No es que no confíe en Git, pero no confío en mí mismo; no confiaría en que lo supiera sin mirar lo que cambió en ese archivo en ese commit y desde entonces. Y una vez que miro, es más fácil crear una nueva confirmación editando el <=>. Quizás sea solo un estilo de trabajo personal.

Echa un vistazo a este git revert pregunta . Parece que hay un problema al revertir las confirmaciones anteriores si no en una secuencia consecutiva, incluida la confirmación más reciente.

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