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?
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é .
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.
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.
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.
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.
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.
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.
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 .
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.
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
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.
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
.
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.
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.
Head pointe sur la pointe de la branche actuellement extraite.
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
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.
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:
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.
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")
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.
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.
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.