【问题标题】:Why does 'git rev-list --left-right' comparing A..B not consistent with B..A?为什么'git rev-list --left-right'比较A..B与B..A不一致?
【发布时间】:2019-05-10 05:09:23
【问题描述】:

我正在尝试使用来自 https://stackoverflow.com/a/27940027/1949430 的答案比较两个提交以了解它们的 Ahead/Behind 差异

"git rev-list --left-right --count A..​​B" 其中 A 和 B 分别是 SHA1 提交引用。

在一种情况下,A..B 的比较得出 0 领先和 17 落后。如果我为 B..A 重新运行相同的命令,那么我会得到 0 Ahead 和 0Behind,而我希望它是 17 Ahead 和 0Behind 的简单倒数。在另一种情况下,我在一个方向上得到 0/6,在另一个方向上得到 0/2。这违背了我试图更好地可视化差异的目的,在这种情况下是子模块引用与签出提交。

为什么 A..B 的结果与 B..A 的结果完全不同?无论顺序如何,我都需要/期望获得一致的值,只需交换前后计数...

有没有更好的方法来持续获取这些信息?目前,我看到的唯一解决方案是在脚本中运行该命令两次(每个方向一个)并显示较大的值。

【问题讨论】:

  • 用--graph --oneline 而不是--count 来看看计算了什么?

标签: git


【解决方案1】:

TL;DR:你想要git rev-list --left-right --count A...B。注意三个点,而不是两个。

两点符号表示1可从B 访问的提交,减去可从A 访问的任何提交。假设有 17 个这样的提交,因为修订历史看起来像这样:

...--o--o--o   <-- A
            \
             o--o--o--...--o   <-- B (17 commits in total, 13 not shown here)

顶行的所有提交都可以从A 访问,因此它们会从B(两行)可访问的提交集中减去。剩下的就是 17 个。

交换顺序意味着可从A 访问的提交,减去可从B 访问的任何提交。 由于所有提交都可从B 访问,我们从可从可访问的提交集中减去它们A,根本不留下任何提交。因此计数为零。

三点符号A...B 表示2提交可从任一 A 或 B,减去所有可从 both A 和 B 访问的提交。 在上图中,有 17 个可从 @ 访问的提交987654336@ 但不是A,并且可以从A 而不是B 达到零提交。使用--left-right 将它们分成它们的子组;使用--count 计算它们;将两者放在一起即可得到两个数字,这两个数字将占据左侧或右侧,具体取决于您使用的是A...B 还是B...A。

三点符号在如下图表中更有用:

       o--o   <-- A
      /
...--*
      \
       o--o--o   <-- B

这里有两个提交可以从A 到达但不是B,三个提交可以从B 到达但不是A。所有中间行提交* 和更早的提交都可以从两个提示中访问,因此被三点符号排除。


1对于git diff,两个和三个点表示法的含义非常不同。 diff 命令大多只需要 两个 提交,A..B 或 A...B 通常意味着 许多 提交——比 git diff 喜欢的两个要多——所以@987654354 @ 只是表示:使用A 作为左侧,使用B 作为右侧,这与git diff A B 完全相同。这并不是那么有用,因为您可以自己用空格替换两个点,但 就是 它的意思。

2在git diff 中,三点语法具有全新且非常不同(且有用!)的含义。 A...B 表示法不是比较提交 A 和 B,而是表示:在中间找到排除的提交——这或多或少是合并基础——并使用那作为左边。使用B 作为右侧。 对于上面说明的最后一种情况,中间排除的提交是commit *,它实际上是合并基础。所以git diff A...B 表示diff commit * vs commit B,而git diff B...A 表示diff commit * vs commit A。


侧边栏:考虑这一点的简单方法

对于那些以视觉为导向的人,假设您有一个图表的打印版本和两个不同颜色的突出显示标记,红色和绿色。你拿图,如:

       o--o   <-- A
      /
...--*
      \
       o--o--o   <-- B

您使用 red 高亮标记并标记A 指向的提交。然后,按照从该提交到其父级的向后连接器。也标记那些红色。继续向后移动,直到您可以通过这种方式到达的所有内容(通过向后移动,通过任何合并处的所有父提交)都标记为红色。

然后,使用您的 绿色 高亮标记并标记B 指向的提交。沿着这个倒退到它的父母那里,并将那些标记为绿色。一直标记为绿色,直到您可以通过这条路到达的所有地方都标记为绿色。

包含仅绿色突出显示的任何提交。任何带有红色或两者都突出显示的提交都被排除在外。你在这里真正做的是两组 reachable 提交的集合减法,但这很容易考虑。

【讨论】:

  • 很好的答案。感谢您的快速回复和详细解释。
猜你喜欢
  • 1970-01-01
  • 2021-10-06
  • 2022-10-24
  • 2014-03-29
  • 2011-05-30
  • 2015-01-18
  • 2010-12-08
  • 2019-04-30
  • 1970-01-01
相关资源
最近更新 更多