Git
Tutorial Git: Deshacer cambios
Git revert, reset y restore: Aprende a deshacer cambios sin alterar el historial del repositorio, ideal para colaborar en equipo manteniendo la integridad.
Aprende Git y certifícategit revert: Revertir commits sin reescribir historial
El comando git revert
sirve para deshacer cambios introducidos sin alterar el historial existente. A diferencia de git reset
, que reescribe el historial, git revert
crea un nuevo commit que aplica los cambios inversos al commit especificado.
Para revertir un commit específico, se ejecuta:
git revert <commit>
Donde <commit>
es el identificador SHA del commit que se quiera revertir. Por ejemplo, para revertir el último commit realizado:
git revert HEAD
Si se necesita revertir varios commits, se puede hacer individualmente para cada uno o utilizar secuencias de comandos, pero con cuidado para evitar conflictos.
Durante el proceso, Git abre el editor de texto para poder modificar el mensaje del nuevo commit de reversión. Si no se quiere editar el mensaje, se puede utilizar la opción -m
para poner un mensaje predeterminado:
git revert -m 1 <merge-commit>
Esta opción se usa mucho al revertir un commit de merge. Para revertir un merge commit hay que especificar el parent al que se quiera volver.
En caso de que haya conflictos al revertir, Git muestra los archivos afectados y es necesario resolverlos. Una vez resueltos, hay que completar el proceso de revert:
git add <archivos_resueltos>
git revert --continue
Si se prefiere aplicar los cambios inversos sin crear un nuevo commit inmediatamente, se puede utilizar la opción --no-commit
o -n
:
git revert --no-commit <commit>
Esto aplica los cambios al área de staging, pudiendo agrupar varias reversiones en un solo commit posterior.
git reset: Modos --soft, --mixed, --hard y su impacto en el repositorio
El comando git reset
sirve para modificar el estado actual del repositorio, moviendo el puntero de la rama actual a un commit específico. Dependiendo del modo utilizado (--soft
, --mixed
, --hard
), se afecta de diferentes maneras el área de staging (índice) y el directorio de trabajo.
- Modo
--soft
Cuando se utiliza git reset --soft <commit>
, se mueve el puntero HEAD
y el puntero de la rama actual al commit especificado, pero se conservan los cambios en el área de staging. Los archivos modificados permanecen indexados, para que se confirmen de nuevo.
Por ejemplo:
git reset --soft HEAD~1
Este comando retrocede un commit manteniendo los cambios en staging. Es útil si se quieren combinar varios commits en uno solo o modificar el último commit.
- Modo
--mixed
(por defecto)
El modo por defecto de git reset
es --mixed
. Al ejecutar git reset --mixed <commit>
, se mueve el puntero HEAD
y el de la rama actual al commit especificado, y se actualiza el área de staging para que coincida con ese commit. Sin embargo, los cambios permanecen en el directorio de trabajo, es decir, los archivos modificados no están indexados pero sí presentes en el sistema de archivos.
Ejemplo de uso:
git reset --mixed HEAD~1
Este comando deshace el último commit y los cambios quedan disponibles en el directorio de trabajo para ser revisados o eliminados. Es útil cuando se quieren modificar los cambios antes de confirmarlos de nuevo.
- Modo
--hard
El modo --hard
es el más drástico. Al ejecutar git reset --hard <commit>
, se mueve el puntero HEAD
y el de la rama actual al commit indicado, y además se actualizan el área de staging y el directorio de trabajo para que coincidan exactamente con ese commit. Esto significa que se descartan todos los cambios en el área de staging y en el directorio de trabajo que difieran del commit objetivo.
Ejemplo:
git reset --hard HEAD~1
Este comando elimina el último commit y cualquier cambio pendiente en el área de staging o en el directorio de trabajo. Hay que tener cuidado porque los cambios descartados con --hard
no se pueden recuperar fácilmente.
Impacto en el repositorio
El uso de git reset
afecta al historial local del repositorio. Al mover el puntero de la rama actual, se reescribe el historial, lo que puede causar problemas al colaborar con otros desarrolladores si los cambios ya han sido compartidos en un repositorio remoto.
- --soft: Reescribe el historial pero mantiene los cambios en staging. Es seguro usarlo cuando se quiere combinar commits antes de hacer push.
- --mixed: Reescribe el historial y los cambios se mantienen en el directorio de trabajo. Es útil para ajustar cambios pero no debe usarse si los commits ya fueron publicados.
- --hard: Reescribe el historial y descarta permanentemente los cambios en staging y en el directorio de trabajo. Debe usarse con cautela y nunca en commits compartidos.
Descartar cambios locales: git restore
Al trabajar en un proyecto, es normal hacer cambios en archivos que luego se quieran descartar sin comprometer el historial del repositorio. Para restaurar un archivo al estado del último commit, se utiliza el comando git restore
.
La sintaxis básica es:
git restore <archivo>
Este comando elimina las modificaciones locales no guardadas en los commits, devolviendo el archivo a su versión confirmada más reciente. Por ejemplo, para descartar los cambios en main.c
:
git restore main.c
Los cambios descartados de esta manera se pierden definitivamente. Así que se recomienda verificar los cambios con git status
antes de proceder.
Descartar cambios en todos los archivos
Si se necesita descartar cambios en todos los archivos modificados, se ejecuta:
git restore .
El punto (.
) indica al comando que se aplique a todo el directorio de trabajo.
Descartar archivos del área de staging
Cuando un archivo ha sido agregado al área de staging con git add
, pero se decide no incluirlo en el próximo commit, se puede quitar del staging sin perder los cambios locales:
git restore --staged <archivo>
Este comando saca el archivo del área de staging, manteniendo las modificaciones en el directorio de trabajo.
Descartar cambios en staging y directorio de trabajo
Para descartar completamente los cambios de un archivo tanto del área de staging como del directorio de trabajo, se combinan las opciones:
git restore --staged --worktree <archivo>
O utilizando el alias -s
y -W
:
git restore -sW <archivo>
Previsualización de cambios a descartar
Es posible revisar interactivamente qué cambios se van a descartar utilizando la opción -p
:
git restore -p <archivo>
Este modo presenta cada hunk de cambios y permite decidir si se descarta o se mantiene.
Uso de git checkout -- <archivo>
Antes, el comando git checkout -- <archivo>
se utilizaba para descartar cambios locales. Aunque sigue funcionando, ahora se recomienda usar git restore
.
Ejemplo con git checkout
:
git checkout -- main.c
Este comando cumple la misma función que git restore main.c
, pero git restore
es más claro al diferenciar acciones sobre archivos y ramas.
Precauciones al descartar cambios locales
- Verificación previa: Antes de descartar cambios, se aconseja utilizar
git diff
ogit status
para revisar las modificaciones. - Cambios irrecuperables: Una vez descartados, los cambios no se pueden recuperar fácilmente. Se debe estar seguro de que los cambios no son necesarios.
- Archivos no rastreados: Para eliminar archivos nuevos que no están en seguimiento, se utiliza:
git clean -f <archivo>
El comando git clean
elimina archivos no rastreados, por lo que se debe usar con cuidado.
Mejores prácticas: Cuándo preferir revert sobre reset
Elegir cuándo usar git revert
en lugar de git reset
depende del contexto y del estado de los commits que se quieran deshacer.
Deshacer cambios en commits compartidos
Si los commits que se quieren revertir ya han sido compartidos con otros colaboradores o enviados a un repositorio remoto, hay que utilizar git revert
. Este comando crea un nuevo commit que invierte los cambios introducidos por los commits específicos, manteniendo intacto el historial y evitando conflictos.
Por ejemplo:
git revert <commit>
De este modo se mantiene un historial intacto.
Reescritura del historial en commits locales
git reset
se usa cuando se necesita modificar el historial local de commits que aún no han sido compartidos. Permite mover el puntero de la rama a un commit anterior y ajustar el área de staging y el directorio de trabajo según se necesite.
Por ejemplo, para deshacer los últimos tres commits sin afectar los archivos del directorio de trabajo:
git reset --soft HEAD~3
Es importante evitar usar git reset
en commits que ya han sido publicados, ya que reescribir el historial puede causar problemas de sincronización.
Colaboración y prevención de conflictos
En proyectos donde varias personas trabajan sobre la misma rama, utilizar git revert
ayuda a preservar un historial lineal. Los revertidos quedan registrados, y así se puede seguir qué cambios se han deshecho y por qué.
Usar git reset
en estos casos puede provocar conflictos, porque otros desarrolladores pueden haber basado su trabajo en los commits que se están eliminando del historial.
Uso seguro de git reset
git reset
es útil en situaciones como:
- Corrección de errores en commits recientes antes de compartirlos.
- Limpieza del historial local durante el desarrollo personal.
Siempre se debe confirmar que los commits afectados no han sido enviados al repositorio remoto. De lo contrario, es preferible utilizar git revert
para mantener la coherencia.
Procedimientos recomendados
Para garantizar un buen flujo de trabajo:
- Utilizar
git revert
cuando se trabaja en ramas compartidas o al deshacer cambios ya publicados. - Emplear
git reset
solo en ramas locales y con commits no compartidos. - Comunicar al equipo cualquier operación que pueda afectar al historial compartido.
- Evitar reescribir el historial en ramas públicas para prevenir problemas de integración.
Integridad del proyecto y herramientas de integración continua
En entornos con integración continua y despliegue automatizado, se necesita mantener un historial consistente. git revert
es la opción más segura, ya que las herramientas de automatización dependen de un historial sin alteraciones para funcionar correctamente.
Reescribir el historial con git reset
puede interrumpir estos procesos y desencadenar fallos en las compilaciones o despliegues.
Ejercicios de esta lección Deshacer cambios
Evalúa tus conocimientos de esta lección Deshacer cambios con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Comandos básicos
GitHub como remoto
Comandos básicos
Comandos avanzados
Git con GitHub Desktop
Ramas
Instalación y configuración
Introducción a Git
Comandos avanzados
Resolución de conflictos
Git con Intellij IDEA
Git con Visual Studio Code
Todas las lecciones de Git
Accede a todas las lecciones de Git y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Git
Introducción Y Entorno
Instalación Y Configuración
Introducción Y Entorno
Primeros Pasos Con Git
Introducción Y Entorno
Ciclo De Vida De Los Archivos
Comandos
Comandos Básicos
Comandos
Comandos Avanzados
Comandos
Gitignore Y Archivos Temporales
Comandos
Visualización Y Navegación De Cambios
Comandos
Etiquetas Tags Y Releases
Comandos
Ramas
Ramas
Merge Vs Rebase
Ramas
Stash De Cambios Entre Ramas
Ramas
Cherry Pick De Cambios
Ramas
Deshacer Cambios
Ramas
Gitflow
Ramas
Resolución De Conflictos
Trabajo Remoto Y Colaboración
Github Como Remoto
Trabajo Remoto Y Colaboración
Git Con Visual Studio Code
Trabajo Remoto Y Colaboración
Git Con Intellij Idea
Trabajo Remoto Y Colaboración
Git Con Github Desktop
Trabajo Remoto Y Colaboración
Crear Y Organizar Issues En Github
Trabajo Remoto Y Colaboración
Github Pages Para Crear Sitios Web
Trabajo Remoto Y Colaboración
Repositorio Especial Username Github
Trabajo Remoto Y Colaboración
Pull Requests (Pr) En Github
Integración Continua Ci
Ci Con Github Actions
Integración Continua Ci
Análisis Estático Con Sonarcloud
Integración Continua Ci
Desplegar En Vercel Desde Github
Integración Continua Ci
Certificados de superación de Git
Supera todos los ejercicios de programación del curso de Git y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el comando
git revert
y su funcionamiento. - Diferenciar entre
git revert
ygit reset
. - Aplicar
git revert
para deshacer cambios en commits compartidos. - Manejar conflictos al revertir commits.
- Utilizar opciones para modificar el mensaje del commit de reversión.