git-svn有一个与精选提交相关的严重问题:
假设您已经提交了 a1b2c3f9,它已经被 dcommitted 到 svn 存储库中:
$ git show a1b2c3f9
commit a1b2c3f9...
Author: Happy Dev <happyd@43fe5c0-...>
Date: Mon Nov 14 13:01:38 2011 +0000
Commit message
git-svn-id: https://host/svn/branches/some-branch@1000 43fe5c0-...
看到这条git-svn-id行了吗?这就是git-svn如何理解您的提交在 Subversion 存储库中的位置。
现在你想挑选这个提交到你当前所在的master分支:
$ git cherry-pick a1b2c3f9
如果没有合并冲突,git 会创建一个新的提交,比如9f3c2b1a,这里我们有:
$ git show 9f3c2b1a
commit 9f3c2b1a...
Author: Happy Dev <happyd@43fe5c0-...>
Date: Mon Nov 14 13:01:39 2011 +0000
Commit message
git-svn-id: https://host/svn/branches/some-branch@1000 43fe5c0-...
因此,Git 创建了一个包含完全相同消息的提交。这造成了严重的问题。以前版本的git-svn将此类提交发送到错误的分支 - ^/branches/some-branch而不是^/trunk/。
这个问题已经在最新版本的 Git 中得到修复。但还有一个仍然存在:
git-svn不尊重 Subversion 的合并跟踪机制。
Subversion 跟踪执行的cherry-picks的合并信息,所以命令
$ svn merge -c 1000 ^/branches/some-branch trunk-working-copy
调整trunk-working-copy的svn:mergeinfo属性如下:
+ /branches/some-branch: 1000
这样,Subversion 就知道这个特定的版本已经合并到^/trunk/分支中,因此它会在进一步的合并中跳过这个更改。
当您运行git cherry-pick
然后git svn dcommit
Subversion 存储库不会获得svn:mergeinfo修改。
免责声明如下:
目前我不在SmartGit上工作,但我与 SmartGit 开发人员保持密切联系。
Syntevo公司开发了SmartGit——一个很好的git-svn替代品。这个 Git 客户端解决了我上面描述的所有问题:
所以,你选择a1b2c3f9提交:
$ git cherry-pick a1b2c3f9
结果你得到9f3c2b1a提交,然后你把它推送到 Subversion 存储库中。SmartGit 尽一切努力保持合并跟踪信息,因此^/trunk/分支对其svn:mergeinfo属性进行必要的修改:
+ /branches/some-branch: 1000
您可以从 SmartGit 本身或使用 Git 命令行界面执行 Git cherry-pick。在第二种情况下,提交消息应该有樱桃挑选源的git-svn-id行。
SmartGit is proprietary software but it's free for non-commercial usage. It has a lot of great features, for more information please refer to SmartGit documentation.
There is another interesting project which solves certain problems with git-svn — SubGit. Basically it is the server-side solution for synchronizing changes between Subversion and Git repositories. It's much more superior than git-svn and doesn't have its problems.
As svn-via-git user, I believe, you might be interested in that too.