如何欺骗git-svn识别用svn进行的合并?

Ant*_*nen 5 git merge git-svn

我们有一个SVN设置,具有稳定的主干和不稳定的开发分支.开发工作(主要)在分支上完成,然后在部署之前合并到主干.

我使用git-svn作为我的SVN客户端.我从unstable到trunk的合并过程如下:

git svn fetch
git co -b trunk svn/trunk 
git merge --no-ff svn/unstable
git svn dcommit
Run Code Online (Sandbox Code Playgroud)

svn/* 是远程SVN分支.

这当然要求在我完成之前没有人向行李箱提交任何东西,但这在实践中不是问题.

这个过程的好处是git现在在我的本地存储库中记录合并提交的父级.这对我的同事没有好处,但它允许git在进行合并时计算共同的祖先.这是非常理想的.

这就是问题.当其他人合并时,git不知道它.这是一个例子:

  o-...-A---o---C--- unstable
 /
X--...--B---o---o--- stable
Run Code Online (Sandbox Code Playgroud)

不稳定的分支是在X点创建的.在A点,我们决定将不稳定分支的变化合并到B点的稳定分支.共同的祖先是正确的X.

由于合并未记录在git历史记录中,因此在C处的以下合并再次假定X是共同的祖先.我希望它是A,如下图所示:

  o-...-A---o---C--- unstable
 /       \
X---...---B---o---o--- stable
Run Code Online (Sandbox Code Playgroud)

获得一个看起来像图中所示的图表并不是绝对必要的.任何将A识别为共同祖先的图表都很好.

我有一些选择,例如正确使用git-filter-branch或"假"提交,它永远不会被SVN拒之门外.但是到目前为止,我的尝试都没有充分发挥作用.

我很感激你能提出的任何想法.该程序不必是自动的.合并是非常罕见的,我可以忍受"手工"这样做的痛苦.

小智 2

另一种替代方法是使用 Grafts 文件,它允许您覆盖提交的父级,而无需实际操作历史记录。

这意味着,在 SVN 存储库中看到合并后,您只需向 .git/info/grafts 添加一行,其中包含合并提交 (M) 及其父项 (A,B) 的 SHA-1。

      o-...-A---o---D--- unstable
     /       
    X-----B---M---o---o--- stable

A = 31423cd8a838f984547a908777308d846043cbda
B = d99cfccb1f859a8f1dbfac95eec75227fe518b23
M = 13319a54d3e3d61b501e7cc6474c46f37784aaa3
Run Code Online (Sandbox Code Playgroud)

为了从 AM 创建链接,您可以将 M 的父母指定为 B 和 A。移植文件的格式相当简单:

commit newparent1 ... newparentN
Run Code Online (Sandbox Code Playgroud)

这意味着您将以下(相当长的)行添加到移植文件中:

13319a54d3e3d61b501e7cc6474c46f37784aaa3 d99cfccb1f859a8f1dbfac95eec75227fe518b23 31423cd8a838f984547a908777308d846043cbda
Run Code Online (Sandbox Code Playgroud)

Git 现在会假装这次合并确实发生了。缺点是,这不会通过 git push/fetch/clone 传播,但这不应该成为个人开发的主要问题。