[英]Git-svn merge two SVN branches
我已经阅读了很多关于git-svn
和合并的SO问题和博客。 有些人(尤其是中git-svn
手册页)警告不要使用我打算分支附近的任何地方合并dcommit
从。
其他的,像这样的SO回答 ,状态合并是罚款,只要我用我以前删除一个关机功能分支dcommitting
。
我有两个长寿SVN(和git)分支的设置:
svn/trunk
,git: master
) - 稳定分支 svn/devel
,git: devel
) - 我从中分支特征分支的主要开发分支(我可以将它们重新定位到devel
而不是合并)。 在上图中, (1)显示了过去的SVN历史,其中branches/devel
已合并到trunk
。
(2)表明我已成功dcommitted
当前的开发重新dcommitted
回SVN。
问题:我可以使用git-svn
合并两个SVN分支,以便历史显示合并点(如SVN本身可以做到的)? 换句话说:如果我如(3)所示从master
那里dcommit
,会发生什么?
这会弄乱我的SVN(或git)历史吗? 或者这只是简单地忘记了devel
被合并为master
?
编辑:如果git
只是忘记了devel
被合并到master
, dcommiting
从点(3)进行dcommiting
并将所有提交应用为单个补丁之间有区别吗?
再深入研究一下这个问题,我发现当dcommit
时,git支持在SVN分支上设置svn:mergeinfo
属性:
git svn dcommit --mergeinfo "/branches/somebranch:1-3"
NB! svn:mergeinfo
被命令行中给出的任何内容覆盖 ,因此请小心列出以前的合并 。
虽然更新的git版本添加了config参数来自动设置此属性:
config key: svn.pushmergeinfo
我对自动mergeinfo有一些麻烦 - 由于一个原因或其他GIT计算错误而我无法使其工作。
解决方案: git-merge-svn
为了自动化这个过程,我编写了一个shell脚本git-merge-svn ,它可以用来合并两个SVN分支,并在dcommit上设置正确的svn:mergeinfo
。
该脚本处理两种情况:
git merge
使用这个脚本,我只能在git端生成这些合并并保留合并信息,以便GIT图很好地显示日志:
用法示例:
dcommit
devel6 to SVN( 需要获取提交的SVN修订号) git merge-svn devel6
最后的commant输出:
% git merge-svn devel6
About to do an SVN merge: devel6 -> testtunk6
* NEW MERGE COMMIT
|\
| * devel6 [7b71187] (r102)
* | testtunk6 [0682a45] (r101)
\|
* [273d6d6] (r100)
STEP 1: GIT merge
Executing:
git merge devel6
Continue? (y/n) [n]: y
Merge made by the 'recursive' strategy.
testfile | 1 +
1 file changed, 1 insertion(+)
STEP 2: SVN dcommit
executing:
git svn dcommit --mergeinfo
/idp/branches/devel:9-32,35-41 /idp/branches/devel6:89 /idp/branches/devel6:94 /idp/branches/devel6:93 /idp/branches/devel6:96 /idp/branches/devel6:97 /idp/branches/devel6:99 /idp/branches/devel6:100 /idp/branches/devel6:102
Continue? (y/n) [n]: y
Committing to https://my.svn.host/svn/auth/idp/branches/testtunk6 ...
M testfile
Committed r103
M testfile
Found merge parent (svn:mergeinfo prop): 7b71187fc371d3f86658c5850009e63be88157ac
r103 = 87759323cbadd38bac78087d57b6870a926287e7 (refs/remotes/svn/testtunk6)
No changes between 3fb2168cfbbe605fbd810d76513443203a85a549 and refs/remotes/svn/testtunk6
Resetting to the latest refs/remotes/svn/testtunk6
Git和Svn有不同的数据结构来保存历史记录。
Svn使用一棵简单的树。 即每个提交只有一个父,但一个提交可能有几个子(分支)。 所以,Svn不支持合并。 他们称之为“合并”的东西实际上是变更集移植,git中最接近的类比是rebase
或者也许是cherry-pick
。 从版本1.5开始,Svn支持元信息属性svn:mergeinfo
,它有助于以某种方式跟踪“合并”的内容,但它看起来主要是一种解决方法,这解释了为什么Svn中的分支如此难以使用。 合并点是一个提交,它将所有合并的变更集和冲突解决方案压缩为一个变更集,可能使用svn:mergeinfo
属性进行注释。
Git使用Directed非循环图 ,这是描述历史合并和分支的非常自然的方式。 合并点只是另外两个(或更多!)父项的提交。 所以,你的(3)图片是合并提交。 因此,所有历史记录看起来都很自然,它可以在当前点的历史图表上访问所有提交。
Git-Svn网桥尝试尽力处理Svn设计缺陷,在进行dcommit
之前,它通常会dcommit
当前Svn分支顶部的所有合并提交。 〜2年前,git-svn无法提供svn:mergeinfo
,所以你要问的是不可能的。 此外,当您dcommit
,git会创建一个“双”提交“几乎”链接到svn提交,因此它会重写原始提交。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.