Lorsque je spécifie un objet de validation d'ancêtre dans Git, je suis confus entre HEAD^
et HEAD~
.
Les deux ont une version "numérotée" comme HEAD^3
et HEAD~2
.
Ils me semblent très similaires ou identiques, mais y a-t-il des différences entre le tilde et le caret?
Réponses:
Règles de base
~
plupart du temps - pour remonter un certain nombre de générations, généralement ce que vous voulez^
lors des validations de fusion - parce qu'ils ont deux parents (immédiats) ou plusMnémotechnique:
~
est presque linéaire en apparence et veut reculer en ligne droite^
suggère un segment intéressant d'un arbre ou d'une fourche sur la routeTilde
La section «Spécification des révisions» de la
git rev-parse
documentation définit~
commeVous pouvez contacter les parents de n'importe quel engagement, pas seulement
HEAD
. Vous pouvez également revenir en arrière à travers les générations: par exemple,master~2
signifie le grand-parent de la pointe de la branche principale, favorisant le premier parent lors des validations de fusion.Caret
L'histoire de Git est non linéaire: un graphique acyclique dirigé (DAG) ou un arbre. Pour un commit avec un seul parent,
rev~
etrev^
signifie la même chose. Le sélecteur de curseur devient utile avec les validations de fusion, car chacun est l'enfant de deux parents ou plus - et le langage des souches emprunté à la biologie.HEAD^
signifie le premier parent immédiat de la pointe de la branche actuelle.HEAD^
est l'abréviation deHEAD^1
, et vous pouvez également adresserHEAD^2
et ainsi de suite, le cas échéant. La même section de lagit rev-parse
documentation le définit commeExemples
Ces spécificateurs ou sélecteurs peuvent être chaînés arbitrairement, par exemple ,
topic~3^2
en anglais est le deuxième parent du commit de fusion qui est l'arrière-grand-parent (trois générations en arrière) de la pointe actuelle de la branchetopic
.La section susmentionnée de la
git rev-parse
documentation trace de nombreux chemins à travers une histoire git théorique. Le temps s'écoule généralement vers le bas. Les validations D, F, B et A sont des validations de fusion.Exécutez le code ci-dessous pour créer un référentiel git dont l'historique correspond à l'illustration citée.
Il ajoute des alias dans le nouveau référentiel jetable uniquement pour
git lol
etgit lola
vous pouvez donc afficher l'historique comme dansNotez que sur votre machine, les noms des objets SHA-1 seront différents de ceux ci-dessus, mais les balises vous permettent d'adresser les commits par nom et de vérifier votre compréhension.
La «Spécification des révisions» dans la
git rev-parse
documentation regorge d'informations utiles et mérite une lecture approfondie. Voir aussi Git Tools - Revision Selection dans le livre Pro Git .Ordre des engagements des parents
Le commit 89e4fcb0dd de la propre histoire de git est un commit de fusion, comme l'
git show 89e4fcb0dd
indique la ligne d'en-tête Merge qui affiche les noms des objets des ancêtres immédiats.Nous pouvons confirmer la commande en demandant
git rev-parse
de montrer les parents immédiats de 89e4fcb0dd dans l'ordre.L'interrogation du quatrième parent inexistant entraîne une erreur.
Si vous souhaitez extraire uniquement les parents, utilisez un joli format
%P
pour les hachages completsou
%p
pour les parents abrégés.la source
^^^^^^^
place de~7
, n'est-ce pas? C'est pourquoi~
est utileLa différence entre
HEAD^
etHEAD~
est bien décrite par l'illustration (par Jon Loeliger) trouvée sur http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html .Cette documentation peut être un peu obscure pour les débutants, j'ai donc reproduit cette illustration ci-dessous:
la source
F = A^2^
.^ == ^1 == LEFTMOST PARENT
,^2 == SECOND LEFTMOST PARENT
et ainsi de suite. Et~ == ~1 == LEFTMOST PARENT
,~2 == LEFTMOST PARENTS LEFTMOST PARENT == LEFTMOST GRANDPARENT
. Par extension,~2^2 == LEFTMOST GRANDPARENTS SECOND LEFTMOST PARENT
Les deux
~
et^
par eux-mêmes se réfèrent au parent de la validation (~~
et les^^
deux se réfèrent à la validation des grands-parents, etc.) Mais ils ont une signification différente lorsqu'ils sont utilisés avec des nombres:~2
signifie monter de deux niveaux dans la hiérarchie , via le premier parent si un commit a plus d'un parent^2
signifie le deuxième parent où un commit a plus d'un parent (c'est-à-dire parce que c'est une fusion)Ceux-ci peuvent être combinés, donc
HEAD~2^3
signifieHEAD
le troisième commit parent du commit grand-parent.la source
^^
c'était la même chose^2
mais ce n'est pas le cas.Mes deux centimes...
la source
H=A~2^2
pasH=A~2^1
?A
,B
,D
,G
sont sur la même branche et la commettrasD
est une fusion deG
etH
, ayant donc deux parents. Ainsi, le commit (H
) d'une autre branche est référencé par^2
.Voici une très bonne explication reprise textuellement de http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde :
la source
Le
^<n>
format vous permet de sélectionner le nième parent du commit (pertinent dans les fusions). Le~<n>
format vous permet de sélectionner le nième commit ancêtre, toujours en suivant le premier parent. Voir la documentation de git-rev-parse pour quelques exemples.la source
Il convient de noter que git a également une syntaxe pour suivre "d'où-vous-êtes venu" / "voulez-vous-revenir-maintenant" - par exemple,
HEAD@{1}
fera référence à l'endroit d'où vous avez sauté vers le nouvel emplacement de validation.Fondamentalement, les
HEAD@{}
variables capturent l'historique du mouvement HEAD, et vous pouvez décider d'utiliser une tête particulière en consultant les reflogs de git à l'aide de la commandegit reflog
.Exemple:
Un exemple pourrait être que j'ai fait des commits locaux a-> b-> c-> d puis que je suis retourné en rejetant 2 commits pour vérifier mon code -
git reset HEAD~2
- et ensuite que je veux ramener mon HEAD sur d -git reset HEAD@{1}
.la source
Simplement :
~
spécifie les ancêtres^
précise les parentsVous pouvez spécifier une ou plusieurs branches lors de la fusion. Ensuite, un commit a deux parents ou plus et
^
est ensuite utile pour indiquer les parents.Supposons que vous êtes sur la branche A et vous avez deux branches: B et C .
Sur chaque branche, les trois derniers commits sont:
Si maintenant sur la branche A, vous exécutez la commande:
alors vous combinez trois branches ensemble (ici votre commit de fusion a trois parents)
et
~
indique le nième ancêtre dans la première branche, doncHEAD~
indique A3HEAD~2
indique A2HEAD~3
indique A1^
indique le nième parent, doncHEAD^
indique A3HEAD^2
indique B3HEAD^3
indique C3La prochaine utilisation de
~
ou^
côte à côte se situe dans le contexte de la validation désignée par les caractères précédents.Remarque 1 :
HEAD~3
est toujours égal à:HEAD~~~
et à:HEAD^^^
(chaque indique A1 ),et généralement :
HEAD~n
est toujours égal à:HEAD~...~
( n fois~
) et à:HEAD^...^
( n fois^
).Avis 2 :
HEAD^3
n'est pas le même queHEAD^^^
(le premier indique C3 et le second indique A1 ),et généralement :
HEAD^1
est le même queHEAD^
,HEAD^n
n'est pas toujours le même queHEAD^...^
( n fois~
).la source
TLDR
~ est ce que vous voulez la plupart du temps, il fait référence aux validations passées dans la branche actuelle
^ référence les parents (git-merge crée un 2ème parent ou plus)
A ~ est toujours identique à A ^
A ~~ est toujours identique à A ^^, et ainsi de suite
A ~ 2 n'est pas identique à A ^ 2 cependant,
parce que ~ 2 est un raccourci pour ~~
tandis que ^ 2 n'est pas raccourci pour quoi que ce soit, cela signifie le 2e parent
la source
HEAD ^^^ est le même que HEAD ~ 3, en sélectionnant le troisième commit avant HEAD
HEAD ^ 2 spécifie la deuxième tête dans un commit de fusion
la source
HEAD ~ spécifie le premier parent d'une "branche"
HEAD ^ vous permet de sélectionner un parent spécifique du commit
Un exemple:
Si vous voulez suivre une branche latérale, vous devez spécifier quelque chose comme
la source
exemple réel de la différence entre HEAD ~ et HEAD ^
la source
Autrement dit, pour le premier niveau de filiation (ascendance, héritage, lignée, etc.) HEAD ^ et HEAD ~ pointent tous deux vers le même commit, qui est (situé) un parent au-dessus de HEAD (commit).
De plus, HEAD ^ = HEAD ^ 1 = HEAD ~ = HEAD ~ 1. Mais HEAD ^^! = HEAD ^ 2! = HEAD ~ 2. Pourtant HEAD ^^ = HEAD ~ 2. Continuer à lire.
Au-delà du premier niveau de filiation, les choses deviennent plus délicates, surtout si la branche de travail / branche principale a eu des fusions (d'autres branches). Il y a aussi la question de la syntaxe avec le curseur, HEAD ^^ = HEAD ~ 2 (ils sont équivalents) MAIS HEAD ^^! = HEAD ^ 2 (ce sont deux choses complètement différentes).
Chaque / le caret fait référence au premier parent de la HEAD, c'est pourquoi les carets enchaînés sont équivalents aux expressions tilde, car ils se réfèrent aux premiers parents du premier parent (premier parent), etc., etc. basés strictement sur le nombre de carets connectés ou sur le nombre suivant le tilde (de toute façon, ils signifient tous deux la même chose), c'est-à-dire rester avec le premier parent et remonter x générations.
HEAD ~ 2 (ou HEAD ^^) fait référence à la validation qui est deux niveaux d'ascendance au-dessus / au-dessus de la validation actuelle (la HEAD) dans la hiérarchie, ce qui signifie la validation des grands-parents de la HEAD.
HEAD ^ 2, d'autre part, ne fait PAS référence à la validation du deuxième parent du premier parent, mais simplement à la validation du deuxième parent. En effet, le signe d'insertion signifie le parent du commit, et le nombre suivant signifie à quel parent le commit est référencé (le premier parent, dans le cas où le caret n'est pas suivi d'un nombre [car il est un raccourci pour le nombre étant 1, c'est-à-dire le premier parent]). Contrairement au signe d'insertion, le nombre qui suit ensuite n'implique pas un autre niveau de hiérarchie vers le haut, mais il implique plutôt combien de niveaux latéralement, dans la hiérarchie, il faut aller trouver le bon parent (commit). Contrairement au nombre dans une expression tilde, il ne s'agit que d'un parent dans la hiérarchie, quel que soit le nombre (immédiatement) précédant le curseur. Au lieu de vers le haut, le signe d'insertion '
Donc HEAD ^ 3 est égal au troisième parent du commit HEAD (PAS l'arrière-grand-parent, ce qui serait HEAD ^^^ AND HEAD ~ 3 ...).
la source
~
cela signifie parent.^
s'il a des parents de deux ou plus, comme merge commit, nous pouvons sélectionner le deuxième parent ou un autre.donc si une seule chose comme (HEAD ~ ou HEAD ^), cela a les mêmes résultats.
la source