9

我面临着将修订子集从一个主题分支合并到另一个的问题。由于我使用的是 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 手册页,答案是“不要那样做”,但是当我在谷歌上搜索时,我得到的印象是 git svn 现在在这些问题上做得更好。

4

3 回答 3

9

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 dcommitSubversion 存储库不会获得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-svnSubGit. 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.

于 2011-12-06T22:59:20.983 回答
8

当您这样做时git svn dcommit,它将svn commit在您的 svn 跟踪分支和 git 中的任何内容之间为每个 git commit依次运行HEAD。在您的示例中,这是三个提交——A、B 和 C 各一个——因为git cherry-pick会立即提交更改。当然,您可以在运行将它们推送到 svngit rebase -i之前将这些提交压缩到一个单独的修订版中。git svn dcommit

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

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

于 2010-12-13T22:49:09.553 回答
1

这一点应该没有问题;我以前在工作中做过很多次。此外,当 TortoiseSVN 过去在合并整个分支时遇到问题时,我采取了将主题分支重新设置在主干之上并将所有提交压缩到一个提交中的方法,这在本质上类似于樱桃挑选。效果很好。

于 2010-12-13T13:10:25.277 回答