使用 git-svn(或类似的)*just* 来帮助进行 svn 合并? [英] Using git-svn (or similar) *just* to help out with an svn merge?

查看:16
本文介绍了使用 git-svn(或类似的)*just* 来帮助进行 svn 合并?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目中出现了一些复杂的 subversion 合并:分离了很长时间的大分支.Svn 提供了太多冲突 - 其中一些似乎是虚假的.

Some complex subversion merges are coming up in my project: big branches that have been apart for a long time. Svn gives too many conflicts - and some of them seem spurious.

鉴于 git 因其卓越的合并体验而受到称赞,使用 git-svn 只是为了使合并更易于管理有什么好处吗?

Given that git is praised for a superiour merge experience, Would it be any good to use git-svn just for the benefit of making the merge more manageable?

您能否推荐其他替代方案(例如 svkhgsvn)来减轻合并的痛苦?

Can you recommend other alternatives (eg. svk, hgsvn) to lessen the merge pain?

有些冲突很容易解决(例如 java 导入、空格) - 所以我也想知道是否有任何自动化解决方案.

Some conflicts are easy enough to resolve (e.g java imports, whitespaces) - so I'm also wondering if there is any automated solutions for those.

未来可能会完全切换到 DVCS(我们中的一些人会喜欢),但不是现在.(更新:这不再是真实的 - 团队最近完全转换并且对此感到高兴).

A full switch to DVCS might happen in the future (some of us would love that), but not right now. (UPDATE: this isn't true any longer - the team switched fully recently and are happy about it).

提前致谢.

PS:有些帖子似乎是相关的(例如 git-svn merge2 个 svn 分支)但他们没有完全回答这个问题.

PS: there are posts that seem to be related (eg. git-svn merge 2 svn branches) but they don't fully answer this question.

更新:在走下(和上:)这条路后,看看我的新手回答.

Update: see my -novice- answer after going down (and up:) this road.

推荐答案

尝试回答我的问题:使用 git 进行 svn 合并似乎很有希望.

Trying to answer my question: using git for svn merges seems promising.

更新:它不仅有希望,而且取得了巨大的成功.简而言之,Linus 是对的.

Update: it's not just promising, it's a great success. In short, Linus was right.

刚刚完成了2个相隔1.5年的svn分支的巨大合并;更改了 3k 个文件,在 svn 中出现了大量冲突(我认为是 800 个).

Just completed a huge merge of 2 svn branches that have been apart for 1.5 years; 3k files were changed, got tons of conflicts in svn (~800 I think).

我找到了 git &git-svn 救命稻草:

I found git & git-svn a life saver:

  • 自动冲突解决:首先,它减少了很多冲突的文件(我认为是大约一半)
  • 令人难以置信的表现
  • 出色的repo/branching 模型,灵活的工作流程:轻松进行各种实验方法,例如逐块(及时)合并,始终进行完整性检查(编译等);每当遇到麻烦时:只需回溯.您可以随时在需要时退后一步.
  • 可用性,出色的工具:
    • git-log(以及底层的 git-rev-parse 选项),没有比这更强大的了.它也很方便:-p 一次性为您提供差异;在 svn 中你会得到一个日志,然后找到那个revision-1:revision"的差异,或者使用笨拙的用户界面.查找何时在 repo 中添加/删除字符串,同时搜索多个分支
    • gitk:结合强大的搜索功能,对于可视化分支历史非常有用.在其他工具中还没有见过这样的东西,尤其是没有这么快.没关系它在 Tk 中,它只是很棒
    • git gui:即使不是最性感的也能正常工作 - 对新手发现有很大帮助
    • 责备:奇迹.是的,它会检测原始片段的来源(复制和粘贴等)
    • mergetool:比启动大型 svn merge 更愉快的体验,然后每次(即每 5 分钟)它遇到冲突时停止,按 '(p)ostpone',而不是稍后手动寻找冲突的文件.喜欢在 git gui 中集成的这种风格(需要一个 小补丁为了那个原因).发现集成的外部差异工具比 svn 中的可配置性更好.
    • 可插入的合并驱动程序和对它们的细粒度控制
    • rebase 允许过滤掉 svn 历史的混乱部分
    • auto-conflict resolution: for a start, it gave a lot less conflicted files (~half I think)
    • unbelievable performance
    • excellent repo/branching model, flexible workflows: easy experimentation with various approaches, such as chunk-by-chunk(in time) merge, always doing sanity checks(compile,etc); whenever trouble hits: just backtrack. You can always just take a step back when needed.
    • usability, great tooling:
      • git-log (and the underlying git-rev-parse options), nothing can be more powerful than this. It's handy as well: -p gives you diffs in one go; in svn you get a log, then find the diff for that "revision-1:revision", or use clumsy UIs. Find when a string was added/removed into the repo, search multiple branches simultaneously
      • gitk: hugely useful for visualising branch histories, combined with great search capabilities. Haven't seen anything like this in other tools, especially not as fast as this. Nevermind it's in Tk, it's just brilliant
      • git gui: works fine even if not the sexiest - great help for the novice to discover things
      • blame: a miracle. Yes, it detects where the original segment comes from (copy&paste etc)
      • mergetool: much more pleasant experience than kicking off the big svn merge which then stops everytime (ie. every 5 minutes) it runs into a conflict, press '(p)ostpone', than manually hunt for conflicted files later. Preferred a flavour of this integrated in git gui (needed a tiny patch for that). Found integrating external diff tools better configurable than in svn.
      • pluggable merge drivers and fine grained control of them
      • rebase allowed to filter out messier parts of the svn history
      • 带有 Unison 的 USB 驱动器使同步工作<->回家蛋糕
      • 如果没有 git 的疯狂压缩,这是不可能的(5 年的项目,提交 26k,大量的分支和二进制文件,主干 svn checkout:1.9Gb => 所有这些都在完整的 git 存储库中:1.4Gb!)
      • a USB drive with Unison made syncing work<->home a piece of cake
      • this wouldn't have been possible without git's crazy compression (5 years old project with 26k commits, tons of branches and binary files, trunk svn checkout: 1.9Gb => all of these in the full git repo: 1.4Gb!)

      所以,这真的可以让噩梦变成快乐 - 特别是如果你喜欢学习(在这种情况下确实需要一些努力 - 我想就像在骑自行车之后学习摩托车一样).

      So, this really can make the difference from a nightmare to joy - especially if you enjoy learning (which does take some effort in this case - I guess like learning a motorbike after a bicycle).

      尽管我不能强迫公司中的每个人都立即转换 - 我真的不打算这样做.再一次,git-svn 通过先尝试"的方法拯救了我们.但是看到同事的反应,转换可能会在任何人预料的之前发生:)

      Even though I can't force everyone in the company to switch immediately - I really didn't intend to actually. Again, git-svn saves us by 'dipping the toe first' approach.. But seeing colleagues' reactions the switch might happen much before anyone expected:)

      我想说 - 即使我们忘记了合并和;提交,这些东西作为查询、可视化、备份等的只读前端已经很棒了.

      I'd say- even if we forget about merges & commits, this stuff is already great as a read-only frontend for queries, visualisation, backups, etc..

      警告:

      "不要将 Git 合并提交到Subversion 存储库.颠覆不以相同的方式处理合并作为 Git,这会导致问题.这意味着你应该保留你的 Git线性发展历史(即,没有从其他分支合并,只是变基)."(http://learn.github.com/p/git-svn.html的最后一段 )

      "Do not dcommit Git merge commits to the Subversion repository. Subversion doesn’t handle merges in the same way as Git, and this will cause problems. This means you should keep your Git development history linear (i.e., no merging from other branches, just rebasing)." (last paragraph of http://learn.github.com/p/git-svn.html )

      另一个很好的来源是 Pro Git book,基本上是切换活动分支"部分说合并确实有效,但 dcommit 只会存储合并的内容,但历史会受到损害(这会破坏后续的合并),因此您应该在合并后删除工作分支.无论如何这毕竟是有道理的,在实践中很容易避免这里的陷阱..在 svn 中,我发现人们通常不会重新合并,所以如果你首先来自 git world,这只能被视为退后一步地方.

      Another excellent source is the Pro Git book, section 'Switching Active Branches' basically says that the merge does work, but dcommit will only store the content of the merge, but the history will be compromised (which breaks subsequent merges), so you should drop the work branch after merge. Anyway it makes sense after all, and in practice it's easy to avoid traps here.. in svn, I found people do not usually re-merge anyway so this could only be seen as a step back if you come from git world in the first place.

      无论如何,dcommit 对我有用.我在我自己的 svn 工作分支上做了它,我只保留了这个,所以当时避免了任何额外的冲突.但是,我决定从这个工作分支到 svn 中的 svn 主干进行最终合并(在 git 中同步所有内容之后);--ignore-ancestry 在那里给出了最好的结果.

      Anyhow, the dcommit just worked for me. I did it onto my own svn workbranch that I kept for this only, so avoided any extra conflicts that time. However, I decided to do the final merge from this workbranch to the svn trunk in svn (after syncing up everything in git); --ignore-ancestry gave the best results there.

      更新:正如我后来发现的,上面的最后几步(额外的 svn 分支和合并--ignore-ancestry)很容易避免,只要保持你从线性提交的分支即可.正如 Gabe 在下面所说,merge --squash 只是创建了一个简单的愚蠢的 svn 友好提交.就在我的本地分支上准备好大规模合并(可能需要几天/几周)时,我现在只想:

      Update: as I found out later, the last few steps above (extra svn branch and merge--ignore-ancestry) is easily avoided by just keeping the branch you're dcomitting from linear. As Gabe says below, merge --squash just creates a simple stupid svn-friendly commit. Just when ready with huge merge(s) on the my local branch (which might take days/weeks), I would now just:

      git checkout -b dcommit_helper_for_svnbranch  svnbranch
      git merge --squash huge_merge_work_with_messy_nonlinear_history
      git commit 'nice merge summary' # single parent, straight from the fresh svnbranch
      git dcommit
      

      我知道在 svn 端合并跟踪不会很好地工作,直到我们完全切换.我等不及了.

      I know the merge tracking won't work great from the svn-side, until we switch fully. I can't wait for that.

      更新:@Kevin 要求提供有关合并 svn 分支的整个过程的更多详细信息.. 有很多文章和帖子,但作为新手,我发现了一些令人困惑/误导/过时了..无论如何,这几天我做的方式(当然,在那次合并之后坚持使用 git-svn;就像一些新感染的同事一样)..

      UPDATE: @Kevin requested some more details on the whole process of merging svn branches.. There are lots articles, posts out there, but as a novice I found some of the confusing/misleading/out of date.. Anyhow, the way I do it these days (of course, stuck with git-svn after that merge affair; just as some newly infected colleagues)..

      git svn clone -s http://svn/path/to/just-above-trunk  # the slowest part, but needed only once ever..you can every single branch from the svn repo since revision #1. 2) 
      git svn fetch          # later, anytime: keep it up to date, talking to svn server to grab new revisions. Again: all branches - and yet it's usually a faster for me than a simple 'svn up' on the trunk:)    
      # Take a look, sniff around - some optional but handy commands:
      git gui   &    # I usually keep this running, press F5 to refresh
      gitk --all     # graph showing all branches
      gitk my-svn-target-branch svn-branch-to-merge    # look at only the branches in question
      git checkout -b my-merge-fun my-svn-target-branch  # this creates a local branch based on the svn one and switches to it..before you notice :)
      # Some handy config, giving more context for conflicts
      git config merge.conflictstyle diff3
      # The actual merge.. 
      git merge  svn-branch-to-merge    # the normal case, with managable amount of conflicts
      # For the monster merge, this was actually a loop for me: due to the sheer size, I split up the 2 year period into reasonable chunks, eg. ~1 months, tagged those versions ma1..ma25 and mb1..mb25 on each branch using gitk, and then repeated these for all of them
      git merge ma1   # through ma25
      git merge mb1   # through mb25
      # When running into conflicts, just resolve them.. low tech way: keep the wanted parts, then "git add file" but you can
      git mergetool   # loops through each conflicted file, open your GUI mergetool of choice..when successful, add the file automatically.
      git mergetool  my-interesting-path # limit scope to that path
      

      实际上我更喜欢使用 'git gui 的内置合并工具集成(右键单击冲突的文件).不过,这有点有限,所以请参阅我上面的小补丁,它允许您插入一个 shell 脚本,您可以在其中调用您喜欢的任何合并工具(我有时同时尝试了多种它们,因为它们引起了惊人的悲伤......但通常我被 kdiff3 困住了 ..

      Actually I preferred to use 'git gui's builtin mergetool integration (right click on file in conflict). That's slightly limited though,so see my little patch above, which allows you to plugin a shell script where you can invoke whatever mergetools you prefer (I tried a variety of them sometimes in parallel as they caused a surprising amount of grief.. but normally I'm stuck with kdiff3..

      当合并步骤顺利(没有冲突)时,合并提交会自动完成;否则,您解决冲突

      When a merge step goes fine (no conflict), a merge commit is done automatically; otherwise, you resolve conflicts then

      git commit  # am usually doing this in the git gui as well.. again, lightning fast.
      

      最后阶段.. 请注意,到目前为止我们只有本地提交,还没有与 svn 服务器通信.除非您使用过 --squash 或其他技巧,否则您现在最终会得到一个图表,其中您的合并提交有 2 个父项:svn-mirror 分支的提示.现在这是通常的问题:svn 只能获取线性历史记录.. 所以 'git-svn' 通过删除第二个父级(在上述情况下为 svn-branch-to-merge)来简化它.. 所以真正的合并跟踪是在 svn 方面走了......但在这种情况下它很好.

      The last phase.. Note that so far we had only local commits, not talking to the svn server yet. Unless you've used --squash or other tricks, you now end up with a graph where your merge commit has 2 parents: the tips of your svn-mirror branches. Now this is the usual gotcha: svn can only take linear history.. so 'git-svn' simplifies it by just dropping the second parent (svn-branch-to-merge in the above case).. so the real merge tracking is gone on the svn side..but otherwise it's fine in this case.

      如果您想要更安全/更清洁的方式,这就是我之前的代码片段的用武之地:只需使用 --squash 进行最终合并.将较早的一个适应此流程:

      If you want a safer/cleaner way, this is where my earlier snippet comes in: just do the final merge with --squash. Adapted the earlier one to this flow:

      git checkout -b dcommit_helper_for_svnbranch my-svn-target-branch  # another local workbranch.. basically needed as svn branches (as any other remote branch) are read-only
      git merge --squash my-merge-fun  
      git commit 'nice merge summary' # single parent, straight from the fresh svn branch
      git dcommit  # this will result in a 'svn commit' on the my-svn-target-branch
      

      哎呀,时间太长了,早点停下来为时已晚..祝你好运.

      oops, this is getting way too long, stopping before too late.. Good luck.

      这篇关于使用 git-svn(或类似的)*just* 来帮助进行 svn 合并?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆