协慌网

登录 贡献 社区

查找 Git 提交来自哪个分支

在给定其 SHA-1哈希值的情况下,是否有办法找出提交来自哪个分支?

如果您能告诉我如何使用 Ruby Grit 做到这一点,您将获得加分。

答案

尽管 Dav 是正确的,即不会直接存储信息,但这并不意味着您永远找不到。这是您可以做的几件事。

查找提交所在的分支

git branch -a --contains <commit>

这将告诉您在其历史记录中具有给定提交的所有分支。显然,如果提交已经被合并,那么它的用处就不那么大了。

搜索引用记录

如果您正在其中进行提交的存储库中,则可以在 reflogs 中搜索该提交的行。超过 90 天的 Reflog 会被 git-gc 删除,因此,如果提交太旧,您将找不到它。也就是说,您可以执行以下操作:

git reflog show --all | grep a871742

找到提交 a871742。请注意,您必须使用提交的首 7 位缩写。输出应该是这样的:

a871742 refs/heads/completion@{0}: commit (amend): mpc-completion: total rewrite

指示提交是在分支 “完成” 上进行的。默认输出显示缩写的提交哈希,因此请确保不要搜索完整的哈希,否则您将找不到任何内容。

git reflog show实际上只是git log -g --abbrev-commit --pretty=oneline的别名,因此,如果您想弄弄输出格式以使 grep 可以使用其他内容,那就是您的起点!

如果您不在进行提交的存储库中工作,那么在这种情况下,您最好的办法是检查 reflog,并查找何时首次将提交引入到存储库中。运气好的话,您就拿到了它所承诺的分支。这有点复杂,因为您不能同时遍历提交树和刷新日志。您需要解析 reflog 输出,检查每个哈希以查看其是否包含所需的提交。

查找后续的合并提交

这是与工作流程有关的,但是如果工作流程良好,则会在开发分支上进行提交,然后将其合并。您可以执行以下操作:

git log --merges <commit>..

查看具有给定提交作为祖先的合并提交。 (如果提交只被合并了一次,那么我想,第一个应该是您要进行的合并;否则,您必须检查一些。)合并提交消息应包含已合并的分支名称。

如果您希望能够这样做,则可能需要使用--no-ff选项进行git merge来强制创建合并提交,即使在快进的情况下也是如此。 (不过,不要急于求成。如果使用过度,这可能会令人困惑。) VonC 对一个相关问题的回答有助于详细说明该主题。

这个简单的命令就像一个魅力:

git name-rev <SHA>

例如(其中test-branch是分支名称):

git name-rev 651ad3a
251ad3a remotes/origin/test-branch

即使这样也适用于复杂的场景,例如:

origin/branchA/
              /branchB
                      /commit<SHA1>
                                   /commit<SHA2>

在这里git name-rev commit<SHA2>返回branchB

2013 年 12 月更新:

sschuberth 评论

git-what-branch (Perl 脚本,请参见下文)似乎不再被维护。 git-when-merged是用 Python 编写的替代方法,对我来说很好用。

它基于 “查找包含特定提交的合并提交”。

git when-merged [OPTIONS] COMMIT [BRANCH...]

查找何时将提交合并到一个或多个分支中。
COMMIT带入指定 BRANCH 的合并提交。

具体来说,在包含COMMIT作为祖先BRANCH的第一父级历史上查找最旧的提交。


2010 年 9 月的原始答案:

塞巴斯蒂安 · 杜什(Sebastien Douche)刚刚抽搐了(在此回答之前 16 分钟):

git-what-branch :发现提交在哪个分支上,或如何到达命名分支

这是Seth Robertson的 Perl 脚本,看起来非常有趣:

概要

git-what-branch [--allref] [--all] [--topo-order | --date-order ]
[--quiet] [--reference-branch=branchname] [--reference=reference]
<commit-hash/tag>...

概述

告诉我们(默认情况下)最早的提交和合并因果路径,以使请求的提交进入命名分支。如果直接在命名分支上进行提交,则显然是最早的路径。

最早的因果路径是指按照提交时间最早合并到命名分支中的路径(除非指定了--topo-order

表现

如果许多分支(例如数百个)包含提交,则系统可能需要很长时间(对于 Linux 树中的特定提交,花了 8 秒钟来探索一个分支,但是有 200 多个候选分支)来跟踪该路径。每次提交。
选择特定的--reference-branch --reference tag进行检查的速度将提高数百倍(如果您有数百个候选分支)。

例子

# git-what-branch --all 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4
 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4 first merged onto master using the following minimal temporal path:
   v2.6.12-rc3-450-g1f9c381 merged up at v2.6.12-rc3-590-gbfd4bda (Thu May  5 08:59:37 2005)
   v2.6.12-rc3-590-gbfd4bda merged up at v2.6.12-rc3-461-g84e48b6 (Tue May  3 18:27:24 2005)
   v2.6.12-rc3-461-g84e48b6 is on master
   v2.6.12-rc3-461-g84e48b6 is on v2.6.12-n
   [...]

该程序没有考虑挑选感兴趣的提交的影响,仅考虑了合并操作。