查找 Git 提交来自哪个分支
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2706797/
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
Finding what branch a Git commit came from
提问by Ethan Gunderson
回答by Cascabel
While Dav is correct that the information isn't directly stored, that doesn't mean you can't ever find out. Here are a few things you can do.
虽然 Dav 是正确的,信息没有直接存储,但这并不意味着你永远找不到。以下是您可以做的一些事情。
Find branches the commit is on
查找提交所在的分支
git branch -a --contains <commit>
This will tell you all branches which have the given commit in their history. Obviously this is less useful if the commit's already been merged.
这将告诉您在其历史记录中具有给定提交的所有分支。显然,如果提交已经被合并,这就没那么有用了。
Search the reflogs
搜索引用
If you are working in the repository in which the commit was made, you can search the reflogs for the line for that commit. Reflogs older than 90 days are pruned by git-gc, so if the commit's too old, you won't find it. That said, you can do this:
如果您在进行提交的存储库中工作,则可以在引用日志中搜索该提交的行。超过 90 天的 Reflog 被 git-gc 修剪,所以如果提交太旧,你将找不到它。也就是说,你可以这样做:
git reflog show --all | grep a871742
to find commit a871742. Note that you MUST use the abbreviatd 7 first digits of the commit. The output should be something like this:
找到提交 a871742。请注意,您必须使用提交的 abbreviatd 前 7 位数字。输出应该是这样的:
a871742 refs/heads/completion@{0}: commit (amend): mpc-completion: total rewrite
indicating that the commit was made on the branch "completion". The default output shows abbreviated commit hashes, so be sure not to search for the full hash or you won't find anything.
表明提交是在分支“完成”上进行的。默认输出显示缩写的提交哈希,因此请确保不要搜索完整的哈希,否则您将找不到任何内容。
git reflog show
is actually just an alias for git log -g --abbrev-commit --pretty=oneline
, so if you want to fiddle with the output format to make different things available to grep for, that's your starting point!
git reflog show
实际上只是 for 的别名git log -g --abbrev-commit --pretty=oneline
,所以如果你想摆弄输出格式以使 grep 可以使用不同的东西,那就是你的起点!
If you're not working in the repository where the commit was made, the best you can do in this case is examine the reflogs and find when the commit was first introduced to your repository; with any luck, you fetched the branch it was committed to. This is a bit more complex, because you can't walk both the commit tree and reflogs simultaneously. You'd want to parse the reflog output, examining each hash to see if it contains the desired commit or not.
如果您不在进行提交的存储库中工作,在这种情况下,您可以做的最好的事情是检查 reflog 并找到提交首次引入存储库的时间;幸运的是,您获取了它承诺的分支。这有点复杂,因为您不能同时遍历提交树和引用日志。您想解析 reflog 输出,检查每个哈希以查看它是否包含所需的提交。
Find a subsequent merge commit
查找后续合并提交
This is workflow-dependent, but with good workflows, commits are made on development branches which are then merged in. You could do this:
这是依赖于工作流的,但如果工作流良好,则会在开发分支上进行提交,然后将其合并。您可以这样做:
git log --merges <commit>..
to see merge commits that have the given commit as an ancestor. (If the commit was only merged once, the first one should be the merge you're after; otherwise you'll have to examine a few, I suppose.) The merge commit message should contain the branch name that was merged.
查看将给定提交作为祖先的合并提交。(如果提交只合并一次,第一个应该是您要进行的合并;否则我想您必须检查一些。)合并提交消息应包含已合并的分支名称。
If you want to be able to count on doing this, you may want to use the --no-ff
option to git merge
to force merge commit creation even in the fast-forward case. (Don't get too eager, though. That could become obfuscating if overused.) VonC's answer to a related questionhelpfully elaborates on this topic.
如果您希望能够指望这样做,您可能需要使用--no-ff
选项git merge
来强制合并提交创建,即使在快进的情况下也是如此。(不过,不要太急切。如果过度使用,这可能会变得模糊不清。)VonC 对相关问题的回答有助于详细说明这个主题。
回答by khichar.anil
This simple command works like a charm:
这个简单的命令就像一个魅力:
git name-rev <SHA>
git name-rev <SHA>
For example (where test-branchis the branch name):
例如(其中test-branch是分支名称):
git name-rev 651ad3a
251ad3a remotes/origin/test-branch
Even this is working for complex scenarios, like:
即使这也适用于复杂的场景,例如:
origin/branchA/
/branchB
/commit<SHA1>
/commit<SHA2>
Here git name-rev commit<SHA2>
returns branchB.
这里git name-rev commit<SHA2>
返回branchB。
回答by VonC
Update December 2013:
2013 年 12 月更新:
git-what-branch
(Perl script, see below) does not seem to be maintained anymore.git-when-merged
is an alternative written in Python that's working very well for me.
git-what-branch
(Perl 脚本,见下文)似乎不再维护。git-when-merged
是一种用 Python 编写的替代方案,对我来说效果很好。
It is based on "Find merge commit which include a specific commit".
它基于“查找包含特定提交的合并提交”。
git when-merged [OPTIONS] COMMIT [BRANCH...]
Find when a commit was merged into one or more branches.
Find the merge commit that broughtCOMMIT
into the specified BRANCH(es).Specifically, look for the oldest commit on the first-parent history of
BRANCH
that contains theCOMMIT
as an ancestor.
查找提交何时合并到一个或多个分支中。
找到带入COMMIT
指定 BRANCH(es)的合并提交。具体来说,在
BRANCH
包含COMMIT
作为祖先的第一父历史记录中查找最旧的提交。
Original answer September 2010:
2010 年 9 月的原始答案:
Sebastien Douchejust twitted(16 minutes before this SO answer):
Sebastien Douche只是发了推文(在这个 SO 答案前 16 分钟):
git-what-branch: Discover what branch a commit is on, or how it got to a named branch
git-what-branch:发现提交所在的分支,或者它如何到达命名分支
This is a Perl scriptfrom Seth Robertsonthat seems very interesting:
这是来自Seth Robertson的Perl 脚本,看起来很有趣:
SYNOPSIS
概要
git-what-branch [--allref] [--all] [--topo-order | --date-order ]
[--quiet] [--reference-branch=branchname] [--reference=reference]
<commit-hash/tag>...
OVERVIEW
Tell us (by default) the earliest causal path of commits and merges to cause the requested commit got onto a named branch. If a commit was made directly on a named branch, that obviously is the earliest path.
By earliest causal path, we mean the path which merged into a named branch the earliest, by commit time (unless
--topo-order
is specified).PERFORMANCE
If many branches (e.g. hundreds) contain the commit, the system may take a long time (for a particular commit in the Linux tree, it took 8 second to explore a branch, but there were over 200 candidate branches) to track down the path to each commit.
Selection of a particular--reference-branch --reference tag
to examine will be hundreds of times faster (if you have hundreds of candidate branches).EXAMPLES
概述
告诉我们(默认情况下)提交和合并的最早因果路径,以导致请求的提交进入命名分支。如果直接在命名分支上进行提交,那显然是最早的路径。
最早的因果路径是指在提交时间(除非
--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
[...]
This program does not take into account the effects of cherry-picking the commit of interest, only merge operations.
该程序不考虑挑选感兴趣的提交的影响,只考虑合并操作。
回答by Eugen Konkov
For example, to find that c0118fa
commit came from redesign_interactions
:
例如,要找到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
You should run:
你应该运行:
git log c0118fa..HEAD --ancestry-path --merges
And scroll down to find last mergecommit. Which is:
并向下滚动以查找上次合并提交。这是:
commit a435005445a6752dfe788b8d994e155b3cd9778f
Merge: 0953cac a06cc29
Author: Eugen Konkov
Date: Sat Oct 1 00:54:18 2016 +0300
Merge branch 'redesign_interactions' into clean_api
Update
更新
Or just one command:
或者只是一个命令:
git log c0118fa..HEAD --ancestry-path --merges --oneline --color | tail -n 1
回答by Jeff Bowman
git branch --contains <ref>
is the most obvious "porcelain" command to do this. If you want to do something similar with only "plumbing" commands:
git branch --contains <ref>
是执行此操作的最明显的“瓷器”命令。如果你只想用“管道”命令做类似的事情:
COMMIT=$(git rev-parse <ref>) # expands hash if needed
for BRANCH in $(git for-each-ref --format "%(refname)" refs/heads); do
if $(git rev-list $BRANCH | fgrep -q $COMMIT); then
echo $BRANCH
fi
done
(crosspost from this SO answer)
(来自这个 SO 答案的交叉帖子)
回答by phyatt
khichar.anil coveredmost of this in his answer.
khichar.anil在他的回答中涵盖了大部分内容。
I am just adding the flag that will remove the tags from the revision names list. This gives us:
我只是添加了从修订名称列表中删除标签的标志。这给了我们:
git name-rev --name-only --exclude=tags/* $SHA
回答by user1338062
A poor man's option is to use the tool tig
1on HEAD
, search for the commit, and then visually follow the line from that commit back up until a merge commit is seen. The default merge message should specify what branch is getting merged to where :)
一个可怜的人的选择是使用工具tig
1on HEAD
,搜索提交,然后在视觉上按照从该提交开始的行返回,直到看到合并提交。默认合并消息应该指定哪个分支合并到哪里:)
1Tig is an ncurses-based text-mode interface for Git. It functions mainly as a Git repository browser, but it can also assist in staging changes for commit at chunk level and act as a pager for output from various Git commands.
1Tig 是一个基于 ncurses 的 Git 文本模式界面。它主要用作 Git 存储库浏览器,但它也可以帮助在块级别提交更改并充当各种 Git 命令输出的寻呼机。
回答by pajp
As an experiment, I made a post-commit hook that stores information about the currently checked out branch in the commit metadata. I also slightly modified gitk to show that information.
作为一项实验,我制作了一个提交后挂钩,用于在提交元数据中存储有关当前检出分支的信息。我还稍微修改了 gitk 以显示该信息。
You can check it out here: https://github.com/pajp/branch-info-commits
你可以在这里查看:https: //github.com/pajp/branch-info-commits
回答by miro
I deal with the same problem (Jenkinsmultibranch pipeline) - having only commit information and trying to find a branch name where this commit originally came from. It must work for remote branches, local copies are not available.
我处理了同样的问题(Jenkins多分支管道)——只有提交信息并试图找到这个提交最初来自的分支名称。它必须适用于远程分支,本地副本不可用。
This is what I work with:
这就是我的工作:
git rev-parse HEAD | xargs git name-rev
Optionally you can strip the output:
(可选)您可以剥离输出:
git rev-parse HEAD | xargs git name-rev | cut -d' ' -f2 | sed 's/remotes\/origin\///g'
回答by Yates Zhou
I think someone should face the same problem that can't find out the branch, although it actually exists in one branch.
我认为有人应该面临找不到分支的相同问题,尽管它实际上存在于一个分支中。
You'd better pull all first:
你最好先拉所有:
git pull --all
Then do the branch search:
然后进行分支搜索:
git name-rev <SHA>
or:
或者:
git branch --contains <SHA>