Introduction
Normalement, HEAD pointe vers une ref de branche, qui pointe à son tour vers un commit. En HEAD détaché, HEAD pointe directement vers un commit. Le HEAD détaché n'est pas cassé ; c'est un mode délibéré utile pour inspecter l'historique et dangereux pour commiter sans réfléchir.
Comment vous y arrivez
git checkout v1.2.3
git switch --detach v1.2.3
git checkout HEAD~5
git checkout origin/main # le tracking distant est lecture-seule-ish
Chacun de ceux-ci met HEAD directement sur un commit au lieu d'une branche.
Inspecter
cat .git/HEAD
# a1b2c3d4... (SHA brut, pas "ref: ...")
git status
# HEAD detached at v1.2.3
Pourquoi il existe
- Inspecter une ancienne release sans affecter aucune branche.
- Bisecter (
git bisectutilise HEAD détaché). - Construire une expérience rapide que vous pourrez jeter.
- Opérer sur un tag qui doit rester immobile.
Commiter en HEAD détaché
Vous pouvez commiter en HEAD détaché, et l'objet commit est créé normalement. Le hic : aucune branche ne pointe vers lui. Changez de branche et le commit devient inatteignable.
git switch --detach v1.2.3
echo fix > patch.txt
git add patch.txt
git commit -m "Quick fix"
git switch main # le nouveau commit est maintenant orphelin
Ancrez-le avant de changer :
git switch -c hotfix/1.2.4
Récupérer après détachement accidentel
Si vous avez déjà changé, le reflog a le commit :
git reflog
# a1b2c3d HEAD@{1}: commit: Quick fix
git switch -c hotfix/1.2.4 a1b2c3d
Quand le HEAD détaché n'est pas détaché
Les dépôts nus ont souvent HEAD comme ref symbolique vers refs/heads/main même s'il n'y a pas d'arborescence de travail. Les sous-modules font aussi intentionnellement un checkout en HEAD détaché sur le commit enregistré ; c'est normal.
Configurer les avertissements
git config --global advice.detachedHead true # défaut : afficher le conseil
Les débutants devraient laisser cela activé ; le texte d'avertissement explique exactement comment récupérer.
Travailler en sécurité en détaché
Si vous voulez intentionnellement expérimenter sans affecter aucune branche, le HEAD détaché est le bon outil. L'astuce est d'ancrer le travail important avant de changer. Un motif fiable :
git switch --detach v1.2.3
# ... expérimenter, commiter ...
git tag tmp/experiment # signet
git switch main
# plus tard
git switch -c rescued tmp/experiment
git tag -d tmp/experiment
Le namespace de tags tmp/ rend évident que ce sont des ancres jetables. Certaines équipes réservent un préfixe entier à cet usage et font ignorer ce préfixe par la CI.
Erreurs fréquentes
Traiter l'avertissement comme une erreur effrayante et paniquer. C'est informatif. Faire un travail important en HEAD détaché puis exécuter git switch main sans créer une branche d'abord ; récupérez via le reflog, mais mieux vaut ancrer d'abord. Confondre HEAD détaché avec un dépôt corrompu ; rien n'est corrompu, vous manquez juste d'une étiquette de branche. Enfin, pousser en détaché : git push a besoin d'une branche aux deux extrémités. Soit créez une branche locale et poussez-la, soit utilisez git push origin HEAD:refs/heads/new.