git-reset-soft-mixed-hard

Deshacer la historia con Git Reset

  • 5 min

El comando git reset es un comando que nos permite deshacer secuencias completas de trabajo moviendo el puntero de nuestro repositorio a un commit anterior.

Hemos visto cómo avanzar en la historia (crear commits) y cómo arreglar pequeños despistes (amend, restore).

Pero a veces, el error es mayor. A veces has avanzado por un camino equivocado durante horas y quieres volver atrás. Quieres coger la máquina del tiempo y regresar al ayer.

git reset es esa máquina del tiempo. Su función principal es mover el puntero HEAD (tu ubicación actual) a un commit anterior.

git reset es una de las herramientas más útiles, pero y también de las más peligrosas.

Usar solo en commits que no han sido puestos en un remoto.

El concepto: Moviendo el puntero

Imagina tu historial como una fila de fichas de dominó. HEAD está apuntando a la última ficha (Commit C).

Si hacemos un git reset al commit A, estamos moviendo el puntero.

Los commits B y C dejan de ser accesibles (se quedan “huérfanos”). Pero, ¿qué pasa con los cambios de código que había dentro de B y C? ¿Se borran? ¿Se quedan en tu carpeta?

La respuesta depende del “sabor” del reset que elijas: Soft, Mixed o Hard.

Tipos de Reset

Para tenerlo claro de un vistazo, imagina que estamos deshaciendo el último commit. ¿Dónde acaban mis cambios?

ModoMueve HEADStaging Area (Index)Working Directory
—softSe conservanSe conservan
—mixed (Default)Se vacíaSe conservan
—hardSe vacíaSE BORRAN 🚨

Los cambios que estaban en el commit deshecho ahora aparecen como Staged (verdes). Es como si hubieras hecho el trabajo y los git add, pero justo antes de hacer el commit.

git reset --soft HEAD~1
Copied!

El ~1 significa “volver un paso atrás”

¿Cuándo usarlo?

  • Para unir commits (Squash manual): Hiciste 3 commits pequeños (“WIP”, “WIP”, “Terminado”) y quieres convertirlos en uno solo. Haces un reset soft de 3 pasos atrás, y vuelves a commitear todo junto con un mensaje decente.

Los cambios del commit deshecho ahora aparecen como Modified (rojos). Están en tu carpeta, a salvo, pero Git “no los ha preparado” todavía.

git reset --mixed HEAD~1
Copied!

O simplemente git reset HEAD~1, ya que Mixed es el modo por defecto

¿Cuándo usarlo?

  • Es el estándar para corregir el rumbo. “He hecho un commit, pero veo que he mezclado dos tareas diferentes”. Haces reset mixed, y ahora tienes los archivos sueltos para ir haciendo git add por partes y separarlos en dos commits limpios.

Todo vuelve a estar exactamente igual que en el commit al que has saltado. Cualquier cambio que hubieras hecho en los commits posteriores o en tu carpeta de trabajo SE DESTRUYE.

git reset --hard HEAD~1
Copied!

¿Cuándo usarlo?

  • Cuando has roto todo: Has intentado una refactorización, nada compila, hay errores por todos lados y quieres tirar todo a la basura y volver al último punto estable.

¡Peligro! Este es el único modo destructivo. Si tenías código sin guardar o cambios importantes en ese commit que estás deshaciendo, los perderás. Úsalo solo cuando estés seguro de que quieres borrar tu trabajo reciente.

Viajando a un punto específico

Aunque hemos usado HEAD~1 (un paso atrás) en los ejemplos, también puedes usar reset a un Commit determinado usando su Hash.

Si haces un git log y ves que el proyecto funcionaba bien en el commit a1b2c3d, puedes saltar directamente allí:

git reset --hard a1b2c3d
Copied!

Ahora tu proyecto es exactamente igual que en ese momento del pasado. Todo lo que ocurrió después ha desaparecido de la historia.

No si has hecho push

Ya lo había avisado antes, pero aquí lo amplio porque es de las liadas más gordas y comunes en Git.

NUNCA hagas git reset (de ningún tipo) en ramas que ya has subido (Push) y que comparten otros compañeros.*

Si tú “borras” historia en tu ordenador, pero tus compañeros la tienen en el suyo, al intentar sincronizar crearás un conflicto horrible 💥.

git reset es una herramienta para limpiar tu historia local antes de compartirla.