git reset

Instantáneas básicas

Restablecer el HEAD actual al estado indicado


El comando 'git reset' sirve para deshacer cambios moviendo el HEAD de la rama actual a un commit concreto. Tiene tres modos principales: --soft (conserva los cambios preparados), --mixed (por defecto: conserva los cambios en el directorio de trabajo) y --hard (descarta todos los cambios). Es esencial para deshacer commits, quitar archivos de la preparación y gestionar tu historial. Cuidado con 'git reset --hard', que descarta los cambios para siempre.

Sinopsis

git reset [-q] [<tree-ish>] [--] <pathspec>...
git reset [-q] [--pathspec-from-file=<file>] [<tree-ish>]
git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>...]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
[ ] opcional| o<arg> valor a sustituir... repetible--flag opción

Opciones

Haz clic en una opción para desplegarla

Principiante (3)

Restablece HEAD al commit indicado, pero conserva todos los cambios preparados. Tu directorio de trabajo y tu área de preparación no cambian. Úsalo para deshacer commits dejando los cambios listos para un nuevo commit.

Cuando haga faltaDeshacer commits dejando los cambios preparados, p. ej. para volver a confirmar o combinar

Ejemplo

git reset --soft HEAD~1

El modo por defecto. Restablece HEAD y el área de preparación, pero conserva los cambios en el directorio de trabajo. Úsalo para quitar cambios de la preparación y seguir pudiendo editarlos.

RecomendadoLa forma más segura de deshacer un commit local o quitar de la preparación; conserva tus cambios

Ejemplo

git reset HEAD~1

Restablece HEAD, el área de preparación Y el directorio de trabajo al commit indicado. Se descartan los cambios sin commit de los archivos con seguimiento, y los archivos sin seguimiento que estorban a los del commit se sobrescriben (los demás archivos sin seguimiento no se tocan). Los cambios sin commit no se pueden recuperar.

No recomendadoDestruye los cambios sin commit de los archivos con seguimiento: haz stash o commit antes

Ejemplo

git reset --hard HEAD~1

Intermedio (1)

Elegir de forma interactiva qué fragmentos quitar de la preparación. Te permite sacar cambios concretos del área de preparación y dejar otros preparados.

Cuando haga faltaQuitar hunks de la preparación de forma interactiva

Ejemplo

git reset -p

Avanzado (2)

Restablece el índice y actualiza los archivos que difieren entre el commit y HEAD, pero conserva los cambios sin preparar. Los cambios preparados se descartan. Se cancela si un archivo que debe cambiar tiene ediciones sin preparar.

Cuando haga faltaAborta un merge; descarta los cambios preparados pero conserva los que no lo están

Ejemplo

git reset --merge HEAD~1

Restablece el índice y actualiza los archivos que difieren entre el commit y HEAD. Se cancela si alguno de esos archivos tiene cambios locales. Conserva los cambios sin commit de los archivos que no cambian entre los commits.

Cuando haga faltaMás seguro que --hard para volver atrás: se niega a sobrescribir cambios locales

Ejemplo

git reset --keep HEAD~1

Elegir la opción adecuada

Modos de reset: ¿qué se conserva?

Entender los tres modos principales de reset y qué pasa con tus cambios

ComandoHEAD se mueveÁrea de preparaciónDirectorio de trabajoÚsalo cuando
--softSíSe conservan (preparados)ConservadoDeshacer un commit para rehacerlo con cambios
--mixed (default)SíSe vacía (sin preparar)ConservadoDeshacer un commit para editar antes de preparar
--hardSíVaciadoSe PIERDEN los cambios con seguimiento (los sin seguimiento se quedan)Descartar por completo el commit y todos los cambios

Reset frente a revert y checkout

Elegir el comando adecuado para deshacer según tu situación

Comando¿Modifica el historial?¿Seguro con commits subidos?Ideal para
git resetSí (mueve la rama)No: causa problemasDeshacer commits locales aún sin subir
git revertNo (añade un commit nuevo)Sí: seguro en ramas compartidasDeshacer commits subidos en ramas compartidas
git checkout -- fileNoSíDescartar cambios sin commit de archivos concretos

Quitar cambios de la preparación: reset frente a restore

El Git moderno ofrece git restore como alternativa a reset para quitar de la preparación

ComandoPropósito¿Afecta a los commits?Recomendado
git reset HEAD fileQuitar un archivo de la preparaciónNoForma tradicional
git restore --staged fileQuitar un archivo de la preparaciónNoForma moderna (Git 2.23+)
git resetQuitar todos los archivos de la preparaciónNoFunciona bien
git restore --staged .Quitar todos los archivos de la preparaciónNoIntención más explícita

Modos de reset avanzados

Cuándo usar --merge y --keep en lugar de --hard

Comando¿Conserva los cambios locales?¿Se detiene si hay conflictos?Caso de uso
--hardNo: lo destruye todoNoReset completo, los cambios dan igual
--mergeSolo los cambios sin preparar (los preparados se pierden)SíCancelar un merge conservando el trabajo no relacionado
--keepSí (en los archivos que el reset no toca)SíDeshacer un commit pero conservar cambios locales no relacionados

Ejemplos

Deshacer el último commit y conservar los cambios preparados

git reset --soft HEAD~1

Retrocede HEAD un commit. Los cambios de ese commit siguen preparados, listos para un nuevo commit.


Deshacer el último commit y conservar los cambios en el directorio de trabajo

git reset HEAD~1

Modo por defecto (--mixed). Retrocede HEAD un commit. Los cambios se conservan, pero sin preparar.


Descartar por completo el último commit y los cambios

git reset --hard HEAD~1

Retrocede HEAD un commit y descarta TODOS los cambios sin commit de los archivos con seguimiento. Con cuidado: el trabajo sin commit perdido no se puede recuperar (el commit en sí sigue en git reflog).


Quitar de la preparación un archivo concreto

git reset HEAD file.js

Quita file.js del área de preparación sin descartar los cambios. El archivo sigue modificado en el directorio de trabajo.

Ejemplos de flujos de trabajo

1
git log --oneline -3

Ver los commits recientes para confirmar cuál deshacer

2
git reset --soft HEAD~1

Deshacer el commit y conservar los cambios preparados

3
git status

Comprobar que los cambios están preparados

4
git commit -m "Better message"

Volver a hacer commit con un mensaje nuevo

1
git status

Ver qué está preparado ahora

2
git reset HEAD unwanted-file.js

Quitar de la preparación uno o varios archivos

3
git status

Comprobar que el archivo ya no está preparado

4
git commit

Hacer commit solo de los archivos que quieres

1
git status

Revisar lo que se va a perder

2
git stash

(Opcional) Guardar los cambios por si acaso

3
git reset --hard HEAD~1

Descartar el último commit Y todos los cambios con seguimiento (los archivos sin seguimiento se quedan)

4
git status

Comprobar que el directorio de trabajo está limpio

1
git reflog

Encontrar el hash del commit anterior al reset

2
git reset --hard abc1234

Volver a ese hash de commit

3
git log --oneline

Comprobar que los commits se han recuperado

Solución de problemas

fatal: ambiguous argument 'HEAD~1': unknown revision

Causa: Estás en el commit inicial: no hay un commit anterior al que volver

Revisa git log. Si solo hay un commit, no puedes retroceder más. Usa git update-ref -d HEAD para empezar de cero por completo.

error: Entry 'app.js' not uptodate. Cannot merge.

Causa: Un archivo que --merge o --keep tendría que cambiar tiene ediciones locales sin commit, así que el reset se cancela

Haz commit o stash de tus cambios primero, o usa --hard si quieres descartarlos

Usé --hard sin querer y perdí cambios

Causa: El reset hard descarta para siempre todo el trabajo sin commit

Si los cambios tenían commit: git reflog para encontrar el commit y luego git reset --hard <hash>. Si nunca tuvieron commit: probablemente se han perdido para siempre.

El reset funcionó, pero un compañero dice que el historial está roto

Causa: Hiciste reset de commits que ya estaban subidos a una rama compartida

En ramas compartidas, usa git revert. Para arreglarlo: git reflog, encuentra el commit original, haz reset a él y luego force push (coordínate con el equipo).

fatal: ambiguous argument 'HEAD' al ejecutar git reset HEAD file

Causa: El repositorio aún no tiene commits, así que HEAD no existe (o la ruta es incorrecta)

Quita HEAD: git reset file.js (o git rm --cached file.js). Comprueba la ruta exacta con git status.

Consejos y trampas

Buenas prácticas

  • ✓Nunca uses git reset con commits subidos a ramas compartidas: usa git revert en su lugar
  • ✓Ejecuta siempre git status antes de un reset para entender qué se verá afectado
  • ✓Mejor --soft cuando quieras rehacer un commit con cambios
  • ✓Haz git stash antes de un reset --hard si quizá quieras recuperar tus cambios
  • ✓Recuerda que git reflog permite recuperarse de la mayoría de errores de reset (para cambios con commit)
  • ✓Usa git reset HEAD <file> para quitar archivos de la preparación en lugar de hacer reset de commits enteros
  • ✓Plantéate git restore --staged como alternativa moderna para quitar archivos de la preparación

Errores comunes

  • ✗Usar 'git reset --hard' sin darse cuenta de que borra para siempre los cambios sin commit. Compruébalo siempre dos veces antes de usar --hard.
  • ✗Hacer reset de commits ya subidos a un remoto compartido. Reescribe el historial y causa problemas a quienes colaboran. Usa 'git revert' en su lugar.
  • ✗Confundir 'git reset' con 'git revert'. Reset mueve hacia atrás el puntero de la rama; revert crea un commit nuevo que deshace los cambios.
  • ✗No saber que puedes recuperarte de un mal reset usando 'git reflog' para encontrar el hash del commit anterior.
  • ✗Usar 'git reset --hard HEAD' para descartar cambios de trabajo cuando 'git checkout -- .' o 'git restore .' serían más adecuados.

Preguntas frecuentes

A:

Soft conserva los cambios preparados. Mixed (por defecto) los conserva en el directorio de trabajo, pero sin preparar. Hard lo descarta todo. Piénsalo así: soft = deshacer solo el commit, mixed = deshacer el commit + quitar de la preparación, hard = deshacerlo todo.

A:

Para cambios con commit: sí, usa git reflog para encontrar el hash del commit original y haz reset a él. Para cambios sin commit perdidos con --hard: normalmente no, han desaparecido para siempre.

A:

HEAD~1 significa «un commit antes de HEAD». HEAD~2 son dos commits atrás, etc. También puedes usar directamente hashes de commit, como git reset abc1234.

A:

Reset para commits locales aún sin subir: reescribe el historial de forma limpia. Revert para commits subidos en ramas compartidas: crea un commit nuevo que deshace los cambios sin reescribir el historial.

A:

Usa git reset HEAD filename para quitar un archivo concreto de la preparación. No mueve HEAD ni afecta a ningún commit: solo saca el archivo del área de preparación.

A:

Borra para siempre los cambios sin commit. A diferencia de los cambios con commit (recuperables con el reflog), el trabajo que nunca tuvo commit no se puede recuperar tras un reset hard.