web-dev-qa-db-fra.com

Qu'est-ce que HEAD dans Git?

Vous voyez la documentation Git disant des choses comme

La branche doit être entièrement fusionnée dans HEAD.

Mais qu'est-ce que Git HEAD exactement?

930
bobobobo

Vous pouvez considérer le HEAD comme "la branche actuelle". Lorsque vous changez de branche avec git checkout, la révision HEAD change pour indiquer le bout de la nouvelle branche.

Vous pouvez voir sur quoi HEAD pointe en faisant:

cat .git/HEAD

Dans mon cas, le résultat est:

$ cat .git/HEAD
ref: refs/heads/master

HEAD peut faire référence à une révision spécifique non associée à un nom de branche. Cette situation s'appelle un HEAD détaché .

706
Greg Hewgill

Pour citer autres personnes :

Une tête est simplement une référence à un objet commit. Chaque tête a un nom (nom de branche ou nom de balise, etc.). Par défaut, il existe une tête dans chaque référentiel appelée maître. Un référentiel peut contenir un nombre quelconque de têtes. A tout moment, une tête est sélectionnée comme "tête actuelle". Cette tête est aliasée avec HEAD, toujours en majuscule ".

Notez cette différence: une “tête” (minuscule) fait référence à l’une des têtes nommées du référentiel; “HEAD” (majuscule) fait exclusivement référence à la tête actuellement active. Cette distinction est fréquemment utilisée dans la documentation Git.

Une autre bonne source couvrant rapidement le fonctionnement interne de git (et donc une meilleure compréhension des têtes/HEAD) peut être trouvée ici . Les références (réf :), têtes ou branches peuvent être considérées comme des post-it collés sur des commits dans l'historique des commits. Habituellement, ils désignent la pointe de la série de commits, mais ils peuvent être déplacés avec git checkout ou git reset etc.

167
Silfheed

Je recommande cette définition du développeur de github, Scott Chacon [ référence vidéo ]:

Head est votre branche actuelle. C'est une référence symbolique. C'est une référence à une branche. Vous avez toujours HEAD, mais HEAD désignera l'un de ces autres pointeurs, l'une des branches sur lesquelles vous vous trouvez. C'est le parent de votre prochain commit. C'est ce qui devrait être ce qui a été archivé pour la dernière fois dans votre répertoire de travail ... Ceci est le dernier état connu de votre répertoire de travail.

La vidéo entière donnera une bonne introduction au système Git, je vous recommande donc également de tout regarder si vous en avez le temps.

54
jasoares

HEAD est juste un pointeur spécial qui pointe vers la branche locale dans laquelle vous vous trouvez.

Du livre Pro Git , chapitre .1 Git Branching - Branches en bref , dans la section Création d'une nouvelle branche :

Que se passe-t-il si vous créez une nouvelle branche? Cela crée un nouveau pointeur pour que vous puissiez vous déplacer. Imaginons que vous créiez une nouvelle branche appelée testing. Vous faites cela avec la commande git branch:

$ git branch testing 

Cela crée un nouveau pointeur sur le même commit que vous êtes actuellement.

enter image description here

Comment Git sait-il sur quelle branche vous vous trouvez actuellement? Il conserve un pointeur spécial appelé HEAD. Notez que ceci est très différent du concept de HEAD dans d'autres VCS auxquels vous pourriez être habitué, tels que Subversion ou CVS. Dans Git, il s’agit d’un pointeur sur la branche locale dans laquelle vous vous trouvez. Dans ce cas, vous êtes toujours en master. La commande git branch a seulement créé une nouvelle branche - elle n’a pas basculé sur cette branche.

enter image description here

50
Alexandr

En supposant que ce ne soit pas un cas spécial appelé "tête détachée", alors, comme indiqué dans le livre de O'Reilly Git, 2e édition, p. 69, HEAD signifie:

HEAD fait toujours référence à la validation la plus récente de la branche actuelle. Lorsque vous changez de branche, HEAD est mis à jour pour faire référence à la dernière validation de la nouvelle branche.

alors

HEAD est le "conseil" de la branche actuelle.

Notez que nous pouvons utiliser HEAD pour faire référence à la dernière validation et utiliser HEAD~ comme validation avant, et HEAD~~ ou HEAD~2 encore plus tôt, et ainsi de suite.

36

HEAD fait référence au commit en cours sur lequel pointe votre copie de travail, c'est-à-dire au commit que vous avez emprunté. De la documentation officielle du noyau Linux sur la spécification des révisions Git :

HEAD nomme le commit sur lequel vous avez basé les modifications dans l'arborescence de travail.

Notez cependant que dans la version 1.8.4 à venir de Git, @ peut également être utilisé comme raccourci pour HEAD, comme noté par le contributeur de Git, Junio ​​C Hamano, dans Git Blame blog :

Au lieu de taper "HEAD", vous pouvez plutôt dire "@", par exemple. "git log @".

Stack Overflow utilisateur VonC en a également trouvé des informations intéressantes sur les raisons pour lesquelles @ a été choisi comme raccourci dans sa réponse à une autre question .

Il est également intéressant de noter que dans certains environnements, il n'est pas nécessaire de capitaliser HEAD, en particulier dans les systèmes d'exploitation qui utilisent des systèmes de fichiers ne respectant pas la casse, notamment Windows et OS X.

21
user456814

Jetez un coup d'œil à Créer et jouer avec des branches

HEAD est en fait un fichier dont le contenu détermine où la variable HEAD fait référence:

$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed

Dans ce référentiel, le contenu du fichier HEAD fait référence à un deuxième fichier nommé refs/heads/master . Le fichier refs/heads/master contient le hachage de la dernière validation sur la branche master.

Le résultat est HEAD pointe sur la validation de la branche principale à partir du fichier . Git/refs/heads/master .

enter image description here

16
onmyway133

Je voudrais juste détailler quelques points dans la réponse acceptée de Greg Hewgil. Selon le Git Pocket Guide

Branche:

la branche elle-même est définie comme étant tous les points accessibles dans le graphe de validation à partir de la validation nommée (la "pointe" de la branche).

HEAD: Un type de réf spécial

La référence spéciale HEAD détermine la branche sur laquelle vous vous trouvez ...

Refs

Git définit deux types de références, ou pointeurs nommés, qu’il appelle "refs":

  • Une simple référence, qui pointe directement sur un ID d'objet (généralement un commit ou une balise)
  • Une référence symbolique (ou symref), qui pointe vers une autre référence (simple ou symbolique)

Comme Greg l'a mentionné, HEAD peut être dans un "état détaché". Donc, HEAD peut être soit une simple référence (pour un HEAD détaché), soit un symref.

si HEAD est une référence symbolique pour une branche existante, alors vous êtes "sur" cette branche. Si, par contre, HEAD est une simple référence nommant directement un commit par son ID SHA-1, vous n'êtes pas "sur" une branche, mais plutôt en mode "détaché HEAD", ce qui se produit. lorsque vous extrayez une commande précédente à examiner.

14
mike

Il existe une idée fausse, peut-être subtile, mais importante dans nombre de ces réponses. Je pensais que j'ajouterais ma réponse pour clarifier les choses.

Qu'est-ce que HEAD?

HEAD c'est toi

HEAD est une référence symbolique pointant où que vous soyez dans votre historique de validation. Il vous suit partout où vous allez, quoi que vous fassiez, comme une ombre. Si vous faites un commit, HEAD sera déplacé. Si vous achetez quelque chose, HEAD sera déplacé. Quoi que vous fassiez, si vous avez déménagé quelque chose de nouveau dans votre historique de validation, HEAD a évolué avec vous. Pour répondre à une idée fausse commune: vous ne pouvez pas vous détacher de HEAD. Ce n'est pas ce qu'est un état détaché HEAD. Si jamais vous vous retrouvez en train de penser: "oh non, je suis en état détaché HEAD! J'ai perdu ma tête!" Rappelez-vous, c'est votre tête. HEAD c'est vous. Vous ne vous êtes pas détaché de la tête, votre HEAD s'est détaché de quelque chose d'autre.

À quoi HEAD peut-il s'attacher?

HEAD peut indiquer un commit, oui, mais généralement pas. Laissez-moi répéter ça. Typiquement, HEAD ne pointe pas vers une validation. Il pointe vers une référence de branche. Il est attaché à cette branche, et lorsque vous faites certaines choses (par exemple, commit ou reset ), la branche attachée se déplacera avec HEAD. Vous pouvez voir ce qu’il pointe en regardant sous le capot.

cat .git/HEAD

Normalement, vous obtiendrez quelque chose comme ceci:

ref: refs/heads/master

Parfois, vous obtenez quelque chose comme ça:

a3c485d9688e3c6bc14b06ca1529f0e78edd3f86

C'est ce qui se produit lorsque HEAD pointe directement sur un commit. Ceci s'appelle une HEAD détachée, parce que HEAD pointe vers autre chose qu'une référence de branche. Si vous faites un commit dans cet état, master, n'étant plus attaché à HEAD, ne se déplacera plus avec vous. Peu importe où se trouve ce commit. Vous pourriez être sur le même commit que votre branche principale, mais si HEAD pointe sur le commit plutôt que sur la branche, elle est détachée et un nouveau commit ne sera pas associé à une référence de branche.

Vous pouvez regarder cela graphiquement si vous essayez l'exercice suivant. Depuis un dépôt git, lancez ceci. Vous obtiendrez quelque chose de légèrement différent, mais leurs éléments clés seront là. Quand il est temps de vérifier directement la validation, utilisez simplement le hachage abrégé que vous obtenez de la première sortie (ici, il s'agit de a3c485d).

git checkout master
git log --pretty=format:"%h:  %d" -1
# a3c485d:   (HEAD -> master)

git checkout a3c485d -q # (-q is for dramatic effect)
git log --pretty=format:"%h:  %d" -1   
# a3c485d:   (HEAD, master)

OK, il y a donc une petite différence dans la sortie ici. L'extraction directe du commit (au lieu de la branche) nous donne une virgule au lieu d'une flèche. Que pensez-vous, sommes-nous dans un état détaché HEAD? HEAD fait toujours référence à une révision spécifique associée à un nom de branche. Nous sommes toujours sur la branche principale, n'est-ce pas?

Maintenant essaye:

git status
# HEAD detached at a3c485d

Nan. Nous sommes dans l'état 'détaché HEAD'.

Vous pouvez voir la même représentation de (HEAD -> branch) contre (HEAD, branch) avec git log -1.

En conclusion

HEAD c'est vous. Il pointe sur tout ce que vous avez vérifié, où que vous soyez. En règle générale, ce n'est pas un commit, c'est une branche. Si HEAD pointe sur un commit (ou une balise), même s'il s'agit de la même commit (ou balise) qu'une branche pointe également, vous (et HEAD) avez été détachés cette branche. Étant donné que vous ne possédez pas de branche, celle-ci ne vous suivra pas lorsque vous effectuez de nouveaux commits. HEAD, cependant.

9
De Novo

Je pense que 'HEAD' est l'actuel check out commit. En d'autres termes, 'HEAD' pointe vers le commit actuellement extrait.

Si vous venez de cloner et de ne pas accéder à votre compte, je ne sais pas à quoi il renvoie, probablement un emplacement non valide.

6
Nataraj

Head pointe sur la pointe de la branche actuellement extraite.

enter image description here

Dans votre référentiel, il y a un dossier .git. Ouvrez le fichier à cet emplacement: .git\refs\heads. Le code (sha-1) de ce fichier (maître dans la plupart des cas) sera la validation la plus récente, c'est-à-dire celle affichée dans le résultat de la commande git log. Plus d'informations sur le dossier .git: http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html

5
stack1

Un bon moyen de faire comprendre les bonnes réponses est de lancer git reflog HEAD, vous obtenez un historique de tous les endroits indiqués par HEAD.

4
tjb

Après avoir lu toutes les réponses précédentes, je voulais toujours plus de clarté. Ce blog sur le site officiel de git http://git-scm.com/blog m'a donné ce que je cherchais:

HEAD: pointeur sur le dernier instantané de commit, parent suivant

Le HEAD dans Git est le pointeur vers la référence de branche actuelle, qui est à son tour un pointeur sur le dernier commit que vous avez fait ou le dernier commit qui a été extrait dans votre répertoire de travail. Cela signifie également que ce sera le parent du prochain commit que vous ferez. Il est généralement plus simple de penser que HEAD est l’instantané de votre dernier commit.

4
user3751385

On a l'impression que HEAD n'est qu'un tag pour le dernier commit que vous avez emprunté.

Cela peut être la pointe d'une branche spécifique (telle que "maître") ou un commit intermédiaire d'une branche ("tête détachée")

2
Vertexwahn

Jetez un oeil à http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is

Figure 3-5. HEAD fichier pointant vers la branche sur laquelle vous vous trouvez.

0
Ting Wang

Ces deux peuvent vous dérouter:

tête

En pointant vers les références nommées, une branche récemment soumise. Sauf si vous utilisez la référence du paquet, les entêtes sont généralement stockées dans $ GIT_DIR/refs/heads /.

HEAD

La branche actuelle ou votre arbre de travail est généralement généré à partir de l’arbre pointé par HEAD. HEAD doit pointer vers une tête, sauf que vous utilisez une tête séparée.

0
Marcus Thornton

En plus de toutes les définitions, ce qui me tenait à l’esprit était que, lorsque vous effectuez une validation, GIT crée un objet de validation dans le référentiel. Les objets de validation doivent avoir un parent (ou plusieurs parents s'il s'agit d'un commit de fusion). Maintenant, comment git sait-il le parent du commit actuel? Donc, HEAD est un pointeur sur la (dernière référence) du dernier commit qui deviendra le parent du commit en cours.

0
Anwar Husain