用git-svn挑选樱桃

Jes*_*erE 9 svn git cherry-pick

我面临的问题是将一个修订的子集从一个主题分支合并到另一个主题分支.由于我使用git-svn,我很想知道是否可以使用樱桃采摘.使用Subversion,我会这样做:

svn merge -c A
svn merge -c B
svn merge -c C
...
svn commit ...
Run Code Online (Sandbox Code Playgroud)

如果我尝试这样做会发生什么?

git checkout branch1
git cherry-pick A
git cherry-pick B
git cherry-pick C
git svn dcommit
Run Code Online (Sandbox Code Playgroud)

如果我阅读git svn man-page,答案就是"不要那样做",但是当我在谷歌上搜索git时,我会得到一个印象.现在这些问题做得更好.

vad*_*hev 9

git-svn有一个与樱桃挑选提交相关的严重问题:

假设你已经提交了a1b2c3f9,它已经被提交到svn repository:

  $ 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-...
Run Code Online (Sandbox Code Playgroud)

看到这个git-svn-id行?这就是git-svn如何理解你的提交在Subversion存储库中的位置.

现在,您想要将此提交选择为您当前所在的分支:

  $ git cherry-pick a1b2c3f9
Run Code Online (Sandbox Code Playgroud)

如果没有合并冲突,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-...
Run Code Online (Sandbox Code Playgroud)

因此,Git使用完全相同的消息创建了一个提交.这引起了严重的问题.以前版本的git-svn将这样的提交发送到错误的分支 - ^/branches/some-branch而不是^/trunk /.

这个问题已在最新版本的Git中修复.但还有另一个仍然存在:

git-svn不尊重Subversion的合并跟踪机制.

Subversion跟踪已执行的樱桃选择的合并信息,因此该命令

  $ svn merge -c 1000 ^/branches/some-branch trunk-working-copy
Run Code Online (Sandbox Code Playgroud)

调整trunk-working-copysvn:mergeinfo属性,如下所示:

  + /branches/some-branch: 1000
Run Code Online (Sandbox Code Playgroud)

这样Subversion就知道这个特定的修订已经合并到^/trunk / branch中,因此它会在进一步的合并中跳过这个变化.

当你运行git cherry-pick然后git svn dcommitSubversion存储库没有得到svn:mergeinfo修改.


免责声明:
目前我没有使用SmartGit,但我与SmartGit开发人员密切合作.

Syntevo公司开发了SmartGit - git-svn的绝佳替代品.这个Git客户端解决了我上面描述的所有问题:

所以,你挑选a1b2c3f9提交:

  $ git cherry-pick a1b2c3f9
Run Code Online (Sandbox Code Playgroud)

结果你得到9f3c2b1a提交,然后你把它推入Subversion存储库.SmartGit会尽一切努力保持合并跟踪信息,因此^/trunk / branch会对其svn:mergeinfo属性进行必要的修改:

  + /branches/some-branch: 1000
Run Code Online (Sandbox Code Playgroud)

您可以从SmartGit本身或使用Git命令行界面执行Git cherry-pick.在第二种情况下,提交消息应该具有cherry-pick源的git-svn-id行.

SmartGit是专有软件,但它可以免费用于非商业用途.它有很多很棒的功能,有关更多信息,请参阅 SmartGit文档.

还有另一个有趣的项目解决了git-svn的某些问题- SubGit.基本上它是用于同步Subversion和Git存储库之间的更改的服务器端解决方案.它比git-svn更优越,并且没有问题.

作为svn-via-git用户,我相信你也可能对此感兴趣.


Mik*_*itz 8

当你这样做时git svn dcommit,它将svn commit为你的svn跟踪分支和HEADgit中的任何内容之间的每个git提交顺序运行一次.在您的示例中,这是三个提交 - A,B和C各一个 - 因为立即git cherry-pick提交更改.当然,git rebase -i在运行git svn dcommit将它们推送到svn 之前,您可以使用这些提交一起压缩到一个修订版本中.

运行git-svn完全忽略所有svn:mergeinfo的属性.从git-svn手册页:

我们忽略除svn:executable之外的所有SVN属性.记录任何未处理的属性$GIT_DIR/svn/<refname>/unhandled.log