Introducción
Una ref simbólica es una referencia cuyo valor es otro nombre de ref en lugar de un hash de objeto. El ejemplo canónico es HEAD, que normalmente contiene ref: refs/heads/main. Las refs simbólicas permiten a Git rastrear "el branch actual" como datos, no como estado.
Leyendo y escribiendo
git symbolic-ref HEAD
# refs/heads/main
git symbolic-ref refs/remotes/origin/HEAD
# refs/remotes/origin/main
git symbolic-ref HEAD refs/heads/feature/login # cambiar sin checkout
git symbolic-ref --short HEAD # forma corta: main
git symbolic-ref --delete refs/remotes/origin/HEAD
HEAD como ref simbólica
Cuando haces commit, Git resuelve HEAD para encontrar el branch actual y actualiza la punta de ese branch. Cuando HEAD está desconectado, deja de ser simbólica y contiene un SHA crudo.
cat .git/HEAD
# ref: refs/heads/main (simbólica)
# vs después de detach:
# a1b2c3d4... (crudo)
HEAD remoto
Cada remoto puede tener un HEAD simbólico indicando su branch predeterminado. Establecer o refrescar:
git remote set-head origin --auto # consultar al servidor
git remote set-head origin main # establecer explícitamente
git remote set-head origin --delete
Esto es lo que hace que git log origin resuelva a origin/main.
Por qué usarlas
- El "branch actual" puede cambiar sin reescribir el historial.
- Las herramientas pueden preguntar "¿cuál es el predeterminado?" sin codificar nombres.
- Los hooks pueden apuntar al branch actualmente checkeado de forma genérica.
Worktrees y HEAD por worktree
Cada worktree vinculado (git worktree add) tiene su propio HEAD, almacenado bajo .git/worktrees/<name>/HEAD. Cada uno puede apuntar a un branch diferente:
git worktree add ../wt-feature feature/login
cat ../wt-feature/.git
# gitdir: /path/to/main/.git/worktrees/wt-feature
cat .git/worktrees/wt-feature/HEAD
# ref: refs/heads/feature/login
Detección
git symbolic-ref -q HEAD && echo "on a branch" || echo "detached"
Renombrando el predeterminado
Para renombrar master a main de forma segura:
git branch -m master main
git symbolic-ref HEAD refs/heads/main
git push -u origin main
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
Inspeccionando la resolución simbólica
git rev-parse resuelve un nombre a través de refs simbólicas hasta un SHA, mientras que git symbolic-ref solo sigue un nivel. La pareja es útil para scripts:
git symbolic-ref HEAD # refs/heads/main
git symbolic-ref --short HEAD # main
git rev-parse HEAD # SHA
git rev-parse --symbolic-full-name HEAD # refs/heads/main
git rev-parse --symbolic-full-name @{u} # refs/remotes/origin/main
Usa --symbolic-full-name cuando quieras el nombre canónico de la ref sin importar qué atajo escribió el usuario.
Errores comunes
Editar .git/HEAD a mano y olvidar el salto de línea final, dejando a Git incapaz de parsearlo. Usa git symbolic-ref. Tratar refs/remotes/origin/HEAD como autoritativo cuando en realidad está cacheado; refresca con git remote set-head origin --auto. Confundir una ref simbólica que apunta a un branch faltante con un error real; git symbolic-ref -q sale con código distinto de cero, lo que los scripts pueden manejar. Finalmente, eliminar la ref subyacente sin actualizar la simbólica, dejando una symref colgante; las herramientas pueden reportarla pero es inofensiva y fácil de arreglar con otro symbolic-ref.