使用 git-svn 进行挑选
我面临着将修订子集从一个主题分支合并到另一个主题分支的问题。由于我使用的是 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
git-svn 有一个与cherry-picked提交相关的严重问题:
假设你有提交a1b2c3f9,它已经被提交到svn存储库中:
请参阅这个git-svn- id 行?这就是 git-svn 理解您的提交在 Subversion 存储库中的位置的方式。
现在你想挑选这个提交到你当前所在的 master 分支:
如果没有合并冲突,git 会创建一个新的提交,例如 9f3c2b1a 和这里我们有什么:
因此,Git 创建了一个具有完全相同消息的提交。这导致了严重的问题。以前版本的 git-svn 将此类提交发送到错误的分支 - ^/branches/some-branch 而不是 ^/trunk/。
这个问题已经在最新版本的 Git 中得到修复。但还有另一个问题仍然存在:
git-svn 不支持 Subversion 的合并跟踪机制。
Subversion 会跟踪已执行的cherry-picks 上的合并信息,因此该命令
会按如下方式调整 trunk-working-copy 的 svn:mergeinfo 属性:
这样 Subversion 就能了解此特定修订版已经合并到 ^/trunk/ 分支中,因此它在进一步的合并中跳过此更改。
当您运行 gitcherry-pick ,然后运行 git svn dcommit 时,Subversion 存储库不会获得 svn:mergeinfo 修改。
这是免责声明:
目前我不从事 SmartGit 工作,但我与 SmartGit 开发人员保持密切联系。
Syntevo 公司开发了 SmartGit — 一个很好的替代品 < em>git-svn。这个 Git 客户端解决了我上面描述的所有问题:
因此,您挑选 a1b2c3f9 提交:
结果您得到 9f3c2b1a 提交,然后将其推送到 Subversion存储库。 SmartGit 会尽一切努力保留合并跟踪信息,因此 ^/trunk/ 分支对其 svn:mergeinfo 属性进行必要的修改:
您可以从 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:
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:
If there were no merge conflicts, git creates a new commit, say, 9f3c2b1a and here what we have:
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
adjusts the svn:mergeinfo property of trunk-working-copy as follows:
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 thengit 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:
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:
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-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.
当您执行 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
手册页:When you do
git svn dcommit
, it will sequentially run ansvn commit
for each git commit between your svn tracking branch and whateverHEAD
is in git. In your example, that's three commits – one each for A, B, and C – sincegit cherry-pick
commits the changes right away. Granted, you could usegit rebase -i
to squash those commits together into a single revision before you rungit svn dcommit
to push them to svn.Running
git-svn
completely ignores allsvn:mergeinfo
properties. From thegit-svn
man page:这一点应该没有问题;我以前在工作中已经做过很多次了。此外,当 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.