有没有办法通过给定的SHA-1哈希值找出提交来自哪个分支?
如果您能告诉我如何使用Ruby Grit完成此操作,将获得额外的奖励。
有没有办法通过给定的SHA-1哈希值找出提交来自哪个分支?
如果您能告诉我如何使用Ruby Grit完成此操作,将获得额外的奖励。
虽然Dav是正确的,信息并没有直接存储,但这并不意味着你永远无法找到。以下是一些你可以做的事情。
git branch -a --contains <commit>
这会告诉你所有历史记录中包含给定提交的分支。如果提交已经合并,则显然这不太有用。
如果您正在该提交所在的存储库中工作,可以搜索该提交的reflog行。 git-gc清理90天前的reflog,因此,如果提交过旧,则无法找到它。 也就是说,您可以执行以下操作:
git reflog show --all | grep a871742
查找提交记录 a871742。请注意,您必须使用提交记录的前7个缩写字符。输出应该类似于以下内容:
a871742 refs/heads/completion@{0}: commit (amend): mpc-completion: total rewrite
说明提交是在分支 "completion" 上进行的。默认输出显示缩写的提交哈希值,因此确保不要搜索完整的哈希值,否则将找不到任何内容。
git reflog show
实际上只是 git log -g --abbrev-commit --pretty=oneline
的别名,因此如果您想调整输出格式以使不同的内容可供 grep 搜索,那么这是您的起点!
如果您没有在提交所在的存储库中工作,则在这种情况下,您最好检查 reflogs 并查找提交首次引入到您的存储库的时间;带着希望,您已经获取了它提交的分支。这有点更复杂,因为您无法同时遍历提交树和 reflogs。您需要解析 reflog 输出,检查每个哈希值是否包含所需的提交。
这取决于工作流程,但对于良好的工作流程,提交是在开发分支上进行的,然后合并到主干。您可以执行以下操作:
git log --merges <commit>..
查看以给定提交为祖先的合并提交。(如果该提交只被合并了一次,则第一个合并提交应该是您要查找的;否则,您可能需要检查几个。) 合并提交消息应包含已合并的分支名称。
如果希望能够依赖此操作,可能需要使用--no-ff
选项进行git merge
以强制创建合并提交,即使在快进情况下也是如此。(不过不要过于急切,如果过度使用可能会使事情变得复杂。)VonC回答了相关问题,有助于详细解释这个主题。
--no-ff
选项来确保始终存在合并提交,这样您就可以随时追踪给定提交的路径,它是如何朝着主分支合并的。 - Cascabel-a
标志,例如:git branch -a --contains <commit>
。 - Jonathan Daymerge --no-ff
来可靠地记录分支名称。但是,除此之外,请将分支名称视为临时短标签,将提交说明视为永久标签。“在开发过程中我们用什么短名称来指代它?”这个问题确实不应该像“这个提交做了什么?”这个问题那样重要。 - Cascabel这个简单的命令非常好用:
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。
git name-rev --name-only <SHA>
对于仅获取分支名称更加有用。我的问题是...它在任何情况下是否可能返回多个分支? - dnk8ngit name-rev --refs="refs/heads/*" --name-only <SHA>
。 - Andrey Semakingit name-rev
命令时,给出了我从未使用过的分支,特别是来自另一个用户的远程分支。这完全没有意义! - vinc17c0118fa
提交是从 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
git merge -m“任意字符串”
将隐藏源分支和目标分支的信息。 - qneillMerge: f6b70fa d58bdcb
。您可以按照自己的意愿为合并提交命名。这不会有任何影响。 - Eugen Konkov2013年12月更新:
git-what-branch
(Perl脚本,请参见下文)似乎不再维护。git-when-merged
是一种替代方案,用Python编写,对我来说非常有效。
它基于 "Find merge commit which include a specific commit"。
git when-merged [OPTIONS] COMMIT [BRANCH...]
COMMIT
合并到指定分支的合并提交。
具体而言,查找包含COMMIT
作为祖先的BRANCH
第一父历史上最早的提交。
2010年9月的原始答案:
Sebastien Douche刚才发推(在此SO答案之前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
[...]
这个程序不考虑挑选感兴趣的提交(commit)对结果的影响,只考虑合并操作。
khichar.anil 在他的回答中已经涵盖了大部分内容。
我只是添加了一个标志,它将从版本名称列表中删除标记。这给了我们:
git name-rev --name-only --exclude=tags/* $SHA
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
HEAD
在合适的位置):git log --branches --source | grep <sha>
#or if you also care about remotes
git log --branches --remotes --source | grep <sha>
HEAD
所在位置而改变,但对我来说,将HEAD
放在我的主分支上最新的提交产生了我期望的结果。gitk --all
进行目视检查也可能有所帮助。它为每个提交都有一个“分支”字段,但它显示可以“到达”该提交的所有分支,而不一定是该提交所在的分支。参见这里。
我处理与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'
简单来说,Git不会存储提交所在分支的名称。尝试重构此信息的技巧似乎并不总是奏效。
tig
1在HEAD
上搜索提交,然后从该提交开始沿着线条向上追踪,直到看到合并提交。默认的合并消息应该指定将哪个分支合并到哪里 :)
1 Tig是一个基于ncurses的Git文本模式界面。它主要作为Git仓库浏览器,但也可以在分块级别上协助暂存变更以进行提交,并作为各种Git命令输出的分页器。