Introduzione
Un ref simbolico è un riferimento il cui valore è il nome di un altro ref piuttosto che un hash di oggetto. L'esempio canonico è HEAD, che di solito contiene ref: refs/heads/main. I ref simbolici permettono a Git di tracciare "il branch corrente" come dato, non come stato.
Lettura e scrittura
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 # cambia senza checkout
git symbolic-ref --short HEAD # forma corta: main
git symbolic-ref --delete refs/remotes/origin/HEAD
HEAD come ref simbolico
Quando fai commit, Git risolve HEAD per trovare il branch corrente e aggiorna la punta di quel branch. Quando HEAD è detached smette di essere simbolico e contiene uno SHA grezzo.
cat .git/HEAD
# ref: refs/heads/main (simbolico)
# vs dopo detach:
# a1b2c3d4... (grezzo)
HEAD remoto
Ogni remote può avere un HEAD simbolico che indica il suo branch predefinito. Imposta o ricarica:
git remote set-head origin --auto # interroga il server
git remote set-head origin main # imposta esplicitamente
git remote set-head origin --delete
Questo è ciò che fa risolvere git log origin a origin/main.
Perché usarli
- "Branch corrente" può cambiare senza riscrivere la storia.
- Gli strumenti possono chiedere "qual è il default?" senza hardcodare i nomi.
- Gli hook possono prendere di mira il branch attualmente checkoutato in modo generico.
Worktree e HEAD per worktree
Ogni worktree linkato (git worktree add) ha il proprio HEAD, memorizzato sotto .git/worktrees/<name>/HEAD. Ognuno può puntare a un branch diverso:
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
Rilevamento
git symbolic-ref -q HEAD && echo "su un branch" || echo "detached"
Rinominare il default
Per rinominare master in main in sicurezza:
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
Ispezionare la risoluzione simbolica
git rev-parse risolve un nome attraverso ref simbolici fino a uno SHA, mentre git symbolic-ref segue solo un livello. La coppia è utile per gli script:
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 quando vuoi il nome ref canonico indipendentemente da quale scorciatoia l'utente abbia digitato.
Errori comuni
Modificare .git/HEAD a mano e dimenticare la newline finale, lasciando Git incapace di parsarlo. Usa git symbolic-ref. Trattare refs/remotes/origin/HEAD come autoritario quando in realtà è cachato; aggiorna con git remote set-head origin --auto. Confondere un ref simbolico che punta a un branch mancante con un errore reale; git symbolic-ref -q esce con codice non-zero, che gli script possono gestire. Infine, cancellare il ref sottostante senza aggiornare quello simbolico, lasciando un symref dangling; gli strumenti possono segnalarlo ma è innocuo e facile da risolvere con un altro symbolic-ref.