Git:父节点和祖先节点的逻辑区别是什么?

7

我知道可以找到许多关于 HEAD^HEAD~ 之间区别的问题。

  • ~ 指定 祖先
  • ^ 指定 父代

我的问题是关于 父代祖先 之间意义的不同。对我来说,父代和祖先是相同的。

Git 中 HEAD^ 和 HEAD~ 的区别是什么? 没有回答我的问题,我的问题是关于这两个术语的逻辑含义的区别。


2
可能是Git中HEAD^和HEAD~有什么区别?的重复问题。 - jonrsharpe
1
重复问题的答案确实回答了这个问题,描述了父级和祖先的含义。 - jonrsharpe
严格来说, ~^ 可以用来指定提交本身。 HEAD~0HEAD^0 都等于 HEAD。从某种角度来看,我们可以说提交是其自身的第 0 个父代或祖先。此外,如果 foo 是指向提交的注释标签,则 foo^0 是提交对象,而 foo 是标签对象。 - ElpieKay
2个回答

10

这里的区别有点垂直与水平的问题。

在Git中,提交是一种链接列表,每个提交都有对父提交或多个父提交的引用。

使用~访问父级或祖先级:

  • ~是提交的直接父级,
  • ~2(或~~)是二级父级,
  • 以此类推。

如果您查看日志,使用~将沿着提交向下移动,这是垂直方向。

现在,当您合并两个分支时,它会产生一个合并提交。合并提交定义为将两个或多个分支合并在一起。因此,合并提交将具有两个或多个父级。

从合并提交开始,如果您想要访问不同的父级,则使用^(它实际上看起来像合并了两个分支)。

因此,请考虑以下日志部分:

*   39a2f899 (HEAD)
|\  
| * e2e7d241 (BRANCH)
| * caf13dc1
| * 609a9715
|/  
*   663e09ff

如果您想访问BRANCH的父提交,您可以使用BRANCH~e2e7d241~,这将给出caf13dc1。现在,如果您想访问HEAD的父节点,并执行HEAD~,它将给您663e09ff(分支开始之前的提交)。
但是,如果您想访问合并分支的提交链,这就是^发挥作用的地方,您可以执行HEAD^2,表示“HEAD的第二个父提交”(而不是父亲的父亲)。
当然,您可以将它们组合在同一张图中,HEAD^2~是HEAD的第二个父提交(^2)的父提交(~),即caf13dc1
顺便说一下,每个提交至少有一个父提交,因此commit^总是与commit~相同。另一方面,如果一个提交只有一个父提交(它不是合并提交),commit^2将返回错误。
总之,您可以使用^访问合并的不同父提交,并使用~访问提交的代数。
下面是一个更复杂的合并示例(合并了4个分支)的图示:
----------> use ^ to go through the parents of the merge
|
|   *-----.   6af2936d
|   |\ \ \ \  
|   | | | | * 20d6fb23 BRANCH1
|   | | | * | e589d446 BRANCH2
|   | | | * | ec6088bd
|   | | | |/  
|   | | * | 38dcecfa BRANCH3
|   | | |/  
|   | * | 698c3daa BRANCH4
|   | |/  
|   |/  
|   *   2d97958e
|   |\  
|   | * 8989f1d3
|   | * d907cb7a
|   |/  
|   *   af368002
V
use ~ to go this way (through the ancestors)

2

简而言之

"parents" 指的是直接的父级,即在给定提交定义中明确声明 SHA-1 的提交。

"ancestors" 指的是一个提交的父级以及它们的父级,递归地。

最初的回答

“parents”指的是直接父级,即在给定提交的定义中明确说明SHA-1的提交。

“ancestors”指的是提交的父级和它们的父级,递归地。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接