← Git

Flujos y buenas prácticas

¿Cuál es la diferencia entre `git reset`, `git revert` y `git checkout`?

Ver respuesta — intenta responderla en voz alta primero

git reset mueve HEAD a otro commit y puede modificar staging y working directory (reescribe historia local). git revert crea un nuevo commit que deshace los cambios de otro, sin borrar historia (seguro para lo publicado). git checkout mueve HEAD entre ramas/commits o restaura archivos (hoy dividido en switch y restore).

Los tres tocan el estado del repo, pero de formas distintas:

  • git reset <commit>: mueve la rama actual a ese commit. Con --soft conserva cambios en staging, --mixed (por defecto) los deja sin stage, --hard los borra. Reescribe historia, así que solo en local.
  • git revert <commit>: no borra nada; crea un commit nuevo que es lo inverso del commit indicado. Como no reescribe historia, es la opción segura para deshacer algo ya compartido.
  • git checkout: históricamente hacía dos cosas: cambiar de rama/commit (mover HEAD) y restaurar archivos. Por eso Git lo dividió en git switch (ramas) y git restore (archivos), más claros.

Resumen: reset para historia local, revert para historia pública, checkout/switch/restore para navegar y restaurar.

# RESET: mover HEAD hacia atras (reescribe historia local)
git reset --soft HEAD~1   # deshace el commit, conserva cambios en staging
git reset --mixed HEAD~1  # deshace, cambios sin stage (por defecto)
git reset --hard HEAD~1   # deshace y BORRA los cambios (cuidado)

# REVERT: deshacer un commit publicado creando uno inverso (seguro)
git revert abc1234
# Crea un nuevo commit que anula los cambios de abc1234

# CHECKOUT (uso clasico) y sus reemplazos modernos:
git checkout otra-rama        # cambiar de rama -> hoy: git switch otra-rama
git checkout -- archivo.txt   # descartar cambios -> hoy: git restore archivo.txt
git checkout abc1234          # ir a un commit especifico (detached HEAD)

Usar git reset --hard en una rama compartida (reescribe historia que otros tienen). Confundir reset con revert: reset borra/mueve, revert añade un commit inverso. Y con checkout, olvidar que ahora conviene usar switch para ramas y restore para archivos, que dejan la intención mucho más clara.

"git reset mueve HEAD a otro commit y, según el modo, toca staging y working directory; reescribe historia, así que solo lo uso en local. git revert no borra nada: crea un commit nuevo que deshace los cambios de otro, y por eso es lo seguro para historia ya publicada. git checkout originalmente cambiaba de rama y también restauraba archivos; Git lo dividió en switch para ramas y restore para archivos, que son más claros. Regla mental: reset para local, revert para público, switch/restore para navegar."

Reto rápido

Un commit con un bug ya está en main y varios compañeros ya hicieron pull. ¿Usas reset --hard o revert para deshacerlo?

Ver respuesta

git revert. Como el commit ya está publicado y otros lo tienen, reset --hard reescribiría la historia compartida y les causaría divergencias y conflictos. git revert crea un commit nuevo que anula los cambios del commit con bug sin borrar historia, así que todos pueden hacer pull sin problemas.