HEAD et ORIG_HEAD dans Git

252

À quoi se réfèrent ces symboles et que signifient-ils?

(Je ne trouve aucune explication dans la documentation officielle)

collimarco
la source
4
Remarque: HEADest maintenant (git1.8.4 à venir) ' @'! Voir ma réponse modifiée ci
VonC
Note-bis: ' @' (pour HEAD) est toujours à venir, mais pas pour la réponse 1.8.4 éditée et modifiée .
VonC
1
Note ter: ' @' for HEADest de retour pour git 1.8.5 / 1.9. réponse modifiée à nouveau .
VonC
21
HEADet ORIG_HEADdans Git sont comme $PWDet $OLDPWDdans Bash. :)
musiphil

Réponses:

325

HEADest une référence (directe ou indirecte, c'est-à-dire symbolique) au commit actuel. C'est un commit que vous avez vérifié dans le répertoire de travail (à moins que vous n'ayez apporté quelques modifications, ou équivalent), et c'est un commit au-dessus duquel "git commit" en ferait un nouveau. HEADEst généralement une référence symbolique à une autre branche nommée; cette branche est actuellement une branche extraite, ou branche actuelle. HEADpeut également pointer directement vers un commit; cet état est appelé "HEAD détaché" et peut être compris comme étant sur une branche anonyme et anonyme.

Et @seul est un raccourci pour HEAD, depuis Git 1.8.5

ORIG_HEADest l'état précédent de HEAD, défini par des commandes qui peuvent avoir un comportement dangereux, pour être facile à les rétablir. Il est moins utile maintenant que Git a reflog: HEAD@{1}est à peu près équivalent à ORIG_HEAD( HEAD@{1}est toujours la dernière valeur de HEAD, ORIG_HEADest la dernière valeur de HEADavant une opération dangereuse).

Pour plus d'informations, lisez la page de manuel git (1) , le manuel de l'utilisateur Git , le livre de la communauté Git et le glossaire Git

Jakub Narębski
la source
2
Salut Jakub. +1 pour l'explication. Pourriez-vous détailler la partie "à peu près équivalente" de HEAD @ {1}? Je me réfère dans ma réponse au fil thread.gmane.org/gmane.comp.version-control.git/38379 (vous y étiez, en février 2007), et je n'ai pas compris exactement la discussion que vous aviez autour la syntaxe @ {...}.
VonC
19
ORIG_HEAD est défini (je pense) uniquement par des commandes «dangereuses», qui déplacent HEAD plus d'un commit. Ainsi, ORIG_HEAD n'est pas toujours défini, tandis que HEAD @ {1} est toujours défini. @ {1} est $ (git symbolic-ref HEAD) @ {1}, c'est-à-dire qu'il utilise reflog pour la branche courante, pas HEAD reflog.
Jakub Narębski
Riiight ... Je comprends maintenant :) Merci pour cette précision. Pour ce que ça vaut, j'ai aussi voté pour votre commentaire!
VonC
1
"et HEAD est un commit au-dessus duquel" git commit "en ferait un nouveau." - bon à retenir, merci! Également à partir de @VonC, 'Il s'agit du build "git commit" construit par dessus, et "git diff --cached" et "git status" se comparent. "
Minqi Pan
1
git help revisions fait apparaître git-scm.com/docs/gitrevisions , qui décrit toutes les façons de référencer les validations (y compris HEADet ORIG_HEAD).
dahlbyk
104

Depuis git reset

"pull" ou "merge" laisse toujours la pointe d'origine de la branche courante dedans ORIG_HEAD.

git reset --hard ORIG_HEAD

Une réinitialisation difficile ramène votre fichier d'index et l'arborescence de travail à cet état et réinitialise la pointe de la branche à ce commit.

git reset --merge ORIG_HEAD

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


Avant d'appliquer des correctifs, ORIG_HEAD est défini sur la pointe de la branche actuelle.
Ceci est utile si vous avez des problèmes avec plusieurs validations, comme l'exécution de ' git am' sur la mauvaise branche ou une erreur dans les validations qui est plus facilement corrigée en changeant la boîte aux lettres (par exemple + erreurs dans les lignes "De:").

De plus, la fusion définit toujours « .git/ORIG_HEAD» à l'état d'origine de HEAD afin qu'une fusion problématique puisse être supprimée à l'aide de « git reset ORIG_HEAD».


Remarque: d' ici

HEAD est un pointeur en mouvement. Parfois, cela signifie la branche actuelle, parfois non.

Donc, HEAD n'est PAS déjà synonyme de "branche actuelle" partout.

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

Mais cela signifie presque toujours le "commit actuel".
Il s'agit du commit " git commit" construit sur, et " git diff --cached" et " git status" comparer.
Cela signifie la branche actuelle uniquement dans des contextes très limités (exactement quand nous voulons qu'un nom de branche fonctionne --- réinitialisation et croissance de la pointe de la branche via commit / rebase / etc.).

Reflog est un véhicule pour 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 nous trouvons MAINTENANT, puis découvrir où se trouvait la pointe 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, par exemple si j'avais" git show HEAD "à l'époque".


git1.8.4 (juillet 2013) présente introduit une nouvelle notation!
(en fait, ce sera pour 1.8.5 ou 1.9, Q4 2013: réintroduit avec commit 9ba89f4 )

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

Voir commit cdfd948

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

La raison du choix de ' @' est qu'il découle naturellement de la ref@opsyntaxe (par exemple HEAD@{u}), sauf que nous n'avons pas de référence, et aucune opération, et quand nous n'en avons pas, il est logique de supposer ' HEAD'.

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

Jusqu'à présent ' @' était un nom valide, mais il entre en conflit avec cette idée, alors rendons-le invalide. Probablement très peu de gens, le cas échéant, ont utilisé ce nom.


Un article de blog pendant la période 1.8.4-rc3 (14 août 2013) a annoncé que cette fonctionnalité avait été annulée et retardée (merci Cupcake pour le heads-up ).
Encore une fois, il est à nouveau introduit avec commit 9ba89f4 (sept. 2013).

Voir commit 2c2b664 :

Rétablir "Ajouter un nouveau @raccourci pour HEAD"

Ceci annule le commit cdfd948 , car il ne s'applique pas seulement à " @" (et aux formulaires avec des modificateurs comme @{u}appliqué à lui), mais affecte également par exemple " refs/heads/@/foo", ce qu'il ne devrait pas.

L'idée de base de donner un raccourci pourrait être bonne, et le sujet peut être réessayé plus tard, mais revenons pour éviter d'affecter les cas d'utilisation existants pour l'instant pour la prochaine version.

VonC
la source
Après avoir exécuté git, réinitialisez ORIG_HEAD et validez. ORIG_HEAD est toujours là sous Références à côté de HEAD. Pourquoi n'a-t-il pas été supprimé de la vue?
powder366
@ powder366 mais un git resetva générer un ORIG_HEAD. Vous devez donc le rmfaire manuellement. Voir stackoverflow.com/a/12418078/6309 par exemple.
VonC
1
@VonC, l' @alias de HEADest en cours de restauration (temporaire?) Pour la version Git 1.8.4 ! Cela vient d'être annoncé aujourd'hui!
Nous avons apprécié le commentaire "heads-up"!
Robino
2

Ma compréhension est que HEAD pointe la branche actuelle, tandis que ORIG_HEAD est utilisé pour stocker la précédente HEAD avant de faire des opérations "dangereuses".

Par exemple, git-rebase et git-am enregistrent la pointe de branche d'origine avant d'appliquer les modifications.

ynime
la source
4
HEAD ne pointe pas toujours sur la branche courante (elle peut être détachée)
VonC
1
Alors, quelle est la "branche actuelle" lorsque HEAD est "détaché"?
cjs
@ CurtJ.Sampson C'est "pas de branche". c'est pourquoi lorsque vous en tête détachée, vous le faites git branch foo -bafin de "créer" une branche pour que les orphelins les commettent.
Royi Namir
1

De man 7 gitrevisions:

HEAD nomme la validation sur laquelle vous avez basé les modifications dans l'arborescence de travail. FETCH_HEAD enregistre la branche que vous avez récupérée à partir d'un référentiel distant avec votre dernière invocation de git fetch. ORIG_HEAD est créé par des commandes qui déplacent votre HEAD de manière drastique, pour enregistrer la position de la HEAD avant leur opération, de sorte que vous pouvez facilement remettre la pointe de la branche dans l'état avant de la lancer. MERGE_HEAD enregistre les validations que vous fusionnez dans votre branche lorsque vous exécutez git merge. CHERRY_PICK_HEAD enregistre la validation que vous choisissez à la cerise lorsque vous exécutez git cherry-pick.

Nathan Chappell
la source