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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3005392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:32:52  来源:igfitidea点击:

How can I tell if one commit is a descendant of another commit?

git

提问by engie

With Git, how can I tell if one commit in my branch is a descendant of another commit?

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

采纳答案by Jakub Nar?bski

If you want to check this programmatically (e.g. in script), you can check if git merge-base A Bis equal to git rev-parse --verify A(then A is reachable from B), or if it is git rev-parse --verify B(then B is reachable from A). git rev-parseis here needed to convert from commit name to commit SHA-1 / commit id.

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

Using git rev-listlike in VonC answeris also possibility.

git rev-listVonC 答案中使用like也是可能的。

Edit:in modern Git there is explicit support for this query in the form of git merge-base --is-ancestor.

编辑:在现代 Git 中,以git merge-base --is-ancestor.



If one of commits you are asking about is a branch tip, then git branch --contains <commit>or git branch --merged <commit>might be better non-programmatic solution.

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

回答by Matt R

From Git 1.8.0, this is supported as an option to merge-base:

从 Git 1.8.0 开始,支持作为以下选项merge-base

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

From the man page:

从手册页:

--is-ancestor

Check if the first is an ancestor of the second , and exit with status 0 if true, or with status 1 if not. Errors are signaled by a non-zero status that is not 1.

--is-祖先

检查第一个是否是第二个的祖先,如果为真则以状态 0 退出,否则以状态 1 退出。错误由非 1 的非零状态表示。

For example:

例如:

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

回答by VonC

This kind of operations relies on the notion of range of revisionsdetailed in the SO question: "Difference in ‘git log origin/master' vs ‘git log origin/master..'".

这种操作依赖于SO 问题中详述的修订范围概念:“ 'git log origin/master' 与 'git log origin/master..' 的差异”。

git rev-listshould be able to walk back from a commit, up until another if reachable.

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

So I would try:

所以我会尝试:

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

(Boundary commits are prefixed with -)

(边界提交以 为前缀-

If the last commit displayed is the same than the first commit in the git rev-listcommand, then it is a commit reachable from the second commit.

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

If the first commit is not reachable from the second, git rev-listshould return nothing.

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

git rev-list --boundary A..B

would finish by A, if Ais reachable from B.
It is the same as:

将在A,如果A从 可达B
它与以下内容相同:

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

,with Ba positive reference, and Aa negative reference.
It will starts at Band walks back through the graph until it encounters a revision that is reachable from A.
I would argue that if Ais directly reachable from B, it will encounter (and display, because of the --boundaryoption) Aitself.

B一个正参考,和A一个负参考
它将从 开始B并返回图,直到遇到可从 到达的修订A
我会争辩说,如果A可以从 直接到达B,它将遇到(并显示,因为该--boundary选项)A本身。

回答by itub

Another way would be to use git logand grep.

另一种方法是使用git loggrep

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

This will produce one line of output if commit def456 is an ancestor of commit abc123, or no output otherwise.

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

You can usually get away with omitting the --prettyargument, but it is needed if you want to make sure that you only search through actual commit hashes and not through log comments and so on.

您通常可以省略--pretty参数,但如果您想确保只搜索实际提交哈希而不是日志注释等,则需要这样做。

回答by viq

git show-branchbranch-sha1 commit-sha1

git show-branchbranch-sha1 commit-sha1

Where:

在哪里:

  • branch-sha1: the sha1 in your branch you want to check
  • commit-sha1: the sha1 of the commit you want to check against
  • branch-sha1:您要检查的分支中的 sha1
  • commit-sha1:要检查的提交的 sha1

回答by ocroquette

Building up on itub's answer, in case you need to do this for all the tags in the repository:

以 itub 的回答为基础,以防您需要对存储库中的所有标签执行此操作:

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