El estado Detached HEAD es una situación donde HEAD apunta directamente hacia un commit en lugar de referenciar una rama.
En artículos anteriores vimos cómo restaurar un archivo específico (git restore). Pero a veces, la necesidad no es recuperar un fichero suelto, sino llevar todo el proyecto a un estado anterior.
Quizás necesitas compilar la versión exacta que entregaste al cliente hace seis meses para reproducir un bug. O quieres verificar si una funcionalidad existía en el commit a1b2c3d.
Para esto, necesitamos mover el puntero HEAD. Al hacerlo de forma directa, entraremos en un estado técnico conocido como Detached HEAD.
¿Qué significa esto a nivel de arquitectura interna? Básicamente que si no tienes cuidado puedes liarla parda 👇.
El comando para viajar al pasado
Para mover nuestro entorno de trabajo completo a un commit específico, usamos el comando switch con la bandera --detach:
git switch --detach a1b2c3d`
Antiguamente se usaba git checkout a1b2c3d
Al ejecutar esto, Git actualiza tu Working Directory para que coincida exactamente con la foto guardada en ese commit.
Inmediatamente, Git mostrará un aviso extenso que comienza con:
You are in ‘detached HEAD’ state.
Empieza la fiesta 🚨.
Anatomía del Detached HEAD
Técnicamente, “Detached HEAD” significa simplemente: HEAD está apuntando directamente a un Commit, no a una Rama.
Para comprender este estado, debemos recordar cómo funciona el puntero HEAD en condiciones normales.
Estado Normal (Attached): Generalmente, HEAD apunta a una Rama. Cuando haces un nuevo commit, Git sabe que debe actualizar la referencia de main para que avance.
Estado Detached: Cuando HEAD apunta directamente a un commit, saltándose la referencia de rama.
¿Qué puedo (y no) hacer aquí?
Este es un estado de observación. Es seguro para:
- Compilar y ejecutar el proyecto en esa versión antigua.
- Ejecutar tests.
- Inspeccionar archivos.
El problema surge si decides escribir código y hacer commits en este estado.
El peligro de los commits huérfanos
Supongamos que estando en Detached HEAD arreglas un bug y haces git commit. Git creará un nuevo commit D y moverá el HEAD a él.
Hasta aquí todo parece bien. El problema ocurre cuando decides volver al presente:
git switch main
En el momento en que cambias a main:
HEAD deja de apuntar a D y vuelve a apuntar a main.
Ninguna rama apunta a D.
El commit D se queda huérfano e inaccesible. No aparecerá en el git log y, eventualmente, el recolector de basura de Git lo eliminará definitivamente.
Cómo “arreglar” un Detached HEAD
Hay dos escenarios posibles al trabajar en este estado:
Escenario A: Solo estaba mirando
Si solo has entrado para mirar y no has hecho cambios, realmente no hay nada que arreglar. Simplemente vuelve a tu rama habitual:
git switch main
Escenario B: He hecho commits y quiero guardarlos
Si has generado commits en estado Detached HEAD (por error o intencionadamente para probar un fix) y quieres conservarlos, debes crear una rama que apunte a ellos antes de irte.
Estando todavía en el estado Detached HEAD (sobre tu nuevo commit D), ejecuta:
git switch -c fix-antiguo
¿Qué ocurre internamente?
- Git crea una nueva etiqueta de rama llamada
fix-antiguopegada a tu commit actual (D). - Git reconecta HEAD a esta nueva rama.
Has convertido tus commits temporales en una línea de historia. Ahora puedes fusionar esa rama con main o seguir trabajando en ella con total seguridad.
