Pourquoi mon dépôt Git est-il entré dans un état HEAD détaché?

387

Je me suis retrouvé avec une tête détachée aujourd'hui, le même problème que celui décrit dans: git push dit que tout est à jour même si j'ai des changements locaux

Pour autant que je sache, je n'ai rien fait hors de l'ordinaire, juste des commits et des push de mon repo local.

Alors, comment ai-je fini avec un detached HEAD?

Adam Bergmark
la source
18
Vérifier une branche distante semble être le moyen le plus courant de le faire accidentellement; une autre façon courante consiste à vérifier branch-name@{n}, la nième position précédente de branch-name. Mais quoi qu'il en soit, à un moment donné, il devait y avoir un git checkout <rev>. Si cela ne vous dit rien, alors vous avez probablement fait ce que Will a mentionné - essayé de faire git checkout <file>et réussi à spécifier une révision par accident.
Cascabel
3
Pour annuler un état HEAD détaché, voir Réparer une tête détachée Git? .
Mon dépôt s'est retrouvé dans cet état lorsque des conflits ont été rencontrés lors du rebasage. Heureusement Git m'a dit quoi faire quand j'ai couru git status:all conflicts fixed: run "git rebase --continue"
Paul
2
Se produit également si vous tapez accidentellement git checkout remotes/origin/my-branchau lieu de git checkout my-branchou git checkout origin/my-branch.
Adam Libuša
@adam Libusa, merci cela a fonctionné pour moi. Quelle est la différence entre les télécommandes git checkout / origin / my-branch et git checkout my-branch. N'est-ce pas pareil. mais ce que vous avez dit a fonctionné pour moi. Par curiosité, je demande.
karunakar bhogyari

Réponses:

281

Toute extraction d'un commit qui n'est pas le nom d'une de vos succursales vous donnera un HEAD détaché. Un SHA1 qui représente la pointe d'une branche donne toujours une TETE détachée. Seule une extraction d'un nom de branche locale évite ce mode.

Voir l' engagement avec une HEAD détachée

Lorsque HEAD est détaché, le travail est validé comme d'habitude, sauf qu'aucune branche nommée n'est mise à jour. (Vous pouvez considérer cela comme une branche anonyme.)

texte alternatif

Par exemple, si vous extrayez une "branche distante" sans la suivre au préalable, vous pouvez vous retrouver avec une TETE détachée.

Voir git: changer de branche sans détacher la tête


Avec Git 2.23 (août 2019), vous n'avez plus besoin d'utiliser la commande déroutantegit checkout .

git switch peut également extraire une branche et obtenir un détachement HEAD, sauf:

  • il a une --detachoption explicite

Pour vérifier la validation HEAD~3pour une inspection ou une expérience temporaire sans créer de nouvelle branche:

git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
  • il ne peut pas détacher par erreur une branche de suivi à distance

Voir:

C:\Users\vonc\arepo>git checkout origin/master
Note: switching to 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

Contre. en utilisant la nouvelle git switchcommande:

C:\Users\vonc\arepo>git switch origin/master
fatal: a branch is expected, got remote branch 'origin/master'

Si vous vouliez créer une nouvelle branche locale suivant une branche distante:

git switch <branch> 

Si <branch>n'est pas trouvé mais qu'il existe une branche de suivi dans exactement une télécommande (appelez-la <remote>) avec un nom correspondant, traitez comme équivalent à

git switch -c <branch> --track <remote>/<branch>

Plus d'erreur!
Plus de tête détachée indésirable!

VonC
la source
12
Vous pouvez également entrer dans l'état de tête détachée si vous êtes au milieu d'un rebase interactif et que vous souhaitez modifier l'un des validations. Lorsque Git vous dépose lors de la validation de la modification, vous serez dans un état de tête détachée jusqu'à ce que vous ayez terminé le rebase.
Dans ce guide visuel, il y a cette explication: git commit files creates a new commit containing the contents of the latest commit, plus a snapshot of files taken from the working directory. Additionally, files are copied to the stage.Qu'est-ce que cela signifie par «les fichiers sont copiés sur la scène»? Je pensais que les fichiers étaient validés, ce qui signifie que la scène est effacée?
max
16
En fait, vous obtiendrez un HEAD détaché chaque fois que vous extrayez un commit par son SHA1, qu'il soit ou non à la pointe d'une branche; le seul type de chose que vous pouvez commander sans obtenir un HEAD détaché est un nom de branche. Par exemple, même si masterest ed489sur le diagramme ci-dessus, git checkout ed489vous donnera une tête détachée, tandis que git checkout masterce ne sera pas le cas.
musiphil
8
"You can think of this as an anonymous branch":) J'aime l'analogie
Adrien Be
118

Je l'ai reproduit tout à l'heure par accident:

  1. répertorie les branches distantes

    git branch -r
          origin/Feature/f1234
          origin/master
    
  2. Je veux en commander un localement, donc je coupe la pâte:

    git checkout origin/Feature/f1234
    
  3. Presto! État HEAD détaché

    You are in 'detached HEAD' state. [...])
    

Solution n ° 1:

N'incluez pas origin/à l'avant de mes spécifications de succursale lors de la vérification:

git checkout Feature/f1234

Solution n ° 2:

Ajouter un -bparamètre qui crée une branche locale à distance

git checkout -b origin/Feature/f1234 ou

git checkout -b Feature/f1234 il retombera automatiquement à l'origine

Owen
la source
14
C'est presque une excellente réponse, mais ne parvient pas à expliquer pourquoi vous êtes entré dans un état de tête détaché.
Goose
5
Je suis d'accord mais cela fournit la solution que je cherchais. Merci!!
Kilmazing
J'ai vu dans cette autre réponse que git checkout -b Feature/f1234<=> git branch Feature/f1234et git checkout Feature/f1234.
Armfoot
1
par défaut, il regarde à l'origine, donc quand vous donnez origin/branchname, il cherche origin/origin/branchnameà dire que le premier est le nom distant que vous utilisez -b, sinon vous créez une anonymousbranche qui est détachée. De même, pour vérifier à partir d'une autre télécommande, vous devez mentionner un -bparamètre, sinon git n'a aucun moyen de le savoir à partir d'une nouvelle télécommande, il cherchera origin/remote/branchname.
garg10mai
Tu es un saint!
Harvey Lin
12

essayer

git reflog 

cela vous donne un historique de la façon dont vos pointeurs HEAD et branch ont été déplacés dans le passé.

par exemple :

88ea06b HEAD @ {0}: paiement: passage du DÉVELOPPEMENT aux télécommandes / origine / SomeNiceFeature e47bf80 HEAD @ {1}: tirer l'origine DÉVELOPPEMENT: Avance rapide

le haut de cette liste est une raison pour laquelle on pourrait rencontrer un état DETACHED HEAD ... en vérifiant une branche de suivi à distance.

André R.
la source
7

Cela peut facilement se produire si vous essayez d'annuler les modifications que vous avez apportées en retirant à nouveau les fichiers et en n'obtenant pas tout à fait la bonne syntaxe.

Vous pouvez regarder la sortie de git log- vous pouvez coller la queue du journal ici depuis le dernier commit réussi, et nous pourrions tous voir ce que vous avez fait. Ou vous pouvez le coller et le demander joliment #gitsur l'IRC de freenode.

Volonté
la source
5

Cela peut arriver si vous avez une balise portant le même nom qu'une branche.

Exemple: si "release / 0.1" est le nom de la balise, alors

git checkout release/0.1

produit une tête détachée à "libération / 0,1". Si vous vous attendez à ce que release / 0.1 soit un nom de branche, vous vous trompez.

radzimir
la source
1
Oui. Mais comment y remédier? Comment faites-vous pour passer à la caisse?
Martin
5

Detached HEAD signifie que ce qui est actuellement extrait n'est pas une branche locale.

Quelques scénarios qui aboutiront à un Detached HEADétat:

  • Si vous réglez une succursale distante , par exemple origin/master. Il s'agit d'une branche en lecture seule. Ainsi, lors de la création d'un commit à partir de origin/mastercelui-ci, il flottera librement , c'est -à- dire qu'il ne sera connecté à aucune branche.

  • Si vous extrayez une balise ou un commit spécifique . Lorsque vous effectuez un nouveau commit à partir d'ici, il sera à nouveau flottant , c'est -à- dire qu'il n'est connecté à aucune branche. Notez que lorsqu'une branche est extraite, les nouvelles validations sont toujours automatiquement placées à l'extrémité.

    Lorsque vous souhaitez revenir en arrière et extraire une validation ou une balise spécifique pour commencer à travailler à partir de là, vous pouvez créer une nouvelle branche provenant de cette validation et y basculer git checkout -b new_branch_name. Cela empêchera l' Detached HEADétat car vous avez maintenant une branche extraite et non un commit.

Tim Skov Jacobsen
la source
3

Un moyen accidentel simple consiste à faire une git checkout headcomme une faute de frappe HEAD.

Essaye ça:

git init
touch Readme.md
git add Readme.md
git commit
git checkout head

qui donne

Note: checking out 'head'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 9354043... Readme
Thomas Weller
la source
Également mentionné dans longair.net/blog/2012/05/07/the-most-confusing-git-terminology (recherchez "" HEAD "et" head "")
VonC
@VonC: merci pour ce lien. Je prépare une formation Git et je veux aussi souligner pourquoi c'est parfois si déroutant. J'ai déjà beaucoup d'exemples (comme checkout -bqui ressemble à une caisse mais en fait des branches) mais une autre liste est juste la bienvenue.
Thomas Weller
2

L'autre façon d'entrer dans un état de tête détachée git est d'essayer de valider sur une branche distante. Quelque chose comme:

git fetch
git checkout origin/foo
vi bar
git commit -a -m 'changed bar'

Notez que si vous faites cela, toute autre tentative de vérification de l'origine / foo vous ramènera dans un état de tête détaché!

La solution consiste à créer votre propre branche foo locale qui suit l'origine / foo, puis éventuellement à pousser.

Cela n'a probablement rien à voir avec votre problème d'origine, mais cette page est en haut des hits google pour "git détaché tête" et ce scénario est gravement sous-documenté.

dspeyer
la source
Cette situation semble être ce dont parle la réponse d'Owen ci-dessus - où couper et coller "origine / foo" fait penser à git comme "origine / origine / foo".
mvanle
1

Lorsque vous passez à un commit git checkout <commit-hash>ou à une branche distante, votre HEAD se détache et essaie de créer un nouveau commit dessus.

Les validations qui ne sont accessibles par aucune branche ou balise seront récupérées et supprimées du référentiel après 30 jours.

Une autre façon de résoudre ce problème consiste à créer une nouvelle branche pour la validation nouvellement créée et à la retirer. git checkout -b <branch-name> <commit-hash>

Cet article explique comment accéder à l' état HEAD détaché .

Nesha Zoric
la source