使用 git-svn 进行挑选

发布于 2024-10-07 12:01:22 字数 419 浏览 6 评论 0原文

我面临着将修订子集从一个主题分支合并到另一个主题分支的问题。由于我使用的是 git-svn,所以我很好奇是否可以使用cherry-picking 来实现这一点。使用 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 现在在处理这些问题上做得更好了。

I'm facing the problem of merging a subset of revisions from one topic-branch to another. Since I am using git-svn, I was curious to see if it is possible to use cherry-picking for this. Using Subversion, I would do:

svn merge -c A
svn merge -c B
svn merge -c C
...
svn commit ...

what will happen if I try to do this?

git checkout branch1
git cherry-pick A
git cherry-pick B
git cherry-pick C
git svn dcommit

If I read the git svn man-page, the answers is "don't do that", but I get the impression when googling around that git svn does a much better job now with these kinds of issues.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一直在等你来 2024-10-14 12:01:22

git-svn 有一个与cherry-picked提交相关的严重问题:

假设你有提交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 会跟踪已执行的cherry-picks 上的合并信息,因此该命令

  $ svn merge -c 1000 ^/branches/some-branch trunk-working-copy

会按如下方式调整 trunk-working-copysvn:mergeinfo 属性:

  + /branches/some-branch: 1000

这样 Subversion 就能了解此特定修订版已经合并到 ^/trunk/ 分支中,因此它在进一步的合并中跳过此更改。

当您运行 gitcherry-pick ,然后运行 ​​git svn dcommit 时,Subversion 存储库不会获得 svn:mergeinfo 修改。


这是免责声明:
目前我不从事 SmartGit 工作,但我与 SmartGit 开发人员保持密切联系。

Syntevo 公司开发了 SmartGit — 一个很好的替代品 < em>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 文档

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

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

git-svn had a serious problem related to cherry-picked commits:

Suppose you have commit a1b2c3f9 which is already dcommitted into 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-...

See this git-svn-id line? This is how git-svn understands where your commit lies in Subversion repository.

Now you want to cherry-pick this commit to master branch you're currently on:

  $ git cherry-pick a1b2c3f9

If there were no merge conflicts, git creates a new commit, say, 9f3c2b1a and here what we have:

  $ 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-...

So, Git created a commit with exactly the same message. This caused serious problems. Former versions of git-svn sent such commit into wrong branch — ^/branches/some-branch instead of ^/trunk/.

This problem is already fixed in the latest versions of Git. But there is another one which is still present:

git-svn doesn't honor merge-tracking mechanism of Subversion.

Subversion tracks merge information on performed cherry-picks, so the command

  $ svn merge -c 1000 ^/branches/some-branch trunk-working-copy

adjusts the svn:mergeinfo property of trunk-working-copy as follows:

  + /branches/some-branch: 1000

This way Subversion understands that this particular revision was already merged into ^/trunk/ branch thus it skips this change in further merges.

When you run git cherry-pick and then git svn dcommit Subversion repository doesn't get svn:mergeinfo modification.


Here goes the disclaimer:
Currently I don't work on SmartGit but I work in a close contact with SmartGit developers.

Syntevo company developed SmartGit — a great replacement of git-svn. This Git client resolves all the issues I've described above:

So, you cherry-pick a1b2c3f9 commit:

  $ git cherry-pick a1b2c3f9

as result you get 9f3c2b1a commit, and then you push it into Subversion repository. SmartGit does everything to keep merge-tracking information, so ^/trunk/ branch gets necessary modification of its svn:mergeinfo property:

  + /branches/some-branch: 1000

You can perform Git cherry-pick either from SmartGit itself or using Git command line interface. In the second case commit message should have git-svn-id line of the cherry-pick source.

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.

飘然心甜 2024-10-14 12:01:22

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

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

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

When you do git svn dcommit, it will sequentially run an svn commit for each git commit between your svn tracking branch and whatever HEAD is in git. In your example, that's three commits – one each for A, B, and C – since git cherry-pick commits the changes right away. Granted, you could use git rebase -i to squash those commits together into a single revision before you run git svn dcommit to push them to svn.

Running git-svn completely ignores all svn:mergeinfo properties. From the git-svn man page:

We ignore all SVN properties except svn:executable. Any unhandled properties are logged to $GIT_DIR/svn/<refname>/unhandled.log

转身泪倾城 2024-10-14 12:01:22

这一点应该没有问题;我以前在工作中已经做过很多次了。此外,当 TortoiseSVN 过去在合并整个分支时遇到困难时,我会求助于在主干顶部重新调整主题分支并将所有提交压缩为一个提交,这本质上类似于樱桃选择。效果很好。

There should be no problem with this at all; I've done this many times at work before. Additionally, when TortoiseSVN has had trouble merging entire branches in the past, I have resorted to rebasing topic branches on top of trunk and squashing all the commits into one commit, which is similar in nature to a cherry-pick. It's worked great.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文