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
How can I tell if one commit is a descendant of another commit?
提问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 B
is 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-parse
is 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-list
like in VonC answeris also possibility.
git rev-list
在VonC 答案中使用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-list
should 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-list
command, 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-list
should return nothing.
如果第一个提交无法从第二个提交,则git rev-list
不应返回任何内容。
git rev-list --boundary A..B
would finish by A
, if A
is reachable from B
.
It is the same as:
将在A
,如果A
从 可达B
。
它与以下内容相同:
git rev-list --boundary B --not A
,with B
a positive reference, and A
a negative reference.
It will starts at B
and walks back through the graph until it encounters a revision that is reachable from A
.
I would argue that if A
is directly reachable from B
, it will encounter (and display, because of the --boundary
option) A
itself.
与B
一个正参考,和A
一个负参考。
它将从 开始B
并返回图,直到遇到可从 到达的修订A
。
我会争辩说,如果A
可以从 直接到达B
,它将遇到(并显示,因为该--boundary
选项)A
本身。
回答by itub
Another way would be to use git log
and grep
.
另一种方法是使用git log
和grep
。
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 --pretty
argument, 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