Qu'est-ce que la tête dans git?


232

Il semble y avoir une différence entre le dernier commit, le HEAD et l'état du fichier que je peux voir dans mon répertoire.

Qu'est-ce que HEAD, que puis-je en faire et quelle erreur dois-je éviter?



1
À partir de Git v1.8.4, toutes les réponses ci-dessous utilisent HEADou headpeuvent désormais être utilisées @à la place HEAD. Voir cette réponse (dernière section) pour savoir pourquoi vous pouvez le faire.

3
De git-scm : Le HEAD dans Git est le pointeur vers la référence de branche actuelle, qui est à son tour un pointeur vers 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 d'y penser car HEAD est l'instantané de votre dernier commit.
Quazi Irfan

Réponses:


185

HEAD est une référence au dernier commit de la branche actuellement extraite.


Il y a une petite exception à cela, qui est la tête détachée. Un HEAD détaché est la situation dans laquelle vous vous retrouvez chaque fois que vous extrayez un commit (ou un tag) au lieu d'une branche. Dans ce cas, vous devez imaginer cela comme une branche temporaire sans nom; donc au lieu d'avoir une référence de branche nommée, nous n'avons que HEAD. Il vous permettra toujours de faire des commits (ce qui mettra à jour HEAD), donc la courte définition ci-dessus est toujours vraie si vous pensez à un HEAD détaché comme une branche temporaire sans nom.


1
Alors, pourquoi pouvez-vous avoir deux têtes?
e-satis

1
@ e-satis: parfois, vous verrez des branches appelées têtes - elles sont stockées dans refs/heads. HEADCependant, la tête en minuscules est différente de . Ma réponse clarifie un peu cela.
Cascabel

7
@ e-satis: Ce n'est pas regex. C'est ^juste la notation de git pour "le commit avant" - c'est le commit avant le courant. (Si le courant est une fusion, il utilise le premier parent.)
Cascabel

1
@ e-satis: Voir la section spécifiant les révisions de la page de manuel de git-rev-list pour plus d'informations sur toutes les façons de spécifier les commits - ce n'est qu'un tout petit morceau. kernel.org/pub/software/scm/git/docs/…
Cascabel

1
Non, lorsque rev et HEAD pointent vers le même commit, il n'y a pas de différence. Et vous pouvez même écrire l'ID de validation (la valeur SHA-1) au lieu de rev ou HEAD. Et ne vous inquiétez pas, vous ne nous harcelez pas avec les questions :) (moi au moins: P)
poke

87

HEAD est une référence (référence) au commit actuellement extrait.

Dans les états normaux, il s'agit en fait d'une référence symbolique à la branche que vous avez vérifiée - si vous regardez le contenu de .git / HEAD, vous verrez quelque chose comme "ref: refs / heads / master". La branche elle-même est une référence au commit à l'extrémité de la branche. Par conséquent, dans l'état normal,HEAD fait effectivement référence à la validation à la pointe de la branche actuelle.

Il est également possible d'avoir une "TÊTE détachée". Cela se produit lorsque vous extrayez quelque chose en plus d'une branche (locale), comme une branche distante, une validation spécifique ou une balise. L'endroit le plus courant pour voir cela est lors d'une rebase interactive, lorsque vous choisissez de modifier un commit. Dans l'état HEAD détaché, votre HEAD est une référence directe à un commit - le contenu de .git / HEAD sera un hachage SHA1.

D'une manière générale, HEAD est juste un nom pratique pour signifier "ce que vous avez vérifié" et vous n'avez pas vraiment à vous en préoccuper. Sachez simplement ce que vous avez vérifié et rappelez-vous que vous ne voulez probablement pas vous engager si vous n'êtes pas sur une branche (état HEAD détaché) à moins que vous ne sachiez ce que vous faites (par exemple, si vous êtes dans un rebase interactif) .


6
C'est quelque chose que je ne comprends pas. Si vous extrayez une succursale distante, pourquoi vous retrouvez-vous avec une "TÊTE détachée". Pourquoi ne sautez-vous pas automatiquement dans la branche de votre dépôt local correspondant à votre télécommande?
e-satis

3
@ e-satis: Si vous voulez la succursale locale, consultez la succursale locale. N'oubliez pas que les deux ne sont pas nécessairement les mêmes - vous devez dire au local de fusionner le distant (ou le tirer). Le suivi est juste pour qu'il sache lequel tirer automatiquement lorsque vous le demandez. La raison pour laquelle elle est détachée est que la branche distante est destinée à être un pointeur vers le dernier emplacement vu de la branche dans le référentiel distant. Si vous essayez de vous y engager, le dépôt distant ne change pas, donc la branche distante ne devrait pas non plus.
Cascabel

1
OK, c'est ce que je n'ai pas compris: avoir une branche locale nommée d'une manière n'implique pas qu'elle soit la même que la distante. Vraiment difficile à obtenir au début car je viens d'un milieu SVN :-) Merci mec. BTW, comment déplacez-vous un HEAD sans tête vers une branche locale pour le valider ici?
e-satis

3
@ e-satis: La réponse générale est git rebase <branch> HEAD. Cela trouvera le dernier ancêtre commun de <branch>et HEAD, puis prendra toutes les validations à partir de là HEADet les appliquera (les rebasera) <branch>. Il le fait essentiellement en les appliquant sous forme de correctifs, donc si les deux branches sont vraiment différentes, il pourrait y avoir des conflits. Mais si <branch>est un ancêtre de HEAD(c'est-à-dire que vous étiez au bon endroit, juste oublié que vous vous étiez détaché HEAD), le rebase n'est qu'une fusion rapide.
Cascabel

3
C'est l'une des descriptions les plus claires et précises de git HEAD que j'ai vues, après avoir cherché pendant un certain temps.
LarsH

21

J'ai toujours pensé que cela HEAD~5signifie GO à 5 commits avant. Mais il ne porte pas la partie GO de la commande. Il porte uniquement la référence / « où » une partie de la commande.

En termes simples, il est utilisé pour répondre à la question de: OERE dois-je aller? À quel engagement?

  • HEAD signifie (la référence au) commit en cours
  • HEAD~1 signifie (la référence à) 1 commit avant
  • HEAD~ Signifie également (la référence à) 1 commit avant
  • HEAD~87 signifie (la référence à) 87 commet avant

Usage:

  • git checkout HEAD~1 va effectivement aller / checkout à 1 commit / référence avant
  • git reset HEAD~3 va annuler vos 3 dernières validations - sans supprimer les modifications, c'est-à-dire que vous pouvez voir toutes les modifications apportées lors des 3 dernières validations ensemble, supprimer tout ce que vous n'aimez pas ou y ajouter, puis les valider à nouveau.
  • git reset --hard HEAD~3annulera votre dernier commit et supprimera leurs modifications . Il supprimera complètement ces modifications. Pour plus voir ici .
  • git diff HEAD~3 pour vérifier les changements dans les 3 derniers commits

3
revenant à ma propre réponse :)
Honey

15

Pointeur HEAD dans Git

Git maintient une variable de référence appelée HEAD. Et nous appelons cette variable un pointeur, car son but est de référencer ou de pointer vers une validation spécifique dans le référentiel. Au fur et à mesure que nous faisons de nouveaux commits, le pointeur va changer ou se déplacer pour pointer vers un nouveau commit. HEAD pointe toujours vers la pointe de la branche actuelle dans notre référentiel. Maintenant, cela a à voir avec notre référentiel, pas notre index de transfert, ou notre répertoire de travail.

Une autre façon de penser est le dernier état de notre référentiel ou ce qui a été extrait pour la dernière fois, et parce que c'est là que le référentiel s'est arrêté ou le dernier état, vous pouvez également dire que la HEAD pointe vers le parent du prochain commit ou c'est où l'écriture de validation va avoir lieu.

Je pense qu'une bonne métaphore pour y penser est la tête de lecture et d'enregistrement sur un magnétophone à cassettes. Lorsque nous commençons à enregistrer de l'audio, la bande passe devant la tête et elle enregistre dessus. lorsque nous appuyez sur Arrêter, l'endroit où cette tête d'enregistrement est arrêtée est l'endroit où l'enregistrement recommencera lorsque nous appuierons sur Record une deuxième fois. Maintenant, nous pouvons nous déplacer, nous pouvons déplacer la tête à différents endroits, mais partout où la tête est positionnée quand nous frappons à nouveau Record, c'est là que ça va commencer l'enregistrement.

Le pointeur HEAD dans Git est très similaire, il pointe vers l'endroit où nous allons commencer à enregistrer ensuite. C'est l'endroit où nous nous sommes arrêtés dans notre référentiel pour les choses que nous avons commises.


0

En termes simples, HEAD est une référence au dernier commit de la branche actuellement extraite.

Considérez la HEAD comme la "branche actuelle". Lorsque vous changez de branche avec git checkout, la révision HEAD change pour pointer vers la pointe de la nouvelle branche.

Vous pouvez voir ce que HEAD pointe en faisant:

cat .git/HEAD

Il est possible que HEAD fasse référence à une révision spécifique qui n'est pas associée à un nom de branche. Cette situation est appelée une tête détachée.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.