Los comandos git checkout
, git revert
y git reset
sirven para deshacer cambios en nuestro control de versiones. Son muy útiles, pero también muy parecidos y pueden generar confusión.
Basándome en el excelente tutorial de Git de Atlassian, he tomado algunas notas prácticas y simplificadas para diferenciarlos.
Git checkout
Un checkout es una operación que mueve el puntero de referencia HEAD a un commit específico.
Supongamos que el HEAD de la rama master se encuentra en el commit d. Ahora ejecutamos el comando git checkout b
.
El resultado es un cambio en el historial de commits.
Git checkout a nivel de archivo
El comando git checkout
se puede usar también a nivel de un único archivo. En cuyo caso su comportamiento es diferente a cuando se usa a nivel de commit.
En este caso no mueve el HEAD del repositorio, lo que hace es llevar al directorio de trabajo el fichero al que hemos hecho checkout con el contenido que tenía en el commit especificado.
Git reset
Un reset es una operación que toma un commit específico y restablece el historial para que coincida con el estado del repositorio en ese commit específico.
Supongamos que, partiendo de la siguiente situación, ejecutamos el comando git reset HEAD~2
Estamos deshaciendo los dos últimos commits de la rama Hotfix . Estos dos commits quedarán huérfanos y se eliminarán la próxima vez que Git haga limpieza.
Git reset a nivel de archivo
El comando git reset se puede usar también a nivel de un único archivo. En cuyo caso su comportamiento es diferente a cuando se usa a nivel de commit.
En este caso no mueve el HEAD del repositorio, lo que hace es llevar al directorio de staged el fichero al que hemos hecho reset con el contenido que tenía en el commit especificado. De modo que en el directorio de trabajo estará la versión última del contenido pendiente de commit y en staged la versión del contenido a la que hemos vuelto.
Git revert
Un revert es una operación que toma un commit específico y crea un nuevo commit con el contenido del commit especificado.
Este comando solo se puede ejecutar a nivel de commit y no a nivel de archivo.
Supongamos que partimos de la siguiente situación y queremos volver al commit marcado con el asterisco.
Tras ejecutar el comando git revert HEAD~2
estaremos deshaciendo los cambios de los dos últimos commits de la rama Hotfix añadiendo un nuevo commit que ejecuta los cambios.
Usos más frecuentes
Lo comandos de checkout y reset generalmente se usan para deshacer cambios en nuestro repositorio o rama de uso privado. Modifican el historial de un repositorio y pueden causar conflictos al hacer push a repositorios o ramas compartidas remotas.
Revert se considera una operación segura para deshacer en un repositorio público ya que crea un nuevo historial que se puede compartir de forma remota y no sobrescribe el historial del que pueden depender los miembros remotos del equipo.
En la siguiente tabla se resumen los usos más frecuentes que se hacen de estos comandos.
Comando | Alcance | Uso más común |
---|---|---|
git reset |
Commit | Descartar commits en una rama privada o descartar cambios no commiteados |
git reset |
Archivo | Cargar en el directorio staged una versión antigua del archivo |
git checkout |
Commit | Cambiar entre ramas o inspeccionar commits antiguos |
git checkout |
Archivo | Cargar en el directorio de trabajo una versión antigua del archivo |
git revert |
Commit | Deshacer commits en una rama pública |
git revert |
Archivo | No disponible |