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 提交的集合减法,但这很容易考虑。