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

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


当前回答

我处理了同样的问题(Jenkins多分支管道)——只有提交信息,并试图找到该提交最初来源的分支名称。它必须适用于远程分支,本地副本不可用。

这是我的工作:

git rev-parse HEAD | xargs git name-rev

也可以剥离输出:

git rev-parse HEAD | xargs git name-rev | cut -d' ' -f2 | sed 's/remotes\/origin\///g'

其他回答

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

如果OP试图确定在创建特定提交时分支所遍历的历史(“在给定SHA-1哈希值的情况下,找出提交来自哪个分支”),那么如果没有reflog,Git对象数据库中就没有任何记录显示哪个命名的分支绑定到了什么提交历史。

(我将此作为回复评论的回复发布。)

希望这个脚本能说明我的观点:

rm -rf /tmp/r1 /tmp/r2; mkdir /tmp/r1; cd /tmp/r1
git init; git config user.name n; git config user.email e@x.io
git commit -m"empty" --allow-empty; git branch -m b1; git branch b2
git checkout b1; touch f1; git add f1; git commit -m"Add f1"
git checkout b2; touch f2; git add f2; git commit -m"Add f2"
git merge -m"merge branches" b1; git checkout b1; git merge b2
git clone /tmp/r1 /tmp/r2; cd /tmp/r2; git fetch origin b2:b2
set -x;
cd /tmp/r1; git log --oneline --graph --decorate; git reflog b1; git reflog b2;
cd /tmp/r2; git log --oneline --graph --decorate; git reflog b1; git reflog b2;

输出表明,没有任何方法知道使用“Add f1”的提交是来自远程克隆/tmp/r2的分支b1还是b2。

(此处为输出的最后一行)

+ cd /tmp/r1
+ git log --oneline --graph --decorate
*   f0c707d (HEAD, b2, b1) merge branches
|\
| * 086c9ce Add f1
* | 80c10e5 Add f2
|/
* 18feb84 empty
+ git reflog b1
f0c707d b1@{0}: merge b2: Fast-forward
086c9ce b1@{1}: commit: Add f1
18feb84 b1@{2}: Branch: renamed refs/heads/master to refs/heads/b1
18feb84 b1@{3}: commit (initial): empty
+ git reflog b2
f0c707d b2@{0}: merge b1: Merge made by the 'recursive' strategy.
80c10e5 b2@{1}: commit: Add f2
18feb84 b2@{2}: branch: Created from b1
+ cd /tmp/r2
+ git log --oneline --graph --decorate
*   f0c707d (HEAD, origin/b2, origin/b1, origin/HEAD, b2, b1) merge branches
|\
| * 086c9ce Add f1
* | 80c10e5 Add f2
|/
* 18feb84 empty
+ git reflog b1
f0c707d b1@{0}: clone: from /tmp/r1
+ git reflog b2
f0c707d b2@{0}: fetch origin b2:b2: storing head

2013年12月更新:

sschuberth注释

gitwhat分支(Perl脚本,见下文)似乎不再被维护。合并时的git是一种用Python编写的替代方法,对我来说非常有用。

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

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

查找提交合并到一个或多个分支的时间。查找将commit带入指定BRANCH的合并提交。具体来说,在包含commit作为祖先的BRANCH的第一个父历史上查找最早的提交。


原答复2010年9月:

Sebastien Douche刚刚推了推(在这个SO回答之前16分钟):

gitwhatbranch:发现提交所在的分支,或者它是如何到达命名分支的

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

简介

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

概述告诉我们(默认情况下)提交和合并的最早因果路径,以使请求的提交到达指定的分支。如果直接在指定的分支上进行提交,那么这显然是最早的路径。所谓最早的因果路径,我们指的是最早合并到命名分支的路径,即提交时间(除非指定了拓扑顺序)。性能如果许多分支(例如数百个)包含提交,系统可能需要很长时间(对于Linux树中的特定提交,探索一个分支需要8秒,但有超过200个候选分支)来跟踪每个提交的路径。选择要检查的特定引用分支引用标记将快数百倍(如果您有数百个候选分支)。示例

 # 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
   [...]

该程序不考虑樱桃选择感兴趣的提交的影响,只考虑合并操作。

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

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

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

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

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

例如,要发现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