我的git存储库有三个分支devel
,stable
和customers/acme_patches
.很久以前,它stable
是分叉的devel
,并且所有的错误修正都发生在stable
.时不时地stable
被合并回来devel
.customers/acme_patches
是一个具有一些客户特定补丁的分支.该分支未合并为devel
和stable
.
一些ASCII艺术来说明场景:
o---o---o customers/acme_patches? / o---o---1---o---o---o stable / \ \ o---o---o---2---o---o---o---o devel \ o---o---o customers/acme_patches?
现在我想知道:
customers/acme_patches
分叉的是什么分支- devel
或者stable
?我只是知道它过去曾分离过其中一个,但我不知道哪个.例如它可能已经提交1
或2
在上图中.
我一直在玩git log --oneline --graph
,gitk
但自从customers/acme_patches
分开了几百次提交之后,很难按照画出的线条.
是否有一个快速命令(一个小脚本也可以),它可以以某种方式跟随提交customers/acme_patches
向后找到第一个提交有两个孩子(叉点),然后确定是否在stable
或在中提交devel
?
在最好的情况下,我可以执行类似的操作(请原谅,我在Windows上):
C:\src> git fork-origin customers/acme_patches
stable
Run Code Online (Sandbox Code Playgroud)
Von*_*onC 24
使用git 1.9/2.0(2014年第1季度),您可以git merge-base --fork-point
根据Git请求最佳共同祖先.
你可以看到这个新选项:
而且,由于提交ad8261d从约翰饲养(johnkeeping
),git rebase
可以使用相同的新--fork-point
选项,它可以派上用场,如果您需要衍合分支像customers/acme_patches
到devel
.
(我不是说这在你的具体情况下会有意义)
注意:Git 2.16(2018年第一季度)确实澄清并增强了" merge-base --fork-point
"的文档,因为很清楚它的计算方法,但不是为什么/为什么.
见Junio C Hamano()提交6d1700b(2017年11月9日).(由Junio C Hamano合并- -在提交022dd4a,2017年11月27日)gitster
gitster
merge-base --fork-point
doc:澄清示例和失败模式图示的历史用于解释
--fork-point
名为三个关键点的模式提交从最旧到最新的B3,B2和B1,这很难阅读.
将它们重新标记为B0,B1,B2.
还说明了使用该--fork-point
设施的rebase之后的历史.该文本已经提到使用reflog,但描述并不清楚我们通过使用reflog获得了什么好处.
澄清它是要找到已知位于远程跟踪分支顶端的提交.
这反过来又需要用户知道基本假设的后果,即,reflog条目的到期将使得无法确定哪些提交位于远程跟踪分支的尖端,并且我们在有疑问时失败(而不是随机给出)甚至没有警告的错误结果).
另一个限制是,如果你没有从远程跟踪分支的尖端而是从中间分叉,它将没有用处.
描述他们.
所以文档现在写道:
在使用
topic
创建的分支上工作后git checkout -b topic origin/master
,远程跟踪分支的历史origin/master
可能已经被重绕并重建,从而导致了这种形状的历史:
o---B2
/
---o---o---B1--o---o---o---B (origin/master)
\
B0
\
D0---D1---D (topic)
Run Code Online (Sandbox Code Playgroud)
其中,
origin/master
用于指向在提交B0,B1,B2,现在它在B处点,你topic
当分支开始在它的背面顶部origin/master
是在B0,和你建立三个提交,D0,D1和d,在它的上面.
想象一下,您现在想要topic
在更新的基础上重新设计您所做的工作origin/master
.在这种情况下,
git merge-base origin/master topic
将返回B0的家长在上面的图片,但是B0^..D
是不是你想重播对B的顶部提交的范围(它包括B0,这是不是你写的东西,它是一个提交其他当它的尖端从B0移动到B1时丢弃.
git merge-base --fork-point origin/master topic
旨在帮助这种情况.
它不仅需要B,还需要B0,B1和B2(即存储库的reflog知道的远程跟踪分支的旧技巧),以查看构建主题分支的提交并找到B0,允许您仅重放对你主题的提交,不包括后来丢弃的提交.于是
$ fork_point=$(git merge-base --fork-point origin/master topic)
Run Code Online (Sandbox Code Playgroud)
会找到B0,和
$ git rebase --onto origin/master $fork_point topic
Run Code Online (Sandbox Code Playgroud)
将重放B顶部的D0,D1和D以创建此形状的新历史记录:
o---B2
/
---o---o---B1--o---o---o---B (origin/master)
\ \
B0 D0'--D1'--D' (topic - updated)
\
D0---D1---D (topic - old)
Run Code Online (Sandbox Code Playgroud)
需要注意的是,您的存储库中较旧的reflog条目可能会过期
git gc
.
如果远程跟踪分支的reflog中不再出现B0origin/master
,则该--fork-point
模式显然无法找到并失败,从而避免给出随机且无用的结果(例如B0的父级,就像没有--fork-point
选项的同一命令一样).此外,您使用
--fork-point
模式的远程跟踪分支必须是您的主题从其提示分叉的主题.
如果你从旧犯比前端分叉,这种模式不会找到叉点(想象一下在上面的示例历史B0不存在,origin/master
开始在B1,转移到B2,然后B,你叉你在话题origin/master^
的时候origin/master
了B1;历史的形状与上面相同,没有B0,B1的父级是git merge-base origin/master topic
正确找到的,但--fork-point
模式不会,因为它不是以前提交的提交之一origin/master
) .
嗯,这个答案可能没有完美的解决方案.我的意思是fork-origin
git中没有等价物(据我所知).由于stable
分支合并到devel
,你acme_patches
(1)是两个devel
和stable
分支.
你可能做的是:
git branch --contains $(git merge-base customers/acme_patches devel stable)
Run Code Online (Sandbox Code Playgroud)
如果你有稳定而不开发,或开发并且不稳定,那么你就知道它来自哪里.
例如,在案例2中,您将拥有
$ git branch --contains $(git merge-base customers/acme_patches devel stable)
customers/acme_patches
devel
Run Code Online (Sandbox Code Playgroud)
而在案例1中你会有
$ git branch --contains $(git merge-base customers/acme_patches devel stable)
customers/acme_patches
devel
stable
Run Code Online (Sandbox Code Playgroud)
因为它现在在两个分支上(因为从稳定到开发的合并)
归档时间: |
|
查看次数: |
17785 次 |
最近记录: |