Revertir cambios a un archivo específico desde una confirmación específica

3 minutos de lectura

Avatar de usuario de Ryan
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?

  • 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

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 la git 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 applypero no sabía que podías usar git apply --reverse, eso es definitivamente genial! Por que git 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.

¿Ha sido útil esta solución?