293 votes

HEAD et ORIG_HEAD dans Git

À quoi ces symboles font-ils référence et que signifient-ils ?

(Je ne trouve pas d'explication dans la documentation officielle)

5 votes

Note : HEAD est maintenant (à venir dans git1.8.4) ' @ ' ! Voir ma réponse éditée ci-dessous

0 votes

Note-bis : ' @ (pour HEAD ) est toujours disponible, mais pas pour la version 1.8.4. réponse éditée et modifiée .

2 votes

Note ter : @ pour HEAD est de retour pour git 1.8.5/1.9. réponse éditée à nouveau .

369voto

Jakub Narębski Points 87537

HEAD est une référence (directe ou indirecte, c'est-à-dire symbolique) au commit courant. C'est un commit que vous avez vérifié dans le répertoire de travail (à moins que vous n'ayez fait des changements, ou équivalent), et c'est un commit sur lequel "git commit" en ferait un nouveau. Habituellement, HEAD est une référence symbolique à une autre branche nommée ; cette branche est la branche actuellement extraite, ou la branche actuelle. HEAD peut aussi pointer directement vers un commit ; cet état est appelé "detached HEAD", et peut être compris comme étant sur une branche anonyme sans nom.

Et @ seul est un raccourci pour HEAD depuis Git 1.8.5

ORIG_HEAD est l'état précédent de HEAD définis par les commandes qui ont un comportement potentiellement dangereux, afin de pouvoir les inverser facilement. Il est moins utile maintenant que Git dispose de reflog : HEAD@{1} est à peu près équivalent à ORIG_HEAD ( HEAD@{1} est toujours la dernière valeur de HEAD , ORIG_HEAD est la dernière valeur de HEAD avant toute opération dangereuse).

Pour plus d'informations, lisez Page de manuel git(1) / [page de manuel de gitrevisions(7)] [git-revisions], Manuel de l'utilisateur de Git le Livre de la communauté Git y Glossaire Git

2 votes

Salut Jakub. +1 pour l'explication. Pourriez-vous détailler la partie "grossièrement équivalente" de HEAD@{1} ? Je fais référence dans ma réponse au fil de discussion thread.gmane.org/gmane.comp.version-control.git/38379 (vous y étiez, en février 2007), et je n'ai pas vraiment compris la discussion que vous avez eue autour de la syntaxe @{...}.

24 votes

ORIG_HEAD n'est activé (je pense) que par des commandes 'dangereuses', qui déplacent HEAD de plus d'un commit. Donc ORIG_HEAD n'est pas toujours activé, alors que HEAD@{1} est toujours activé. @{1} est $(git symbolic-ref HEAD)@{1}, c'est-à-dire qu'il utilise le reflog de la branche courante, et non le reflog de HEAD.

0 votes

Riiight... Je comprends maintenant :) Merci pour cette clarification. Pour ce que ça vaut, j'ai aussi upvoted votre commentaire !

127voto

VonC Points 414372

Desde git reset

"pull" ou "merge" laisse toujours l'extrémité originale de la branche courante en ORIG_HEAD .

git reset --hard ORIG_HEAD

La réinitialisation du commit ramène votre fichier d'index et l'arbre de travail à cet état, et réinitialise l'extrémité de la branche à ce commit.

git reset --merge ORIG_HEAD

Après avoir inspecté le résultat de la fusion, vous pouvez trouver que le changement dans l'autre branche n'est pas satisfaisant. Exécution " git reset --hard ORIG_HEAD " vous permettra de revenir là où vous étiez, mais il supprimera vos modifications locales, ce que vous ne voulez pas. " git reset --merge " conserve vos modifications locales.


Avant l'application de tout correctif, ORIG_HEAD est défini à l'extrémité de la branche courante.
Ceci est utile si vous avez des problèmes avec des commits multiples, comme l'exécution de ' git am ' sur la mauvaise branche ou une erreur dans les commits qui est plus facilement corrigée en changeant la boîte aux lettres (par exemple +erreurs dans les lignes "From :").

En outre, Merge définit toujours ' .git/ORIG_HEAD ' à l'état original de HEAD afin qu'une fusion problématique puisse être supprimée en utilisant ' git reset ORIG_HEAD '.


Note : de aquí

HEAD est un pointeur mobile. Parfois il désigne la branche courante, parfois non.

Ainsi, HEAD est PAS un synonyme de "branche actuelle" partout déjà.

HEAD signifie "actuel" partout dans git, mais cela ne signifie pas nécessairement "branche actuelle" (c'est-à-dire HEAD détaché).

Mais cela signifie presque toujours le "commit actuel".
Il s'agit de l'engagement " git commit "se construit par-dessus, et " git diff --cached " et " git status " comparer avec.
Il ne signifie la branche courante que dans des contextes très limités (exactement quand nous voulons un nom de branche pour opérer sur --- réinitialisation et croissance de la pointe de la branche via commit/rebase/etc.).

Reflog est un véhicule permettant de remonter le temps et les machines à remonter le temps ont une interaction intéressante avec la notion de "courant".

HEAD@{5.minutes.ago} pourrait signifier "déréférencer HEAD symref pour savoir sur quelle branche nous sommes MAINTENANT, et ensuite trouver où se trouvait l'extrémité de cette branche il y a 5 minutes".
Alternativement, cela pourrait signifier "Quel est le commit que j'aurais appelé HEAD il y a 5 minutes ? minutes auparavant, par exemple si j'avais fait "git show HEAD" à ce moment-là".


git1.8.4 (juillet 2013) présente introduit une nouvelle notation !
(En fait, ce sera pour la 1.8.5, Q4 2013 : réintroduite avec commettre 9ba89f4 ), par Felipe Contreras .

Au lieu de taper quatre lettres majuscules " HEAD ", vous pouvez dire " @ " maintenant,
Par exemple, " git log @ ".

Voir commettre cdfd948

Taper HEAD ' est fastidieux, surtout quand on peut utiliser ' @ à la place.

La raison du choix de ' @ est qu'elle découle naturellement de la ref@op syntaxe (par exemple HEAD@{u} ), sauf que nous n'avons pas de ref, ni d'opération, et quand nous n'avons pas ces éléments, il est logique de supposer que ' HEAD '.

Nous pouvons donc maintenant utiliser ' git show @~1 ', et toutes ces bonnes choses.

Jusqu'à maintenant. @ était un nom valide, mais il est en conflit avec cette idée, alors rendons-le invalide. Il est probable que très peu de personnes, voire aucune, n'utilisaient ce nom.

0 votes

Après avoir lancé git reset ORIG_HEAD et commit. ORIG_HEAD est toujours là sous Références à côté de HEAD. Pourquoi n'a-t-il pas été supprimé de la vue ?

0 votes

@powder366 mais un git reset générera un ORIG_HEAD . Vous devez donc rm manuellement. Voir stackoverflow.com/a/12418078/6309 par exemple.

1 votes

@VonC le @ alias pour HEAD est en train de rétabli (temporairement ?) pour la version 1.8.4 de Git ! Elle vient d'être annoncée aujourd'hui !

5voto

Nathan Chappell Points 316

Desde man 7 gitrevisions :

HEAD nomme le commit sur lequel vous avez basé les changements dans le fichier arbre de travail. FETCH_HEAD enregistre la branche que vous avez récupérée d'un dépôt distant avec votre dernière invocation de git fetch. ORIG_HEAD est créé par des commandes qui déplacent votre HEAD d'une de manière drastique, afin d'enregistrer la position du HEAD avant leur opération, afin que vous puissiez facilement changer la pointe de la branche à l'état antérieur à leur exécution. MERGE_HEAD enregistre le(s) commit(s) que vous fusionnez dans votre branche lorsque vous exécutez git merge. CHERRY_PICK_HEAD enregistre le commit que vous êtes en train de cherry-pick lorsque vous exécutez git cherry-pick.

2voto

ynimous Points 536

D'après ce que j'ai compris, HEAD indique la branche actuelle, tandis que ORIG_HEAD est utilisé pour stocker le HEAD précédent avant d'effectuer des opérations "dangereuses".

Par exemple, git-rebase et git-am enregistrent l'extrémité originale de la branche avant d'appliquer des modifications.

4 votes

HEAD ne pointe pas toujours sur la branche courante (il peut être détaché)

2 votes

Alors qu'est-ce que la "branche actuelle" quand HEAD est "détaché" ?

0 votes

@CurtJ.Sampson C'est "pas de branche". C'est pourquoi quand vous êtes dans la tête détachée, vous faites git branch foo -b afin de "créer" une branche pour les commits de cet orphelin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X