ing*_*ger 27 svn merge svk git-svn hgsubversion
我的项目中出现了一些复杂的颠覆合并:长期分离的大分支.Svn给出了太多的冲突 - 其中一些似乎是虚假的.
鉴于git对于优秀的合并体验而言,为了使合并更易于管理,使用git-svn 它是否有益?
你能推荐其他的替代品(如svk,hgsvn),以减轻疼痛合并?
有些冲突很容易解决(例如java导入,空格) - 所以我也想知道是否有任何自动解决方案.
将来可能会完全切换到DVCS(我们中的一些人会喜欢),但现在不行.(更新:这不再是真的 - 团队最近完全切换并对此感到高兴).
提前致谢.
PS:有些帖子似乎是相关的(例如git-svn合并2个svn分支),但他们没有完全回答这个问题.
更新:看完我的-novice-回答后再往下走(这个道路).
ing*_*ger 34
试图回答我的问题:使用git进行svn合并似乎很有希望.
更新:它不仅仅是有希望的,它取得了巨大的成功.简而言之,Linus是对的.
刚刚完成了2个svn分支的巨大合并,这些分支已经分开了1.5年; 3k文件被更改,在svn中有大量冲突(我认为~800).
我发现git&git-svn是一个救生员:
git-log(以及基础git-rev-parse选项),没有什么能比这更强大.它也很方便:-p一次性给你差异; 在svn中你得到一个日志,然后找到"revision-1:revision"的差异,或使用笨拙的UI.查找何时将字符串添加/删除到repo中,同时搜索多个分支gitk:对于可视化分支历史非常有用,并具有出色的搜索功能.在其他工具中没有看到这样的东西,特别是没有这么快.没关系它在Tk,它很棒git gui:即使不是最性感也能正常工作 - 对于新手发现事物有很大的帮助blame: 奇迹.是的,它会检测原始片段的来源(复制和粘贴等)mergetool:比开始大的更好的体验svn merge,然后每次停止(即每5分钟)它会遇到冲突,按'(p)ostpone',而不是以后手动搜索冲突的文件.首选的是它的味道git gui(需要一个小补丁).发现集成外部差异工具比可以更好地配置svn.rebase 允许过滤掉svn历史的混乱部分所以,这真的可以改变从噩梦到欢乐的区别 - 特别是如果你喜欢学习(在这种情况下需要付出一些努力 - 我想在骑自行车后学习摩托车).
即使我不能强迫公司里的每个人立即切换 - 我真的不打算这样做.再一次,git-svn通过"先蘸脚趾"的方法来拯救我们.但是看到同事们的反应,切换可能会在任何人预期之前发生:)
我会说 - 即使我们忘记了合并和提交,这些东西已经很好用作查询,可视化,备份等的只读前端.
警告:
"请不要将Git合并提交到Subversion存储库.Subversion不会像Git一样处理合并,这会导致问题.这意味着你应该保持你的Git开发历史是线性的(即不与其他分支合并,只是变基.)" (http://learn.github.com/p/git-svn.html的最后一段)
另一个很好的来源是Pro Git书,"切换活动分支"部分基本上说合并确实有效,但dcommit只会存储合并的内容,但历史记录会受到损害(打破后续的合并),所以你应该放弃合并后的工作分支.无论如何它毕竟是有道理的,在实践中很容易避免陷阱在这里...在svn中,我发现人们通常不会重新合并,所以这只能被视为后退如果你来自第一个git世界地点.
无论如何,dcommit只对我有用.我把它放在我自己的svn workbranch上,我只保留这个,所以避免任何额外的冲突.但是,我决定从这个workbranch到svn中的svn trunk进行最后的合并(在git中同步所有内容之后); --ignore-ancestry在那里给出了最好的结果.
更新:正如我后来发现的那样,上面的最后几个步骤(额外的svn分支和合并 - ignore-ancestry)很容易通过保持你从线性分支的分支来避免.正如Gabe在下面所说, merge --squash只是创建了一个简单的svn友好提交.就在我在当地分支机构准备好大量合并时(可能需要数天/周),我现在只是:
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
Run Code Online (Sandbox Code Playgroud)
我知道合并跟踪在svn端不会很好,直到我们完全切换.我等不及了.
更新:@Kevin要求关于合并svn分支的整个过程的更多细节..有很多文章,帖子在那里,但作为一个新手我发现一些令人困惑/误导/过时..无论如何,我的方式这些天做的(当然,在合并之后坚持使用git-svn;就像一些新感染的同事一样)..
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
Run Code Online (Sandbox Code Playgroud)
实际上我更喜欢使用'git gui的内置mergetool集成(右键单击文件冲突).虽然这略有限制,所以请看上面我的小补丁,它允许你插入一个shell脚本,你可以在其中调用你喜欢的任何合并工具(我尝试了各种有时并行,因为它们引起了惊人的悲痛......但通常我被困在kdiff3 ..
当合并步骤正常(没有冲突)时,合并提交会自动完成; 否则,你解决冲突
git commit # am usually doing this in the git gui as well.. again, lightning fast.
Run Code Online (Sandbox Code Playgroud)
最后阶段..请注意,到目前为止,我们只有本地提交,而不是与svn服务器交谈.除非您使用了--squash或其他技巧,否则您现在最终会得到一个图表,其中您的合并提交有2个父项:svn-mirror分支的提示.现在这是常见的问题:svn只能采用线性历史..所以'git-svn'通过删除第二个父(在上面的情况下为svn-branch-to-merge)简化了它.所以真正的合并跟踪是在svn方面走了......但是在这种情况下它很好.
如果你想要一种更安全/更清洁的方式,这就是我早期代码片段的用武之地:只需用--squash进行最后的合并.将之前的一个改编为此流程:
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
Run Code Online (Sandbox Code Playgroud)
哎呀,这已经太久了,太晚之前停下来..祝你好运.