我使用 git-blame 来查找特定的提交。现在我想找到它最初来自的分支。(从那里,我将使用分支名称来查找特定票证)
让我们将“原始分支”定义为“在分支合并到任何其他分支之前提交的分支”。
我使用 git-blame 来查找特定的提交。现在我想找到它最初来自的分支。(从那里,我将使用分支名称来查找特定票证)
让我们将“原始分支”定义为“在分支合并到任何其他分支之前提交的分支”。
就像其他人所说的那样,如果您要查找的分支不是您指责此提交的存储库的本地分支(例如,仅在远程开发人员的个人存储库中的分支),那么您就完蛋了。
但是假设你可以看到广受欢迎的分支,并且当然你有提交的哈希,比如说d590f2...
,部分答案是你可以这样做:
$ git branch --contains d590f2
tests
* master
然后,只是为了确认你有罪魁祸首:
$ git rev-list tests | grep d590f2
当然,如果d590f2
已经合并到多个分支中,则必须比这更微妙。
这在 git 中并不适用。分支是每个存储库的本地概念:一个人的“local-stuff”分支可以与另一个人的“local-stuff”分支完全分开。如果您执行诸如查看主要集成分支和查询提交以及删除两者之间的所有合并基础之类的操作,则应该能够获得提交历史记录的子树,该子树可能会有所启发……或可能不会. 例如,如果您跟踪从查询提交到“master”的链接,您应该希望找到带有有用注释的合并提交,说明合并来自哪里......但这些信息只是信息性的,没有以某种方式记录,旨在自动检索.
例如gitk some-commit...master
(几乎是 的缩写gitk some-commit master --not $(git merge-base some-commit master)
)
Git 分支只不过是一个“指向提交的命名指针”(这是一个与其他知名 VCS 完全不同的概念)。
这种情况很清楚,commit A is on branch-1
,commit B on branch-2
:
o A [branch-1]
|
o | B [branch-2]
| |
合并后变得不清楚 A(或 B)最初是 onbranch-1
还是branch-2
:
o [branch-1] [branch-2]
|
o merged
|\
| o A
| |
o | B
| |
如果您标记了 A 的父提交,也许您可以猜测提交 A 是哪个 Git 分支,例如release-1
,并且您知道该标记仅用于branch-1
.
o [branch-1] [branch-2]
|
o merged
|\
| o A
| |
o | B
| |
| o <release-1]
| |
我试一试,由于不完全确定,请发表评论,但我相信它可以完成工作。
仅当分支在合并到 master 之前仍然指向尖端时,以下操作才有效,如果分支位于同一个 repo 上,情况就是这样:
o [master]
|
o merged branch "great-feature" into master
|\
| o A [great-feature]
| |
o | B
| |
如果不是这种情况(例如,如果您从另一个 repo 中提取),您仍然可以手动重新创建它们。
首先获取您的提交所在的分支:
$ git branch -a --contains=<sha-of-B>
*master
great-feature
然后对于每个分支获取将它们的头部与提交分开的提交数:这是输出指定范围的 git log 的行数:
$ git log --pretty=oneline <sha-of-B>..great-feature | wc -l
1
$ git log --pretty=oneline <sha-of-B>..master | wc -l
4
所以B最接近great-feature,这意味着它是在其中创建的。
这可以做成一个很好的脚本,随时将它添加到答案中(我不擅长这个)
首先确保您从远程获取更改
$ git fetch --all
和,
$ git branch -a --contains d590f2
如果没有-a选项,您将无法找到仅存在于远程分支上的提交
当您在分支上时,“原始分支”已合并到。你可以运行:
git log <SHA>..HEAD --ancestry-path --merges
此命令将merge
显示<SHA>..HEAD
. 你需要最后一个。
例如对于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 <sha>..HEAD --merges
!
此命令显示 master 和 commit 之间发生的合并;该命令的最后一个提交输出是包含它的第一个合并提交。它通常包含分支名称,因此即使分支被删除,您也可以找到它的名称。
要仅获取分支的名称,只需键入git log <sha>..HEAD --merges --oneline |tail -1
这似乎不是一个可以通过 git 以 100% 精度回答的问题。
git branch --contains --merge <sha1>
返回提交合并到的所有分支和原始分支的列表。 --no-merged返回包含提交的所有后续分支,因为它们在合并点之后分支。
因此,您可以获得每个合并但不是原始分支的列表,并且在命令执行之前删除的任何分支都会丢失(或者您查看 reflogs)
结果
git branch --contains <sha1 for "added feature/inital 1">
* develop
feature/inital
feature/subsequent1
git branch --contains <sha1 for "added feature/inital 1"> --merged
* develop
feature/inital
git branch --contains <sha1 for "added feature/inital 1"> --no-merged
feature/inital
测试脚本
function mkbranch {
git checkout -b $1
git push --set-upstream origin $1
}
# Develop
mkbranch develop
for f in 1 2 3; do date > file${f}.txt; git add file${f}.txt; git commit -m "added develop $f"; done
git push
# Initial Feature Branch
mkbranch feature/inital
for f in 1 3; do date > file${f}.txt; git add file${f}.txt; git commit -m "modified feature/inital $f"; done
git push
# Merge
git checkout -b develop
git merge feature/inital
git push
# Next Feature Branch
mkbranch feature/subsequent1
for f in 1 3; do date > file${f}.txt; git add file${f}.txt; git commit -m "modified feature/subsequent1 $f"; done
git push
这对我来说足够好,可以从 Jenkins 工作区中的分离头获取分支名称:
git show -s --pretty=%d