我面临的问题是将一个修订的子集从一个主题分支合并到另一个主题分支。由于我使用的是git-svn,我很想知道是否可以使用樱桃采摘。使用Subversion,我会这样做:
svn merge -c A
svn merge -c B
svn merge -c C
...
svn commit ...
如果我尝试这样做会发生什么?
git checkout branch1
git cherry-pick A
git cherry-pick B
git cherry-pick C
git svn dcommit
如果我阅读git svn man-page,答案就是“不要那样做”,但是当我在谷歌上搜索git时,我会得到一个印象。现在这些问题做得更好。
答案 0 :(得分:9)
git-svn 有一个与樱桃挑选提交相关的严重问题:
假设你已经提交 a1b2c3f9 ,它已经被提交到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跟踪已执行樱桃选择的合并信息,因此命令
$ 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是专有软件,但它可以免费用于非商业用途。它有很多很棒的功能,有关详细信息,请参阅SmartGit documentation。
另一个有趣的项目解决了 git-svn - SubGit的某些问题。基本上它是用于同步Subversion和Git存储库之间的更改的服务器端解决方案。它比 git-svn 更优越,并且没有问题。
作为svn-via-git用户,我相信,您可能也对此感兴趣。
答案 1 :(得分:8)
执行git svn dcommit
时,它将为您的svn跟踪分支与git中的svn commit
之间的每个git提交顺序运行HEAD
。在您的示例中,这是三个提交 - A,B和C各一个 - 因为git cherry-pick
立即提交更改。当然,您可以使用git rebase -i
将这些提交压缩成一个修订版,然后再运行git svn dcommit
将它们推送到svn。
正在运行git-svn
会完全忽略所有svn:mergeinfo
属性。来自git-svn
man page:
我们忽略除svn:executable之外的所有SVN属性。任何未处理的属性都会记录到
$GIT_DIR/svn/<refname>/unhandled.log
答案 2 :(得分:1)
根本没有问题;我以前在工作中做了很多次。另外,当TortoiseSVN过去难以合并整个分支时,我已经在主干上重新设置主题分支并将所有提交压缩成一个提交,这在本质上类似于樱桃选择。这很棒。