La vérification de la balise Git conduit à «l'état HEAD détaché»

166

Je développe un script de déploiement pour mon projet git et je viens de commencer à utiliser des balises. J'ai ajouté une nouvelle balise appelée v2.0:

git tag -a v2.0 -m "Launching version 2.0"

Et j'ai poussé cette balise vers le référentiel distant

git push --tags

Lorsque j'essaie d'exécuter le script de déploiement et de vérifier la v2.0balise, je reçois ce message:

Vous êtes dans l'état «HEAD détaché». Vous pouvez regarder autour de vous, apporter des modifications expérimentales et les valider, et vous pouvez annuler toutes les validations que vous faites dans cet état sans affecter les branches en effectuant une autre extraction. Si vous souhaitez créer une nouvelle branche pour conserver les commits que vous créez, vous pouvez le faire (maintenant ou plus tard) en utilisant à nouveau -b avec la commande d'extraction. Exemple: git checkout -b new_branch_name HEAD est maintenant à

Est-ce normal? Le référentiel est dans les limbes car si je le fais:

git branch

J'obtiens cette sortie:

* (no branch)
  master

Désolé si cela est évident mais je n'ai pas pu le comprendre.

Khriz
la source
Quand vous dites, "exécutez le script de déploiement et vérifiez la v2.0" votre code ressemble-t-il à "git checkout v2.0"? J'essaie de réorganiser mon script de publication et lorsque j'exécute "git checkout v2.0" depuis ma machine de production, j'obtiens "error: pathspec 'v2.0' ne correspond à aucun fichier connu de git." Même si j'ai lancé "git push origin --tags" sur ma machine locale avant de faire le "git checkout v2.0" en production. J'ai aussi essayé d'exécuter "git pull --tags" et "git fetch --tags" en production avant d'appeler "git checkout v2.0" et cela ne fonctionne pas non plus ... Je reçois toujours le Erreur. Des idées?
John Erck
3
J'étais sur le point de supprimer le commentaire ci-dessus, mais je me suis dit que le garder pourrait aider quelqu'un d'autre. J'obtenais l'erreur parce que j'avais un TYPO dans mon nom de balise lorsque j'exécutais, "git checkout v2.0". Cependant, l'erreur liée à la faute de frappe est exactement la même que celle que vous obtiendrez si vous exécutez, "git checkout v2.0" SANS une faute de frappe AVANT de lancer, "git fetch --tags". Donc, finalement, mon problème a été résolu en exécutant, "git fetch --tags" AVANT de lancer, "git checkout v2.0" sans aucune faute de frappe. Phew!
John Erck
Bien, oui, vous devez faire fetch --tags avant (ou git fetch qui tirera tout de la télécommande) pour que git puisse extraire la balise. Désolé, je viens de voir votre commentaire aujourd'hui.
Khriz

Réponses:

429

D'accord, d'abord quelques termes un peu simplifiés.

Dans git, a tag(comme beaucoup d'autres choses) est ce qu'on appelle un arbre . C'est une façon de se référer à un moment de l'histoire du projet. Les arborescences peuvent être une balise, un commit, un spécificateur de date, un spécificateur ordinal ou bien d'autres choses.

Maintenant un branch est comme une balise mais est mobile. Lorsque vous êtes "sur" une branche et effectuez un commit, la branche est déplacée vers le nouveau commit que vous avez fait, indiquant sa position actuelle.

Votre HEADpointeur est sur une branche considérée comme "courante". Habituellement, lorsque vous clonez un référentiel, HEADpointera vers masterlequel à son tour pointera vers un commit. Lorsque vous faites ensuite quelque chose comme git checkout experimental, vous basculez le HEADpoint sur la experimentalbranche qui pourrait pointer vers un commit différent.

Maintenant l'explication.

Lorsque vous faites a git checkout v2.0, vous passez à un commit qui n'est pas pointé par un branch. Le HEADest maintenant "détaché" et ne pointe pas vers une branche. Si vous décidez de faire un commit maintenant (comme vous le pouvez), il n'y a pas de pointeur de branche à mettre à jour pour suivre ce commit. Revenir à un autre commit vous fera perdre ce nouveau commit que vous avez fait. C'est ce que le message vous dit.

Habituellement, ce que vous pouvez faire, c'est dire git checkout -b v2.0-fixes v2.0. Cela créera un nouveau pointeur de branche sur le commit pointé par le treeish v2.0(une balise dans ce cas), puis déplacera votre HEADpointeur vers cela. Maintenant, si vous faites des commits, il sera possible de les suivre (en utilisant la v2.0-fixesbranche) et vous pourrez travailler comme vous le feriez habituellement. Il n'y a rien de "mal" dans ce que vous avez fait, surtout si vous voulez juste jeter un œil au v2.0code. Si toutefois vous souhaitez y apporter des modifications que vous souhaitez suivre, vous aurez besoin d'une branche.

Vous devriez passer du temps à comprendre tout le modèle DAG de git. C'est étonnamment simple et rend toutes les commandes assez claires.

Noufal Ibrahim
la source
Ok merci, je n'ai pas besoin de faire de changements dans le code donc je pense que ça va. Je n'ai pas besoin de créer une branche. Merci beaucoup!
Khriz
1
J'étais perdu la première fois que j'ai regardé cette réponse mais après avoir lu la documentation de branchement de Git: http://git-scm.com/book/en/Git-Branching-What-a-Branch- Est- ce que c'était beaucoup plus clair .
mark stiles
3
Réponse géniale, mais puis-je ajouter à propos: "Revenir à un autre commit vous fera perdre ce nouveau commit que vous avez fait." - vous pouvez toujours trouver le commit dans git reflog, ce qui est une excellente commande à connaître! À moins qu'un garbage collection ne se soit produit, il est apparemment "impossible" de perdre un commit.
Dmitry Minkovsky
Les validations non référencées peuvent être perdues par une opération de garbage collection.
Noufal Ibrahim
1
L'URL est incorrecte car ils ont changé la mise en page de la page.
jcubic
12

Oui, c'est normal. C'est parce que vous extrayez un seul commit, qui n'a pas de tête. Surtout, ce n'est (tôt ou tard) aucun chef de branche.

Mais il n'y a généralement aucun problème avec cet état. Vous pouvez créer une nouvelle branche à partir de la balise, si cela vous rend plus en sécurité :)

KingCrunch
la source
1
Ok, je vais le garder ainsi ... la sécurité est surfaite de toute façon;)
Khriz
Comme vous l'avez commenté dans la réponse de Noufals (c'est la meilleure, je dois dire;)): Tant que vous ne changez rien, il n'y a rien dont vous ayez à vous inquiéter. Cependant, si vous supposez que vous pouvez changer quelque chose, vous pouvez simplement créer une branche, car elles sont bon marché dans git et vous pouvez la supprimer (et la recréer plus tard et ainsi de suite).
KingCrunch