Ryan
Hace unas semanas (es decir, hace muchas confirmaciones), hice una confirmación de git que tocó muchos archivos. La mayor parte del compromiso fue genial.
Sin embargo, ahora me gustaría deshacer los cambios que hice en solo uno de esos archivos, pero no quiero anular ningún cambio que se haya hecho en ese archivo. después que cometer.
¿Hay alguna forma de revertir una confirmación específica, pero solo en uno de los archivos de esa confirmación?
Obtenga una diferencia lista para el parche para ese archivo en esa confirmación y luego aplique el parche a la inversa:
git show <commit-id> -- <path> | git apply -R -
Asegúrese de que le gusta el resultado y, de ser así, agregue y confirme con el mensaje apropiado.
-
gracias pero esto falló con:
error: <myFileName>: patch does not apply
– Ryan
29 mayo 2014 a las 23:30
-
Eso implica que algo en los cambios ha cambiado desde entonces, es decir, hay un conflicto. Puede: intentar agregar
-3
(también conocido como--3way
) para usar los mecanismos de fusión de git; o agregar--reject
(en ambos casos, a lagit apply
opciones) pero luego debe resolver manualmente los conflictos.– torek
29 mayo 2014 a las 23:35
-
Solo me gustaría señalar que la forma ingenua de obtener un parche inverso sería simplemente hacer
git diff <commit> <commit>^ -- <path> | git apply
pero no sabía que podías usargit apply --reverse
, eso es definitivamente genial! Por quegit apply -R -
¿Tienes ese guión final al final?– usuario456814
30 de mayo de 2014 a las 4:30
-
@Cupcake:
git apply
quiere tomar un nombre de archivo; la documentación dice- can be used to read from the standard input
. No estaba seguro de antemano si leería stdin de todos modos (siempre lo he alimentado con archivos, al menos hasta donde puedo recordar).– torek
30 de mayo de 2014 a las 4:35
-
¡Gracias! solía
git show <commit-id> -- <path> | git apply -3 -R -
– Ryan
30 de mayo de 2014 a las 14:16
La respuesta de Torek es definitivamente mejor (¡y simple!), pero en aras de la exhaustividad, quería agregar algunas soluciones alternativas (algunas ingenuas) a este problema.
Solución 1: Parche inverso (ingenuo, en comparación con la solución de Torek)
Esto es muy similar a la solución de Torek. Para deshacer los cambios en un archivo específico que se realizaron mediante una confirmación específica, solo obtenga una diferencia inversa de esa confirmación invirtiendo los argumentos para git diff
:
git diff <commit> <commit>^ -- <filepath> | git apply
Normalmente, para conseguir los cambios introducidos por <commit>
usas el orden
git diff <commit>^ <commit>
pero al invertir el orden, terminas obteniendo el inverso de esos cambios, ¡que es una diferencia válida que se puede usar como parche!
Solución 2: revertir todos los archivos, luego solo confirmar cambios en archivos específicos (muy ingenuo)
Una solución más ingenua sería revertir la confirmación que agregó los cambios que desea deshacer, pero no confirme la reversión. Luego simplemente elimine todos los cambios en los otros archivos del índice y la copia de trabajo:
git revert --no-commit <commit>
# Unstage all changes that revert all files
git reset -- .
# Stage and commit just the reversion changes that you want
git add <yourFile>
git commit -m "Revert changes to <yourFile> from <commit>"
# Undo all reversions changes to the other files
git checkout -- .
Esto es necesario porque git revert
no revierte los cambios en archivos individuales, actualmente solo revierte las confirmaciones completas.
Relacionado, pero no duplicado (creo): revertir un solo archivo a una versión anterior en git.
– usuario456814
30 de mayo de 2014 a las 4:50
Consulte también ¿Cómo restablezco/revierto un archivo específico a una revisión específica usando Git?.
– usuario456814
30 de mayo de 2014 a las 4:53