如何判断一个提交是否是另一个提交的后代?

时间:2010-06-09 11:35:15

标签: git

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

8 个答案:

答案 0 :(得分:218)

从Git 1.8.0开始,merge-base支持此选项:

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

从手册页:

  

- 是-祖先

     

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

例如:

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

答案 1 :(得分:46)

如果你想以编程方式检查(例如在脚本中),你可以检查git merge-base A B是否等于git rev-parse --verify A(然后A可以从B到达),或者是{{1} (然后B可以从A到达)。此处需要git rev-parse --verify B将提交名称转换为提交SHA-1 / commit id。

使用VonC answer中的git rev-parse也是可能的。


如果您提出的提交之一是分支提示,那么git rev-listgit branch --contains <commit>可能是更好的非程序化解决方案。

答案 2 :(得分:13)

此类操作依赖于SO问题中详述的修订范围的概念:“Difference in ‘git log origin/master’ vs ‘git log origin/master..’”。

git rev-list 应该能够从提交步骤返回,直到另一个提交为止。

所以我会尝试:

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

(边界提交以-为前缀)

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

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

git rev-list --boundary A..B
如果A可以从A到达,则

将按B结束 它与:

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

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

答案 3 :(得分:9)

另一种方法是使用git log和grep。

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

如果提交def456是commit abc123的祖先,则会生成一行输出,否则无输出。

你通常可以省略“--pretty”参数,但是如果你想确保只搜索实际的提交哈希值而不是通过日志注释等等,那么就可以了。

答案 4 :(得分:3)

https://stackoverflow.com/a/13526591/895245提到它,现在是为了让它更加人性化:

git-is-ancestor() (
  if git merge-base --is-ancestor "$1" "$2"; then
      echo 'ancestor'
  elif git merge-base --is-ancestor "$2" "$1"; then
      echo 'descendant'
  else
      echo 'unrelated'
  fi
)
alias giia='git-is-ancestor'

答案 5 :(得分:1)

git show-branch branch-sha1 commit-sha1

其中:

  • branch-sha1:您要检查的分支中的sha1
  • commit-sha1:要检查的提交的sha1

答案 6 :(得分:0)

如果您使用的是git merge-base --is-ancestor,请确保使用Git 2.28(2020年第三季度)

在Git 2.28(2020年第三季度)中,“ struct commit”中一些并非总是必须存在的字段已移至提交楼板。

请参见commit c752ad0commit c49c82acommit 4844812commit 6da43d9Abhishek Kumar (abhishekkumar2718)(2020年6月17日)。
(由Junio C Hamano -- gitster --commit d80bea4中合并,2020年7月6日)

commit-graph:介绍commit_graph_data_slab

签名人:Abhishek Kumar

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

当我们过渡到第v2代时,这种浪费会更加明显,该版本使用64位的代号而不是当前的32位。

由于经常将它们一起访问,让我们介绍结构commit_graph_data并将其移至commit_graph_data平板上。

虽然整体测试套件的运行速度与master一样快(系列:26m48s,master:27m34s,速度提高了2.87%),但某些命令(例如git merge-base --is-ancestor)却降低了40 %as discovered by Szeder Gábor
最小化提交面板访问后,速度减慢仍然存在,但接近20%。

Derrick Stolee认为,速度下降是由于底层算法而不是slowness of commit-slab access造成的,我们将在以后的系列文章中进行后续讨论。

答案 7 :(得分:-1)

建立itub的答案,以防你需要对存储库中的所有标签执行此操作:

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