【发布时间】:2011-11-24 18:08:50
【问题描述】:
在我做了 git svn clone --stdlayout ... 之后,一切看起来都很好,我已经转换了远程分支。但是当 git log --graph 时,我没有看到任何分支合并图。正常吗?
【问题讨论】:
-
没用过真的支持合并的svn,不过是的,恐怕这很正常。
在我做了 git svn clone --stdlayout ... 之后,一切看起来都很好,我已经转换了远程分支。但是当 git log --graph 时,我没有看到任何分支合并图。正常吗?
【问题讨论】:
自 2008 年夏天发布的 1.5.0 版本以来,Subversion 支持合并跟踪。 Subversion 将执行合并的信息保存为合并目标上设置的 svn:mergeinfo 属性,无论是分支目录,如 ^/trunk/,还是任何其他目录。
Git 和 Subversion 中的合并跟踪机制之间存在重大差异:
整个分支合并。
当你在 master 分支上时,命令
$ git merge some-branch
导致合并提交,其第一个父级设置为 master 引用的提交,第二个父级设置为 some-branch 引用的提交(我不此处不考虑快进和冲突合并)。
对于 git,这意味着创建的合并提交包括 master 和 some-branch 的整个历史。
当你签出 ^/trunk/ 分支到 svn 工作副本然后运行
$ svn merge ^/branches/some-branch trunk-working-copy
Subversion 将在 trunk-working-copy 目录上设置 svn:mergeinfo 属性,如下所示:
/branches/some-branch:10-20,30-40,50-60
范围 10-20,30-40,50-60 包括那些尚未从 ^/ 合并到 ^/trunk/ 分支的修订版分支/一些分支/(Subversion 会自动检测它们)。
Mergeinfo 属性只指定那些曾经合并到分支中的修订。并且由用户来检查所有这些合并的修订是否包含分支的整个历史。
Cherry-pick 合并。
当您需要将来自单个提交的更改合并到您的 master 分支中时,您可以运行
$ git cherry-pick bc347a8
在此之后,git 创建了一个包含相应更改的提交,并将一个父级设置为先前由 master 分支引用的提交。
也就是说,git 不会为cherry-pick 创建任何类型的合并提交。因此,git 无法通过其图形结构跟踪精心挑选的提交。
相反,Subversion 确实通过调整 svn:mergeinfo 属性来跟踪cherry-pick 合并:
$ svn merge -c100 ^/branches/some-branch trunk-working-copy
这个命令很简单,它调整svn:mergeinfo如下:
/branches/some-branch:100
这意味着 Subversion 会跟踪cherry-pick 合并。
因此,翻译后您不会收到合并提交。据我所知,git-svn 在合并历史方面存在某些问题。
但作为 subgit 开发人员,我不得不说 subgit 应该正确处理合并跟踪信息。很可能在您的分支上设置的 svn:mergeinfo 属性不包括合并到它们的分支的整个历史。这是如何发生的:
要解决这个问题,您必须找到合并跟踪信息的跳过部分并将其添加到您的分支中:
尝试查找尚未合并的修订:
$ svn mergeinfo --show-revs eligible ^/branches/some-branch/@HEAD ^/trunk/@HEAD
输出必须包含您尚未从 ^/branches/some-branch/ 合并到 ^/trunk/ 的所有修订。
尝试通过svn合并尚未合并的修订。
作为一个很好的奖励,您可以参考与合并跟踪相关的 SubGit specification,它有一些我上面所说的漂亮图表。
【讨论】:
Subversion 轨道在 svn:mergeinfo 属性的帮助下合并。虽然您的工具可能不会将历史记录显示为图表,但它本质上不是线性的。实际上 svn:mergeinfo 比 Git 合并提交更强大(尽管这种能力可能没有实际用处)
SubGit 之类的工具会在可能的情况下将 svn:mergeinfo 转换为合并提交。
我正在使用我推荐的工具(SubGit),但 git-svn 在双向翻译合并方面确实很弱。
【讨论】:
subgit install repos。安装 SubGit 后,您只需使用 git 运行,例如,git clone ssh://user@host/svn/repos,更详细的配置示例请参阅 SubGit 网站上的文档。
使用 git-svn 不会改变 SVN 本身具有线性历史的事实,因此从技术上讲,所有合并都是快进,用 git 术语来说。没有合并提交,因此图中也没有合并。
【讨论】: