我怎么知道一个承诺是否是另一个承诺的后代?

使用 Git,如何判断分支中的一个提交是否是另一个提交的后代?

45680 次浏览

这种操作依赖于在 SO 问题中详细描述的 修订的范围的概念: “ “ git 日志起源/主”与“ git 日志起源/主”的区别”。

git rev-list 应该能够从一个提交返回,直到另一个如果可达。

所以我会尝试:

git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20

(边界提交以 -作为前缀)

如果显示的最后一次提交与 git rev-list命令中的第一次提交相同,那么它是第二次提交可以达到的提交。

如果第一次提交无法从第二次提交到达,则 git rev-list应该不返回任何内容。

git rev-list --boundary A..B

如果从 B可以到达 A,将在 A结束。
它与:

git rev-list --boundary B --not A

B正面引用A负面参考
它将从 B开始,然后返回到图中,直到遇到从 A可以访问的修订。
我认为,如果从 B可以直接到达 A,它将遇到(并显示,因为 --boundary选项) A本身。

如果你想通过编程的方式检查(例如在脚本中) ,你可以检查 git merge-base A B是否等于 git rev-parse --verify A(那么从 B 可以到 A) ,或者是否是 git rev-parse --verify B(那么从 A 可以到 B)。这里需要将 git rev-parse从提交名称转换为提交 SHA-1/提交 ID。

像在 回答中一样使用 git rev-list也是可能的。

编辑: 在现代 Git 中,这个查询以 git merge-base --is-ancestor的形式得到了明确的支持。


如果您询问的提交之一是 枝尖,那么 git branch --contains <commit>git branch --merged <commit>可能是更好的非编程解决方案。

另一种方法是使用 git loggrep

git log --pretty=format:%H abc123 | grep def456

如果提交 def456是提交 abc123的祖先,这将产生一行输出,否则没有输出。

您通常可以省略 --pretty参数,但是如果您希望确保只搜索实际的提交散列,而不是通过日志注释等,则需要使用 --pretty参数。

从 Git1.8.0开始,merge-base支持这个选项:

git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>

来自手册页:

是祖先

检查第一个是否是第二个的祖先, 如果为 true,则以状态0退出,如果不为 true,则以状态1退出 由非零状态(不是1)发出的信号。

例如:

git merge-base --is-ancestor origin/master master; echo $?

基于 itub 的答案,以防您需要对存储库中的所有标记执行以下操作:

for i in `git tag` ; do echo -ne $i "\t" ; git log --pretty=format:%H $i | (grep <commit to find> || echo ""); done

Git show-Branch Branch-sha1 commit-sha1

地点:

  • 分支 -sha1: 你想检查的分支中的 sha1
  • Commit-sha1: 要检查的提交的 sha1

如果您正在使用 git merge-base --is-ancestor,请确保使用 Git 2.28(Q32020)

使用 Git 2.28(Q32020) ,“ struct commit”中一些不必始终存在的字段已被移动到提交平台。

提交 c752ad0提交 c49c82a提交4844812提交6da43d9(2020年6月17日) by Abhishek Kumar (abhishekkumar2718)
(由 朱尼奥 · C · 哈马诺 gitster犯罪合并,2020年7月6日)

commit-graph : 介绍 commit_graph_data_slab

签名: Abhishek Kumar

结构提交在许多上下文中使用。但是,成员 generationgraph_pos仅用于提交图相关的操作,否则会浪费内存。

当我们转换到使用64位代号而不是当前的32位代号的代号 v2时,这种浪费会更加明显。

因为它们经常一起访问,所以让我们引入结构 commit_graph_data,并将它们移动到一个 commit_graph_data平台。

虽然整个测试套件的运行速度和 master一样快(系列: 26m48s,master:27m34s,快2.87%) ,但某些命令如 git merge-base --is-ancestor的运行速度比 由 Szeder Gábor 发现慢40% 。
在最小化提交-板式访问之后,速度会继续下降,但接近20% 。

Derrick Stolee 认为这种减速是由于底层算法而不是 提交板访问的缓慢性造成的,我们将在后面的系列文章中继续讨论。