繁体   English   中英

Git-svn合并了两个SVN分支

[英]Git-svn merge two SVN branches

我已经阅读了很多关于git-svn和合并的SO问题和博客。 有些人(尤其是中git-svn手册页)警告不要使用我打算分支附近的任何地方合并dcommit从。

其他的,像这样的SO回答 ,状态合并是罚款,只要我用我以前删除一个关机功能分支dcommitting

我有两个长寿SVN(和git)分支的设置:

  • trunk (git-svn: svn/trunk ,git: master ) - 稳定分支
  • branches / devel (git-svn: 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被合并到masterdcommiting从点(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中合并 - 将事先进行git merge
  • 分支已经在git中合并(但不在SVN中) - 将遍历前一个祖先的合并提交修订。

使用这个脚本,我只能在git端生成这些合并并保留合并信息,以便GIT图很好地显示日志:

git-merge-svn结果

用法示例:

  1. devel6上做一些提交
  2. dcommit devel6 to SVN( 需要获取提交的SVN修订号)
  3. 看看testtunk6 - 是的,我知道我在名字上写了一个拼写错误;-)
  4. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM