当我在Git中指定一个祖先提交对象时,我混淆了HEAD^和HEAD~。
两者都有“编号”版本,如HEAD^3和HEAD~2。
在我看来它们非常相似或相同,但是波浪号和插入符号之间有什么不同吗?
当我在Git中指定一个祖先提交对象时,我混淆了HEAD^和HEAD~。
两者都有“编号”版本,如HEAD^3和HEAD~2。
在我看来它们非常相似或相同,但是波浪号和插入符号之间有什么不同吗?
当前回答
~表示父母。
^如果它有两个或更多的父节点,比如合并提交。我们可以选择父节点中的第二个或另一个。
如果只有一个东西,比如(HEAD~或HEAD^),结果是一样的。
其他回答
~和^本身都是指提交的父节点(~~和^^都是指祖父节点提交,等等),但当它们与数字一起使用时,它们的含义有所不同:
~2表示在层次结构中向上两层,如果一个提交有多个父级,则通过第一个父级 ^2表示第二个父节点,其中提交有多个父节点(也就是说,因为它是一个merge)
这些可以组合起来,所以HEAD~2^3意味着HEAD的祖父提交的第三个父提交。
HEAD^和HEAD~之间的区别可以通过http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html上的插图(由Jon Loeliger绘制)很好地描述。
这个文档对于初学者来说可能有点晦涩,所以我复制了下面的插图:
G H I J
\ / \ /
D E F
\ | / \
\ | / |
\|/ |
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2
OP:当我在Git中指定一个祖先提交对象时,我混淆了HEAD^和HEAD~。
Git中的HEAD^和HEAD~有什么区别?
HEAD^(插入号)和HEAD~(波浪号)之间的区别在于它们如何从指定的起点向后遍历历史,在这种特殊情况下是HEAD。
波浪号~
<rev>~[<n>] = select <n>第一代祖先
插入符号 ^
<rev>^[<n>] = select <n>第一代祖先的第一个父母
*第一个父节点总是在merge的左边,例如,在被合并到的分支上提交。
把~和^连在一起
如下图所示,两个选择器~和^可以组合使用。还要注意,不使用HEAD作为起点,任何常规引用都可以使用,比如分支、标记甚至是提交散列。
此外,根据要选择的祖先,^和~可以互换使用,如下表所示。
来源:在这篇关于这个主题的博客文章中可以找到一个完整的纲要。
简单地说:
~指定祖先 ^指定父母
合并时可以指定一个或多个分支。然后提交有两个或多个父节点,然后^用于表示父节点。
假设你在分支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乘以^)
^<n>格式允许您选择提交的第n个父节点(与合并相关)。~<n>格式允许您选择第n个祖先提交,始终紧跟在第一个父提交之后。有关一些示例,请参阅git-rev-parse的文档。