← Git

Commits y cambios

¿Cómo deshaces cambios en Git y cómo eliges el comando correcto?

Ver respuesta — intenta responderla en voz alta primero

Depende de dónde está el cambio. Para descartar ediciones sin commitear usas git restore. Para sacar algo del staging, git restore --staged. Para mover HEAD y deshacer commits locales, git reset (--soft, --mixed, --hard). Para deshacer un commit ya publicado sin borrar historia, git revert, que crea un commit inverso.

La clave es preguntarte: ¿qué quiero deshacer y ese cambio ya se publicó?

  • git restore archivo: descarta los cambios sin commitear de un archivo, volviéndolo al último commit. (Antes se usaba git checkout -- archivo.)
  • git restore --staged archivo: quita el archivo del staging, pero conserva tus cambios en el working directory.
  • git reset: mueve el puntero HEAD a un commit anterior. Tiene tres modos:
    • --soft: deshace el commit, pero deja los cambios en staging.
    • --mixed (por defecto): deshace el commit y saca los cambios de staging, pero los conserva en el working directory.
    • --hard: deshace el commit y borra los cambios. Peligroso: pierdes trabajo.
  • git revert <commit>: crea un nuevo commit que deshace los cambios de otro commit. No borra historia, por eso es seguro para commits ya compartidos.

Regla de oro: en historia ya publicada (que otros tienen), usa revert, nunca reset --hard.

# Descartar cambios sin commitear de un archivo (vuelve al último commit)
git restore index.html

# Sacar un archivo del staging, conservando sus cambios
git restore --staged index.html

# Deshacer el ÚLTIMO commit, conservando los cambios en staging
git reset --soft HEAD~1

# Deshacer el último commit, conservando los cambios sin stage (por defecto)
git reset HEAD~1
# equivalente a: git reset --mixed HEAD~1

# Deshacer el último commit Y BORRAR los cambios (cuidado)
git reset --hard HEAD~1

# Deshacer un commit ya publicado creando uno inverso (seguro)
git revert abc1234

Usar git reset --hard en una rama compartida y reescribir historia que otros ya tienen, causándoles conflictos graves al hacer pull. También es muy común confundir reset --soft, --mixed y --hard: recuerda que --soft conserva en staging, --mixed conserva sin stage y --hard borra todo.

"Depende de dónde esté el cambio. Si solo edité un archivo y no lo commiteé, uso git restore. Si ya lo puse en staging y quiero sacarlo, git restore --staged. Si ya hice un commit local que quiero deshacer, uso git reset: --soft deja los cambios en staging, --mixed los deja sin stage y --hard los borra. Y si el commit ya está publicado, uso git revert, que crea un commit inverso sin reescribir la historia. La regla de oro es no usar reset --hard en historia compartida."

Reto rápido

Hiciste un commit local que aún no has pusheado, y quieres deshacerlo pero conservar los cambios listos para volver a commitear (en staging). ¿Qué comando usas?

Ver respuesta

git reset --soft HEAD~1. El modo --soft deshace el commit pero deja todos sus cambios en el staging area, así que puedes editarlos, volver a preparar lo que quieras y hacer un nuevo commit. Como el commit era local y no estaba publicado, reescribir esa historia es seguro.