Introduzione
Normalmente HEAD punta a un ref di branch, che a sua volta punta a un commit. In detached HEAD, HEAD punta direttamente a un commit. Detached HEAD non è rotto; è una modalità deliberata utile per ispezionare la storia e pericolosa per committare senza pensare.
Come ci si arriva
git checkout v1.2.3
git switch --detach v1.2.3
git checkout HEAD~5
git checkout origin/main # il tracking remoto è quasi-read-only
Ognuno di questi mette HEAD direttamente su un commit invece che su un branch.
Ispezionare
cat .git/HEAD
# a1b2c3d4... (SHA grezzo, non "ref: ...")
git status
# HEAD detached at v1.2.3
Perché esiste
- Ispezionare una vecchia release senza influenzare alcun branch.
- Bisecting (
git bisectusa detached HEAD). - Costruire un esperimento veloce che potresti scartare.
- Operare su un tag che dovrebbe rimanere immutabile.
Committare in detached HEAD
Puoi committare in detached HEAD, e l'oggetto commit viene creato normalmente. Il problema: nessun branch lo punta. Cambia branch e il commit diventa irraggiungibile.
git switch --detach v1.2.3
echo fix > patch.txt
git add patch.txt
git commit -m "Quick fix"
git switch main # il nuovo commit è ora orfano
Ancoralo prima di cambiare:
git switch -c hotfix/1.2.4
Recuperare da un detach accidentale
Se sei già passato altrove, il reflog ha il commit:
git reflog
# a1b2c3d HEAD@{1}: commit: Quick fix
git switch -c hotfix/1.2.4 a1b2c3d
Quando detached HEAD non è detached
I repository bare hanno spesso HEAD come ref simbolico a refs/heads/main anche se non c'è una working tree. I submodule fanno anche intenzionalmente checkout in detached HEAD sul commit registrato; è normale.
Configurare gli avvisi
git config --global advice.detachedHead true # default: mostra consigli
I principianti dovrebbero lasciarlo attivo; il testo dell'avviso spiega esattamente come recuperare.
Lavorare in sicurezza mentre detached
Se vuoi intenzionalmente sperimentare senza influenzare alcun branch, detached HEAD è lo strumento giusto. Il trucco è ancorare il lavoro importante prima di cambiare. Un pattern affidabile:
git switch --detach v1.2.3
# ... sperimenta, committa ...
git tag tmp/experiment # segnalibro
git switch main
# dopo
git switch -c rescued tmp/experiment
git tag -d tmp/experiment
Il namespace di tag tmp/ rende ovvio che sono ancore usa-e-getta. Alcuni team riservano un intero prefisso per questo scopo e fanno ignorare alla CI.
Errori comuni
Trattare l'avviso come un errore spaventoso e farsi prendere dal panico. È informativo. Fare lavoro significativo in detached HEAD e poi eseguire git switch main senza prima creare un branch; recupera tramite reflog, ma meglio ancorare prima. Confondere detached HEAD con un repo corrotto; niente è corrotto, ti manca solo un'etichetta di branch. Infine, pushare mentre detached: git push ha bisogno di un branch su entrambe le estremità. O crea un branch locale e pushalo, o usa git push origin HEAD:refs/heads/new.