当我在Git中指定一个祖先提交对象时,我混淆了HEAD^和HEAD~。
两者都有“编号”版本,如HEAD^3和HEAD~2。
在我看来它们非常相似或相同,但是波浪号和插入符号之间有什么不同吗?
当我在Git中指定一个祖先提交对象时,我混淆了HEAD^和HEAD~。
两者都有“编号”版本,如HEAD^3和HEAD~2。
在我看来它们非常相似或相同,但是波浪号和插入符号之间有什么不同吗?
当前回答
简单地说,对于亲子关系的第一级(祖先,继承,世系等),HEAD^和HEAD~都指向同一个提交,它位于HEAD(提交)之上的一个父级。
此外,HEAD^ = HEAD^1 = HEAD~ = HEAD~1。但是HEAD^^ != HEAD^2 != HEAD~2。然而头^^ =头~2。继续读下去。
在第一级亲子关系之外,事情变得更加棘手,特别是如果工作分支/主分支有合并(来自其他分支)。还有一个插入符号的语法问题,HEAD^^ = HEAD~2(它们是等价的)但是HEAD^^ != HEAD^2(它们是完全不同的两个东西)。
每个/插入符号指的是HEAD的第一个父代,这就是为什么串在一起的插入符号相当于波浪号表达式,因为它们指的是第一个父代的(第一个父代的)第一个父代,等等,严格基于连接插入符号上的数字或波浪号后面的数字(无论哪种方式,它们都意味着相同的事情),即保持第一个父代并向上x代。
HEAD~2(或HEAD^^)指的是在层次结构中当前提交(HEAD)上/上两级祖先的提交,这意味着HEAD的祖父级提交。
HEAD^2, on the other hand, refers NOT to the first parent's second parent's commit, but simply to the second parent's commit. That is because the caret means the parent of the commit, and the number following signifies which/what parent commit is referred to (the first parent, in the case when the caret is not followed by a number [because it is shorthand for the number being 1, meaning the first parent]). Unlike the caret, the number that follows afterwards does not imply another level of hierarchy upwards, but rather it implies how many levels sideways, into the hierarchy, one needs to go find the correct parent (commit). Unlike the number in a tilde expression, it is only one parent up in the hierarchy, regardless of the number (immediately) proceeding the caret. Instead of upward, the caret's trailing number counts sideways for parents across the hierarchy [at a level of parents upwards that is equivalent to the number of consecutive carets].
所以HEAD^3等于HEAD提交的第三个父结点(不是曾祖结点,即HEAD^^^ AND HEAD~3)。
其他回答
^ BRANCH选择器 git结帐头^2 通过移动到所选分支(在提交树上后退一步),选择(合并)提交的第二个分支。
~提交选择器 git结帐头~2 在默认/选择的分支上向后提交2次
将~和^相对引用定义为PARENT选择器是迄今为止我在互联网上看到的主要定义——包括官方的Git Book。是的,它们是PARENT选择器,但这种“解释”的问题是,它完全违背了我们的目标:如何区分两者……:)
另一个问题是当我们被鼓励使用^ BRANCH选择器进行COMMIT选择时(也就是HEAD^ === HEAD~)。 同样,是的,你可以这样使用它,但这不是它的设计目的。^ BRANCH选择器的向后移动行为是一个副作用,而不是它的目的。
只有在合并提交时,才可以将数字分配给^ BRANCH选择器。因此,只有在需要在分支机构之间进行选择时,才能充分利用其容量。 在fork中表达选择的最直接的方法是踏上所选的路径/分支——这是在提交树上后退一步。这只是一种副作用,而不是它的主要目的。
以下是从http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde上逐字逐句摘录的一个很好的解释:
Ref ~是Ref ~1的简写,表示提交的第一个父对象。Ref ~2表示提交的第一个父对象的第一个父对象。Ref ~3表示提交的第一个父级的第一个父级的第一个父级。等等。 Ref ^是Ref ^1的简写,表示提交的第一个父对象。但两者的不同之处在于ref^2表示提交的第二个父对象(记住,当提交是一个merge时,它们可以有两个父对象)。 ^和~操作符可以组合使用。
简单地说:
~指定祖先 ^指定父母
合并时可以指定一个或多个分支。然后提交有两个或多个父节点,然后^用于表示父节点。
假设你在分支A上,还有两个分支:B和C。
在每个分支上的最后三个提交是:
A: a1, a2, a3 B: b1 b2 b3 C: c1 c3 c3
如果现在在分支A上执行命令:
git merge B C
然后你将三个分支合并在一起(这里你的合并提交有三个父分支)
and
~表示第一个分支中的第n个祖先,因此
HEAD~表示A3 HEAD~2表示A2 HEAD~3表示A1
^表示第n个父结点,因此
HEAD^表示A3 HEAD^2表示B3 HEAD^3表示C3
~或^的下一个用法是在前面的字符指定的提交上下文中。
注意1:
HEAD~3总是等于:HEAD~~~和:HEAD^^^(每个表示A1),
和一般:
HEAD~n总是等于:HEAD~…~ (n次~)和to: HEAD^…^ (n乘以^)
注意2:
HEAD^3和HEAD^^^不一样(第一个表示C3,第二个表示A1),
和一般:
HEAD^1和HEAD^是一样的, 但是对于n > 1: HEAD^n总是不等于HEAD^…^ (n乘以^)
简单地说,对于亲子关系的第一级(祖先,继承,世系等),HEAD^和HEAD~都指向同一个提交,它位于HEAD(提交)之上的一个父级。
此外,HEAD^ = HEAD^1 = HEAD~ = HEAD~1。但是HEAD^^ != HEAD^2 != HEAD~2。然而头^^ =头~2。继续读下去。
在第一级亲子关系之外,事情变得更加棘手,特别是如果工作分支/主分支有合并(来自其他分支)。还有一个插入符号的语法问题,HEAD^^ = HEAD~2(它们是等价的)但是HEAD^^ != HEAD^2(它们是完全不同的两个东西)。
每个/插入符号指的是HEAD的第一个父代,这就是为什么串在一起的插入符号相当于波浪号表达式,因为它们指的是第一个父代的(第一个父代的)第一个父代,等等,严格基于连接插入符号上的数字或波浪号后面的数字(无论哪种方式,它们都意味着相同的事情),即保持第一个父代并向上x代。
HEAD~2(或HEAD^^)指的是在层次结构中当前提交(HEAD)上/上两级祖先的提交,这意味着HEAD的祖父级提交。
HEAD^2, on the other hand, refers NOT to the first parent's second parent's commit, but simply to the second parent's commit. That is because the caret means the parent of the commit, and the number following signifies which/what parent commit is referred to (the first parent, in the case when the caret is not followed by a number [because it is shorthand for the number being 1, meaning the first parent]). Unlike the caret, the number that follows afterwards does not imply another level of hierarchy upwards, but rather it implies how many levels sideways, into the hierarchy, one needs to go find the correct parent (commit). Unlike the number in a tilde expression, it is only one parent up in the hierarchy, regardless of the number (immediately) proceeding the caret. Instead of upward, the caret's trailing number counts sideways for parents across the hierarchy [at a level of parents upwards that is equivalent to the number of consecutive carets].
所以HEAD^3等于HEAD提交的第三个父结点(不是曾祖结点,即HEAD^^^ AND HEAD~3)。
OP:当我在Git中指定一个祖先提交对象时,我混淆了HEAD^和HEAD~。
Git中的HEAD^和HEAD~有什么区别?
HEAD^(插入号)和HEAD~(波浪号)之间的区别在于它们如何从指定的起点向后遍历历史,在这种特殊情况下是HEAD。
波浪号~
<rev>~[<n>] = select <n>第一代祖先
插入符号 ^
<rev>^[<n>] = select <n>第一代祖先的第一个父母
*第一个父节点总是在merge的左边,例如,在被合并到的分支上提交。
把~和^连在一起
如下图所示,两个选择器~和^可以组合使用。还要注意,不使用HEAD作为起点,任何常规引用都可以使用,比如分支、标记甚至是提交散列。
此外,根据要选择的祖先,^和~可以互换使用,如下表所示。
来源:在这篇关于这个主题的博客文章中可以找到一个完整的纲要。