programa
El comando git reset es una de las herramientas más potentes de Git para controlar el estado de tu repositorio. Te permite ajustar a qué commit apunta una rama, decidir qué permanece en el área de preparación (staging) para el próximo commit e incluso reescribir el historial local antes de hacer push.
Esta guía se centra específicamente en git reset HEAD, una variación versátil para deshacer el staging de archivos y gestionar el historial de commits.
A lo largo de la guía, veremos el comando en detalle, sus distintos modos y cómo se compara con otros comandos que suelen confundirse, como git revert y git clean.
Fundamentos de git reset HEAD
Antes de aprender a aplicar git reset HEAD, repasemos los conceptos que determinan su comportamiento.
La arquitectura de tres árboles de Git
Git gestiona los datos en tres áreas conceptuales:
- Historial de commits (repositorio): el registro permanente de instantáneas del proyecto, donde se guardan todos los commits que has hecho.
- Área de preparación (index): contiene los cambios que has marcado para incluir en el próximo commit.
- Directorio de trabajo: tu sistema de archivos real, donde editas y pruebas el código.
Estos tres árboles interactúan constantemente cuando trabajas con Git para gestionar el historial de versiones.
Por ejemplo, al ejecutar git add, pasas cambios del directorio de trabajo al área de preparación. Cuando haces commit, Git toma una instantánea del staging y la registra en el historial.
El comando git reset cambia el puntero de la rama actual a un commit concreto, moviendo HEAD con él. En estado de HEAD desanclado (detached), desplaza HEAD directamente. Según el modo, git reset también actualiza el index y puede modificar el directorio de trabajo. Es una herramienta esencial para un control de versiones preciso.
Qué es HEAD en Git
El puntero HEAD es la forma que tiene Git de llevar la cuenta de tu posición actual en el historial de commits. Normalmente, HEAD apunta al último commit de la rama que tienes desprotegida (checkout).
Sin embargo, también puede apuntar directamente a un commit si estás en un estado de «HEAD desanclado». Entender este puntero es clave, ya que git reset funciona moviendo HEAD (y potencialmente la referencia de la rama) a un nuevo commit.
Mientras que los punteros de rama y los hashes de commit proporcionan referencias estáticas, HEAD es dinámico y se mueve al navegar por el historial o cambiar de rama.
Reconocer esta diferencia ayuda a evitar confusiones al hacer resets.
Cómo moverte por el historial de commits
Git ofrece una notación abreviada para moverse en relación con HEAD:
HEAD^→ el padre inmediato (primero) del commit actualHEAD~2→ el commit abuelo (dos pasos atrás)
Esta abreviatura permite navegar rápido sin hashes completos. Aunque ramas y tags también referencian commits, HEAD garantiza que comandos como reset o checkout sepan dónde estás.
Consejo sobre padres: HEAD~N sigue la cadena del primer padre N pasos. ^ selecciona un padre; en commits de merge puedes especificar cuál, por ejemplo, HEAD^1, HEAD^2.
Modos de git reset HEAD: soft, mixed, hard
git reset tiene tres modos, que definen cuán profundo afecta al repositorio. Cada uno produce resultados distintos, así que conviene saber cómo funcionan para usarlos correctamente.
Modo soft
git reset --soft HEAD^
En primer lugar, el modo soft. Con git reset --soft <target>, Git mueve el puntero de la rama hacia atrás (o al commit objetivo) pero mantiene todos los cambios preparados en el index.
Resulta especialmente útil cuando:
- Te das cuenta de que el mensaje del último commit es incorrecto
- Quieres agrupar varios cambios en un único commit sin perder lo que ya tenías en staging.
Este comando deja intacta el área de preparación, así que puedes volver a hacer commit con un mensaje mejor o afinando la selección.
Modo mixed
git reset --mixed HEAD^
A continuación, el modo mixed, que es el predeterminado. git reset --mixed <target> mueve el puntero de la rama y restablece el staging para que coincida con el commit objetivo, conservando los cambios en el directorio de trabajo.
Esto te permite reestructurar commits dividiendo uno grande en varios más pequeños y lógicos. Tras el reset, puedes seleccionar qué archivos preparar y volver a commitear de forma más organizada.
Modo hard
git reset --hard HEAD^
Por último, el modo hard revierte cambios en archivos trackeados. git reset --hard <target> es la opción más contundente y arriesgada. Restablece el puntero de la rama, el index y el directorio de trabajo para que coincidan exactamente con el commit objetivo. Esto descarta todos los cambios no confirmados en archivos trackeados del index y del directorio de trabajo. Los archivos no trackeados no se eliminan (usa git clean para esos casos).
Aunque puede ser útil cuando quieres dejar todo como nuevo, conlleva riesgo, especialmente en equipos, porque elimina de forma permanente cambios que no estén en un commit.
Sintaxis y variantes de git reset HEAD
Vamos a entenderlo mejor mirando la sintaxis del comando.
Estructura básica
La forma general de un comando git reset es:
git reset [--soft | --mixed | --hard] <target>
El modo determina hasta dónde afecta al estado del repositorio, y el objetivo define a qué commit te estás reseteando. Si omites el modo, el valor por defecto es --mixed.
Apuntar a commits concretos
Puedes referenciar commits con distintas notaciones:
- Notación relativa como
HEAD^oHEAD~3 - Hashes explícitos (p. ej.,
git reset 4a5d9c2) - Nombres de rama o tags
Para mayor seguridad, git reflog permite identificar movimientos recientes de HEAD y recuperar commits descartados por error.
Operaciones de reset por archivo
También puedes actualizar el área de preparación solo para un archivo concreto, dejando la copia de trabajo sin cambios.
La sintaxis es:
git reset HEAD -- <file>
Este comando se usa habitualmente para «despreparar» (unstage) un archivo añadido por accidente al index.
Como alternativa, las versiones modernas de Git ofrecen git restore --staged <file>, más descriptivo. Los resets por archivo son ideales para afinar qué entrará en tu próximo commit sin perder tus ediciones.
Si quieres más información sobre comandos de Git, echa un vistazo a nuestra chuleta de Git a continuación.

Aplicaciones prácticas y casos de uso de git reset HEAD
Este comando de reset tiene muchos usos en control de versiones. Algunos casos prácticos:
1. Corregir errores en commits
Es frecuente hacer commits demasiado pronto o con cambios incompletos.
git reset --soft HEAD^ te permite deshacer el último commit manteniendo todo en staging, para volver a commitear correctamente sin rehacer cambios desde cero.
Como alternativa, git reset HEAD^ deshace el commit dejando los cambios sin preparar, para volver a seleccionar con más detalle.
2. Reorganizar commits
A veces un commit incluye demasiados cambios no relacionados. Un reset mixed te permite retroceder un commit manteniendo los cambios en el directorio de trabajo.
Desde ahí, puedes crear varios commits más pequeños que reflejen mejor la evolución del proyecto. Del mismo modo, si hiciste un merge antes de tiempo, hacer reset te da margen para reorganizar el historial antes de compartirlo.
3. Gestionar el staging de archivos
Quitar del staging archivos concretos con git reset HEAD -- <file> garantiza que solo se confirmen juntos los archivos relevantes. Esto favorece commits atómicos, más fáciles de entender y revisar.
Por ejemplo, si corriges un bug y también actualizas la documentación, al quitar uno de esos conjuntos del staging te aseguras de que cada commit tenga un único propósito claro.
4. Sincronizar ramas con remotos
Cuando tu rama local se desvía mucho del remoto, un reset hard a la rama remota (p. ej., git reset --hard origin/main) fuerza la alineación.
Puede ser útil para descartar cambios locales experimentales, pero hazlo con cautela porque elimina modificaciones locales de forma permanente.
Historial remoto: git reset es local. Para reflejar el historial reescrito en el remoto, usa git push --force-with-lease y coordínate con tu equipo para no sobrescribir su trabajo.
Consideraciones de seguridad y gestión de riesgos
Dado que git reset puede descartar cambios en el index y el directorio de trabajo, conviene tener en cuenta algunos aspectos de seguridad y riesgo.
Riesgos de usar git reset HEAD
Aunque los resets pueden limpiar el historial, también pueden destruir trabajo.
Usar git reset HEAD sin flags adicionales aplica el modo mixed por defecto. Esto deshace el staging de los cambios preparados (permanecen en tu directorio de trabajo). Aunque los cambios seguirán en tu copia de trabajo, ya no estarán marcados para el próximo commit.
Los cambios no confirmados pasan a estar sin preparar; las modificaciones de archivos permanecen en disco. Si modificaste archivos que ya estaban en staging, git reset HEAD hará que el área de preparación coincida con el commit en HEAD, dejando efectivamente esos cambios fuera del staging.
Comprobaciones previas al reset
Antes de ejecutar un reset, revisa el estado del repositorio para asegurarte de que todo está en orden.
Para ello, sigue estos pasos:
- Ejecuta
git statuspara confirmar qué archivos están en staging o modificados. - Usa
git logogit reflogpara ver dónde apunta actualmente HEAD. - Compara cambios con
git diffpara confirmar qué podrías perder.
Tomar estas precauciones reduce sorpresas y asegura que haces reset de forma intencionada.
Estrategias de copia de seguridad y recuperación
Crea siempre una copia de seguridad antes de operaciones arriesgadas, como cambios importantes en el código.
Aquí tienes algunas estrategias:
- Stash: guarda temporalmente cambios no confirmados con
git stash push -m "backup". - Ramas: crea una rama de respaldo con
git branch savepointpara conservar el historial actual.
Estas medidas hacen que los resets impongan menos y te dan confianza para experimentar con seguridad.
Mecanismos de recuperación y deshacer
Si ejecutas un comando de Git equivocado, hay varias formas de recuperar el trabajo.
Usar git reflog para recuperar
git reflog registra cada movimiento de HEAD y puede salvarte tras un reset accidental. Si pierdes la pista de un commit, ejecuta:
git reflog
git reset --hard <commit-id>
Esto te permite recuperar trabajo descartado siempre que el commit no haya sido recolectado por el GC.
Estrategias alternativas de recuperación
Además de reflog, puedes apoyarte en stashes y ramas de respaldo. Los stashes capturan trabajo no confirmado, mientras que las ramas preservan historiales completos. En colaboración, a menudo puedes recuperarte trayendo el estado correcto del repositorio remoto.
Usos avanzados y buenas prácticas
El comando git reset HEAD también sirve para operaciones más avanzadas.
1. Flujos de trabajo de staging interactivo
Combinar git add --patch con resets a nivel de archivo te da el máximo control sobre lo que entra en cada commit. Así garantizas commits atómicos y centrados, lo que mejora la legibilidad y reduce el riesgo de introducir cambios no relacionados.
2. Pulir mensajes de commit
Si detectas una errata o quieres aclarar un mensaje, un reset soft te permite reescribir el commit sin tocar el código. Es una forma limpia de mantener un historial con sentido.
3. Gestión de ramas y reescritura de historial
Reset también puede usarse de forma estratégica antes de hacer merge para ordenar el historial. Es habitual usar resets para «squashear» o reorganizar commits y que las ramas presenten un historial más limpio al integrarlas en la línea principal.
4. Protocolos de colaboración
En equipos, los acuerdos claros son esenciales. Evita hacer reset en ramas compartidas y avisa cuando sea necesario usar force-push.
Seguir estos protocolos evita confusiones e historiales rotos en repositorios compartidos.
Comandos relacionados y herramientas adicionales
Los comandos de Git suelen usarse en combinación. Aquí tienes algunos relacionados que funcionan de forma similar a git reset HEAD.
Usar git clean para eliminar archivos no trackeados
A veces, los archivos no trackeados llenan tu directorio de trabajo. git clean los elimina, pero con precaución: es irreversible. Ejecuta git clean -n para una simulación antes de borrar realmente. En combinación con git reset, puedes devolver el repositorio a un estado limpio.
Usar git revert para historial público
Al trabajar en repositorios compartidos, plantéate usar git revert en lugar de git reset para deshacer commits. git revert crea un nuevo commit que revierte los cambios de uno anterior, preservando la integridad del historial. En cambio, git reset reescribe el historial, lo que puede afectar al trabajo de tus compañeros.
Comparativa rápida:
reset→ reescribe el historial.revert→ crea un commit nuevo que deshace uno anterior.restore→ ajusta archivos de trabajo sin cambiar el historial.
Conclusión
Usar git reset HEAD te da un control muy fino sobre el estado del repositorio. Es potente, pero hay que usarlo con cautela, especialmente en entornos colaborativos donde reescribir el historial puede causar conflictos.
Esta función básica ofrece muchas posibilidades para trabajar con repositorios y revertir cambios indeseados. Si quieres aprender más sobre Git, echa un vistazo a nuestro GitHub Foundations skill track o al curso Foundations of Git.
Preguntas frecuentes sobre git reset HEAD
¿Cuáles son las mejores prácticas para usar git reset --hard?
Usa git reset --hard con moderación, ya que descarta de forma permanente los cambios tanto en el área de preparación como en el directorio de trabajo. Verifica siempre que no necesites los cambios no confirmados antes de eliminarlos. Haz commit o stash de tu trabajo antes de ejecutar el comando para tener un plan B si te pasas con el reset.
¿Cómo puedo recuperarme de un git reset --hard accidental?
La recuperación depende de si el commit estaba referenciado en otro sitio. A menudo, el reflog de Git ayuda: al ejecutar git reflog verás el historial de posiciones recientes de HEAD y podrás usar git checkout o git reset para volver al commit perdido. Si no hiciste commit antes del reset, el trabajo no confirmado suele ser irrecuperable.
¿Cuáles son las diferencias entre git reset --soft, --mixed y --hard?
--soft mueve HEAD a un nuevo commit pero mantiene todos los cambios en staging. --mixed (por defecto) mueve HEAD y limpia el área de preparación, pero deja intacto el directorio de trabajo. --hard mueve HEAD, limpia el staging y sobrescribe el directorio de trabajo, borrando por completo los cambios no confirmados.
¿Cómo afecta git reset --hard a los cambios no confirmados?
git reset --hard borra los cambios no confirmados. Cualquier modificación en tu directorio de trabajo o en el área de preparación que no se haya confirmado se pierde al ejecutar git reset --hard.
¿Puedo usar git reset --hard en un repositorio remoto?
No. git reset --hard solo afecta a tu repositorio local. Para cambiar una rama remota, tendrías que hacer push de tus cambios locales con un push forzado (git push --force), que puede reescribir el historial para el resto del equipo. Solo deberías hacerlo avisando claramente, ya que puede romper la colaboración.
Soy Austin, bloguero y escritor técnico con años de experiencia como científico de datos y analista de datos en el sector sanitario. Empecé mi andadura tecnológica con una formación en biología, y ahora ayudo a otros a hacer la misma transición a través de mi blog tecnológico. Mi pasión por la tecnología me ha llevado a escribir para decenas de empresas de SaaS, inspirando a otros y compartiendo mis experiencias.
