如何列出包含特定提交的分支?

1280

如何查询Git以查找包含特定提交的分支?gitk通常会列出这些分支,除非有太多了,在这种情况下,它只会显示“many(38)”或类似的内容。我需要知道完整的列表,或者至少知道特定的分支是否包含此提交。


4
另请参阅:如何列出包含特定提交的所有标签? - Andrew Marshall
与评论中等效提交相关的问题:https://dev59.com/l2Qo5IYBdhLWcg3wI8VV - UpAndAdam
3个回答

1721

来自git-branch手册页面

 git branch --contains <commit>

只列出包含指定提交(如果未指定,则为 HEAD)的分支。意味着 --list


 git branch -r --contains <commit>

列表也会包含远程跟踪分支(如下面user3941992答案所述),即“与远程分支有直接关系的本地分支”。


正如Carl Walsh所指出的那样,这仅适用于默认refspec

fetch = +refs/heads/*:refs/remotes/origin/*

如果需要包含其他引用命名空间(pull requestGerrit等),则需要添加新的refspec,并重新获取:
git config --add remote.origin.fetch "+refs/pull/*/head:refs/remotes/origin/pr/*"
git fetch
git branch -r --contains <commit>

另请参阅git ready文章。

--contains标记将确定某个提交是否已经合并到您的分支中。也许您有一个来自补丁的提交 SHA,您认为已经应用了它,或者您只想检查您最喜欢的开源项目的减少内存使用量75%的提交是否已经完成。

$ git log -1 tests
commit d590f2ac0635ec0053c4a7377bd929943d475297
Author: Nick Quaranto <nick@quaran.to>
Date:   Wed Apr 1 20:38:59 2009 -0400

    Green all around, finally.

$ git branch --contains d590f2
  tests
* master

注意:如果提交在远程跟踪分支上,添加-a选项。
(如MichielB在下方评论中所述)
git branch -a --contains <commit>

MatrixFrog评论说,它只显示包含该确切提交的分支。
如果您想知道哪些分支包含“等效”提交(即哪些分支已经 cherry-pick 了该提交),请使用git cherry

因为 git cherry 比较的是变更集而不是提交ID(sha1),所以您可以使用 git cherry 查找本地进行的提交是否已在不同的提交ID下应用于<upstream>
例如,如果您通过电子邮件向<upstream>提供补丁而不是直接推送或拉取提交,则会发生这种情况。

           __*__*__*__*__> <upstream>
          /
fork-point
          \__+__+__-__+__+__-__+__> <head>

(这里,被标记为'-'的提交在使用git cherry命令时不会显示出来,这意味着它们已经存在于<upstream>中。)

3
测试和主分支 - 主分支是当前分支,因此有星号。 - blueyed
61
这只显示包含“那个确切提交”的分支。如果你想知道哪些分支包含一个“等价的”提交(即哪些分支已经摘取了那个提交),可以使用 git cherry 命令:“因为 git cherry 比较的是变更集而不是提交 ID(sha1),所以你可以使用 git cherry 命令找出本地创建的提交是否已经在另一个提交 ID 下被应用于<上游>。例如,如果你通过电子邮件向<上游>提供补丁而不是直接推送或拉取提交,则会发生这种情况。” 详见:http://www.kernel.org/pub/software/scm/git/docs/git-cherry.html - Tyler
69
添加一个 -a 参数以便同时检查远程分支。 - Raman
31
你还可以使用 git tag --contains <commit> 命令。参见如何搜索包含某个提交的所有标签? - Andrew Marshall
5
@UpAndAdam在这里提出了有关git cherry的问题:https://dev59.com/l2Qo5IYBdhLWcg3wI8VV,不幸的是,该问题尚未得到回答。 - adeelx
显示剩余14条评论

30

你可以执行以下命令:

git log <SHA1>..HEAD --ancestry-path --merges

在输出结果中,您可以从上次提交的评论中找到原始分支名称。

例如:

       c---e---g--- feature
      /         \
-a---b---d---f---h---j--- master

git log e..master --ancestry-path --merges

commit h
Merge: g f
Author: Eugen Konkov <>
Date:   Sat Oct 1 00:54:18 2016 +0300

    Merge branch 'feature' into master

6
好的!我使用了git log <SHA1>..master --ancestry-path --merges --oneline | tail -n1这条命令,以获取这个单行输出。 - James EJ
1
如果您想使用纯git命令,可以使用: git log <SHA1>..master --ancestry-path --merges --oneline -1 - Bartosz
注意:当您的提交sha是主分支/ foo分支(HEAD)上最新的提交时...您不能使用“A..B”提交范围,只需不使用范围即可:git log HEAD --oneline -1 > 82c12a9(HEAD,origin / remote-branch-name,origin / master,origin / dev,origin / HEAD,master,dev)commit message - Devin Rhode
如果这个git仓库是一个子模块,而你正在尝试解决分离的HEAD问题...那么你就有一个关于首选分支的难题...在我的前面的例子中,你可以很容易地说master总是优先考虑,如果它在这个列表中。从那里开始就不太清楚了。你可以尝试从.gitmodules文件中读取git分支:git config -f .gitmodules submodule.src/foo/submodule.branch。这可能是一个长期存在的fork/pr。你可以cd到repo根目录并运行git config submodule.src/foo/submodule.branch。你也可以使用超级项目的当前git分支。 - Devin Rhode
作为一个小提示:git config submodule.src/foo/submodule.branch 可以受到各种 git 配置的影响,包括存储库本地的 .gitconfig 文件。(需要运行 git config --local include.path ./path/to/your/.gitconfig - Devin Rhode

4
git branch -r --contains <commit> 的回答对于普通的远程分支可以很好地工作,但如果提交仅存在于 GitHub 为 PR 创建的隐藏 head 命名空间 中,您需要进行更多步骤。

例如,如果 PR#42 是来自已删除分支的,而该 PR 线程是存储库上提交的唯一引用,那么 git branch -r 不知道 PR #42,因为默认情况下不会将类似 refs/pull/42/head 这样的引用列为远程分支。

[remote "origin"] 部分的 .git/config 中添加一行:

fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

这个Gist提供了更多的背景信息。)

当你执行git fetch时,你会获取所有PR分支,当你运行git branch -r --contains <commit>时,你会看到origin/pr/42包含该提交。


@VonC 感谢您改进我的答案!我没有意识到我正在执行 git commit --add - Carl Walsh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接