El historial de confirmaciones de Git está diseñado para ser inmutable (en su mayor parte) y rastrear cada cambio en su proyecto para que nunca pierda trabajo. Sin embargo, a veces es necesario reescribir el historial de Git, por lo que Git proporciona algunas herramientas para editar confirmaciones existentes.
Agregar nuevos cambios a las confirmaciones
El caso de uso más común para esto es cuando crea un mensaje de confirmación y luego, antes de presionar el control remoto, se da cuenta de que cometió un error y necesita hacer un pequeño cambio. Por supuesto, podría hacer una segunda confirmación, pero eso es innecesario y también muestra a todos sus compañeros de trabajo su estúpido error cuando finalmente presiona el control remoto.
Si simplemente está agregando cambios, puede usar git commit --amend
. Esto modifica la confirmación más reciente y se fusiona con los cambios adicionales que ha realizado.
Primero, deberá organizar sus cambios:
git add .
Y luego enmendar:
git commit --amend --no-edit
los --no-edit
flag hará que el comando no modifique el mensaje de confirmación. Si necesita aclarar los nuevos cambios en un nuevo mensaje, deje esta marca fuera y se le pedirá el nuevo mensaje de confirmación.
Bajo el capó, el comando de modificación realiza una nueva confirmación con los cambios adicionales y luego reemplaza por completo la confirmación de origen en el historial de Git. La confirmación anterior todavía es accesible desde git reflog
(más sobre eso a continuación), pero en el futuro, la nueva confirmación es la única que existe. Cuando empuja a un repositorio remoto, no hay forma de saber que la confirmación se modificó, es un cambio puramente local.
Debido a esto, no querrá modificar las confirmaciones que ya se han enviado, ya que se encontrará con muchos problemas y tendrá que presionar a la fuerza hacia el control remoto, lo que no es bueno para nadie.
Cambiar solo el mensaje de confirmación de Git
Si no necesita realizar ningún cambio y solo desea corregir un error tipográfico, puede ejecutar amend
sin ningún cambio también:
git commit --amend -m "an updated commit message"
Cambios inestables a partir de confirmaciones
El comando de modificación de Git solo funciona si está estrictamente agregando cambios. Cuando decimos «agregado», no solo nos referimos a nuevas líneas de código; cambiar una línea de código también agrega cambios. Eliminar una línea de código, o un archivo completo, también es un cambio que se agrega, aunque está eliminando datos del proyecto cuando se aplica ese cambio.
Sin embargo, también hay casos en los que es posible que desee eliminar los cambios de las confirmaciones. Por ejemplo, digamos que corrió:
git add . git commit
Y agregó todos los cambios en su repositorio a los cambios por etapas, y los comprometió, antes de darse cuenta, “¡Oh, mierda! ¡No quise enviar ese archivo! » En este caso, necesitaría enviar todos los cambios de nuevo a la etapa de preparación y, a continuación, eliminar manualmente la etapa de los archivos que no desea enviar.
La solución es realizar un reinicio, eliminar la confirmación y devolver los cambios. Hay algunos tipos de reinicios, pero todos implican tomar confirmaciones del historial de Git y enviarlas de vuelta a la etapa de pruebas, al directorio local o directamente a la papelera.
En este caso, lo que desea es un restablecimiento parcial, que enviará todos los cambios a la etapa inicial. Puede usar la siguiente abreviatura para restablecer la confirmación detrás de HEAD; de lo contrario, deberá obtener la referencia de git reflog
:
git reset --soft HEAD~
Luego, deberá eliminar el archivo que no desea comprometer. La forma de hacer esto es en realidad también un reinicio, en este caso, un reinicio mixto en un archivo específico:
git reset --mixed filename
Esto funciona porque restablecer este archivo eliminará los cambios de la etapa de preparación y no se confirmará cuando vuelva a realizar la confirmación.
También puede hacer un reinicio mixto en todo el repositorio, y git add
todos los archivos excepto el que no desea. Esto es más fácil de hacer si está utilizando un cliente GUI Git.
¿Necesita deshacer / eliminar una confirmación? Usar reversión
Revertir una confirmación es la forma más sencilla de eliminar cambios. Básicamente, toma todos los cambios de la confirmación de destino y aplica lo contrario. Si creó un archivo, se elimina. Si eliminó una línea de código, ese código se vuelve a agregar. Es la forma aprobada por Git de «eliminar» o «deshacer» una confirmación, ya que el original todavía se mantiene en el historial de git.
Para usarlo, ejecuta git log
para ver las confirmaciones:
git log
Copie la ID de referencia y luego revierte la confirmación:
git revert 62ff517cc7c358eaf0bffdebbbe1b38dea92ba0f
Si solo te quedaste atrapado en vim
, presione Q, y tal vez ejecute git config --global core.editor "nano"
.
Use Rebasing para cualquier cosa más complicada
Rebasar es esencialmente un método para mover confirmaciones en su repositorio. En lugar de fusionarse, rebase reescribe el historial de git para mover las confirmaciones individuales a una nueva ubicación. Las confirmaciones originales se dejan colgando y se eliminan del historial oficial de Git, aunque todavía están allí en git reflog
.
No entraremos en los detalles exactos aquí, pero si está interesado en cómo funciona, puede leer nuestra guía para usar git rebase
.
¿Qué pasa si quieres volver?
Afortunadamente, Git mantiene un registro de cada cambio, incluso cuando rompes las reglas y reescribe el historial.
Cada vez que la sugerencia de su rama se actualiza por cualquier motivo, Git almacena el estado del contenido del directorio antes de la actualización en el Registro de referencia, o reflog
. Puede ver el registro con git reflog
:
git reflog
Muchos de estos serán confirmaciones reales, pero también incluye otros cambios. Si necesita volver a algún cambio individual, puede realizar un restablecimiento completo:
git reset --hard fdb9db9
Esto proporciona una buena red de seguridad, pero se le debe advertir que el re-registro solo rastrea los cambios que se cometieron realmente, no solo se realizaron, y solo rastrea los movimientos de la punta de la rama. Además, reflog solo conserva las entradas durante 90 días. Después de eso, solo podrá restablecer las confirmaciones reales.