给定SHA-1哈希值,是否有方法确定提交来自哪个分支?

如果你能告诉我如何使用Ruby Grit实现这一点,那就加分。


当前回答

要查找本地分支机构,请执行以下操作:

grep -lR YOUR_COMMIT .git/refs/heads | sed 's/.git\/refs\/heads\///g'

要查找远程分支,请执行以下操作:

grep -lR $commit .git/refs/remotes | sed 's/.git\/refs\/remotes\///g'

其他回答

虽然Dav认为信息没有直接存储是正确的,但这并不意味着你永远都找不到。这里有一些你可以做的事情。

查找提交所在的分支

git branch -a --contains <commit>

这将告诉您其历史中具有给定承诺的所有分支。显然,如果提交已经被合并,这就不太有用了。

搜索回流

如果您正在进行提交的存储库中工作,可以在reflog中搜索该提交的行。gitgc会删除90天以上的反射,因此如果提交时间太长,您将找不到它。也就是说,您可以这样做:

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--prett=oneline的别名,因此如果您想修改输出格式以使grep可以使用不同的内容,这就是您的出发点!

如果您不是在进行提交的存储库中工作,那么在这种情况下,您所能做的最好的工作就是检查reflog并查找提交首次引入存储库的时间;幸运的是,您获取了它提交到的分支。这有点复杂,因为您不能同时遍历提交树和reflog。您可能需要解析reflog输出,检查每个哈希,看看它是否包含所需的提交。

查找后续合并提交

这取决于工作流,但对于良好的工作流,在开发分支上进行提交,然后将其合并到中。您可以这样做:

git log --merges <commit>..

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

如果您希望能够做到这一点,您可能需要使用--noff选项来gitmerge,以强制创建合并提交,即使在快进情况下也是如此。(不过,不要过于急切。如果过度使用,这可能会让人困惑。)VonC对相关问题的回答有助于阐述这一主题。

例如,要发现c0118fa提交来自redesign_interactions:

* ccfd449 (HEAD -> develop) Require to return undef if no digits found
*   93dd5ff Merge pull request #4 from KES777/clean_api
|\
| * 39d82d1 Fix tc0118faests for debugging debugger internals
| * ed67179 Move &push_frame out of core
| * 2fd84b5 Do not lose info about call point
| * 3ab09a2 Improve debugger output: Show info about emitted events
| *   a435005 Merge branch 'redesign_interactions' into clean_api
| |\
| | * a06cc29 Code comments
| | * d5d6266 Remove copy/paste code
| | * c0118fa Allow command to choose how continue interaction
| | * 19cb534 Emit &interact event

您应该运行:

git log c0118fa..HEAD --ancestry-path --merges

然后向下滚动以找到最后一次合并提交。即:

commit a435005445a6752dfe788b8d994e155b3cd9778f
Merge: 0953cac a06cc29
Author: Eugen Konkov
Date:   Sat Oct 1 00:54:18 2016 +0300

    Merge branch 'redesign_interactions' into clean_api

使现代化

或者只需要一个命令:

git log c0118fa..HEAD --ancestry-path --merges --oneline --color | tail -n 1

我尝试了以上所有的解决方案,但没有一个对我有效。

以下是迄今为止对我有效的唯一方法(假设HEAD处于合理位置):

git log --branches --source | grep <sha>

#or if you also care about remotes
git log --branches --remotes --source | grep <sha>

分支的名称应位于行的末尾。

从文档中

--来源打印出命令行上给定的引用名称,通过该名称可以实现每次提交。

因此,这可能会根据HEAD所在的位置而改变,但对我来说,将HEAD放在主分支的最新提交时产生了我预期的结果。

用gitk进行目视检查——所有这些都可能有帮助。它为每个提交都有一个“分支”字段,但它显示了“可以到达”该提交的所有分支,而不一定是该提交所在的分支。请参见此处


旁白:

值得一提的是,这个问题有点用词不当。与其他SVC不同,在git中的分支只是指向提交历史/图中位置的临时指针。他们不“拥有”提交,也不“由”提交组成。它们本质上只是标签,在签出标签时更新到您推送的任何提交。因此,分支不是一系列提交,而是指向一系列提交的末端/末端的指针。因此,提交不“属于”或“来自”分支,它们只是图中的节点。

那么我们到底在这里做什么?我们正在使用可达性的概念。如果我们从每个分支指向的提交开始(“分支”的“结束”),并回溯历史,我们可以找到/达到哪些提交?我们说提交是“在”一个分支上,如果找到它们的唯一方法是在该特定分支上开始搜索。

注意,这不是一个稳定的事情。如果我们突然合并、重命名或重新设置分支的基础,那么我们的分支将发生变化,其中哪些提交可以通过(因此“on”)访问。这就是为什么在git中,“在某个特定分支机构上/由某个分支机构拥有”的承诺不是一个正式的或总是有意义的概念。(以及为什么这个问题没有明确的答案)

gitcheckout<SHA>->将使您进入分离的HEAD状态。

git rev parse--abbrev ref HEAD->将打印HEAD,因此此命令在这种状态下不起作用。

现在我们处于分离HEAD状态,可以使用以下命令获取分支名称。PS:如果您没有处于分离的HEAD状态,这将不起作用!

git branch -a --contains HEAD | sed -n 2p | awk '{ printf $1 }'

瞧!现在您有了分支名称。

除了在所有树中搜索直到找到匹配的哈希值之外,没有。