stm*_*max 143 svn git merge mercurial dvcs
我经常读到Hg(和Git和......)在合并方面比SVN更好但是我从未见过Hg/Git可以合并SVN失败的地方(或者SVN需要人工干预的地方)的实际例子.您可以发布一些分支/修改/提交/ ....-操作的逐步列表,显示SVN在Hg/Git愉快地移动时会失败的位置吗?实用,非常特殊的情况请...
一些背景:我们有几十个开发人员在使用SVN进行项目,每个项目(或一组类似项目)都在自己的存储库中.我们知道如何应用发布和功能分支,所以我们不会经常遇到问题(即,我们一直在那里,但我们已经学会克服Joel的问题 "一个程序员给整个团队造成创伤"或"需要六个开发人员两周才能重新整合分支机构").我们的发布分支非常稳定,仅用于应用错误修正.我们的中继线应该足够稳定,能够在一周内创建发布.我们还有一些开发人员或开发人员可以使用的功能分支.是的,它们在重新集成后被删除,因此它们不会使存储库混乱.;)
所以我仍然试图找到Hg/Git优于SVN的优势.我很想获得一些实践经验,但目前还没有任何我们可以移动到汞/ GIT中还没有更大的项目,所以我坚持用只含有少量由文件小型人工玩的项目.而且我正在寻找一些你可以感受到Hg/Git令人印象深刻的力量的案例,因为到目前为止我经常读到它们但却未能自己找到它们.
Mar*_*ler 120
我也一直在寻找一个案例,比如Subversion无法合并分支,而Mercurial(以及Git,Bazaar,......)做对了.
SVN Book 描述了重命名文件的合并方式不正确.这适用于颠覆1.5,1.6,1.7和1.8!我试图重新创建以下情况:
cd /tmp rm -rf svn-repo svn-checkout svnadmin create svn-repo svn checkout file:///tmp/svn-repo svn-checkout cd svn-checkout mkdir trunk branches echo 'Goodbye, World!' > trunk/hello.txt svn add trunk branches svn commit -m 'Initial import.' svn copy '^/trunk' '^/branches/rename' -m 'Create branch.' svn switch '^/trunk' . echo 'Hello, World!' > hello.txt svn commit -m 'Update on trunk.' svn switch '^/branches/rename' . svn rename hello.txt hello.en.txt svn commit -m 'Rename on branch.' svn switch '^/trunk' . svn merge --reintegrate '^/branches/rename'
根据这本书,合并应该干净利落,但重命名的文件中的数据错误,因为trunk
忘记了更新.相反,我得到了一个树冲突(这是与Subversion 1.6.17,在撰写本文时Debian中的最新版本):
--- Merging differences between repository URLs into '.': A hello.en.txt C hello.txt Summary of conflicts: Tree conflicts: 1
根本不应该有任何冲突 - 更新应该合并到文件的新名称中.当Subversion失败时,Mercurial会正确处理这个问题:
rm -rf /tmp/hg-repo
hg init /tmp/hg-repo
cd /tmp/hg-repo
echo 'Goodbye, World!' > hello.txt
hg add hello.txt
hg commit -m 'Initial import.'
echo 'Hello, World!' > hello.txt
hg commit -m 'Update.'
hg update 0
hg rename hello.txt hello.en.txt
hg commit -m 'Rename.'
hg merge
Run Code Online (Sandbox Code Playgroud)
在合并之前,存储库看起来像这样(来自hg glog
):
@ changeset: 2:6502899164cc | tag: tip | parent: 0:d08bcebadd9e | user: Martin Geisler | date: Thu Apr 01 12:29:19 2010 +0200 | summary: Rename. | | o changeset: 1:9d06fa155634 |/ user: Martin Geisler | date: Thu Apr 01 12:29:18 2010 +0200 | summary: Update. | o changeset: 0:d08bcebadd9e user: Martin Geisler date: Thu Apr 01 12:29:18 2010 +0200 summary: Initial import.
合并的输出是:
merging hello.en.txt and hello.txt to hello.en.txt 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit)
换句话说:Mercurial从修订版1中获取了更改,并将其合并到修订版2(hello.en.txt
)中的新文件名中.处理这种情况当然是必不可少的,以支持重构和重构,这正是你想要在分支上做的事情.
Jak*_*ski 91
我自己并不使用Subversion,但是从Subversion 1.5的发行说明:合并跟踪(基础)看起来,在GID或Mercurial等全DAG版本控制系统中,合并跟踪的工作方式有以下不同之处.
合并主干到分支不同于合并分支到主干:由于某种原因合并主干到分支需要--reintegrate
选项svn merge
.
在像Git或Mercurial这样的分布式版本控制系统中,主干和分支之间没有技术差异:所有分支都是相同的(尽管可能存在社会差异).在任一方向上合并都以相同的方式进行.
您需要提供new -g
(--use-merge-history
)选项svn log
并svn blame
考虑合并跟踪.
在Git和Mercurial中,在显示历史记录(日志)和责备时会自动考虑合并跟踪.在Git中,您可以请求仅跟随第一个父母--first-parent
(我猜Mercurial也存在类似选项)以"丢弃"合并跟踪信息git log
.
据我所知,svn:mergeinfo
属性存储有关冲突的每路径信息(Subversion是基于变更集的),而在Git和Mercurial中,它只是可以拥有多个父级的提交对象.
Subversion中合并跟踪的"已知问题"小节表明重复/循环/反射合并可能无法正常工作.这意味着在以下历史记录中,第二次合并可能不会做正确的事情('A'可以是主干或分支,'B'可以分别是分支或主干):
*---*---x---*---y---*---*---*---M2 <-- A \ \ / --*----M1---*---*---/ <-- B
在上述ASCII艺术被破坏的情况下:分支'B'在修订版'x'处从分支'A'创建(分叉),然后分支'A'在修订版'y'处合并到分支'B'中合并'M1',最后将分支'B'合并为分支'A'作为合并'M2'.
*---*---x---*-----M1--*---*---M2 <-- A \ / / \-*---y---*---*---/ <-- B
在上述ASCII艺术被破坏的情况下:分支'B'在修订版'x'处从分支'A'创建(分叉),它在'y'处合并为分支'A'作为'M1',并且稍后再次合并为分支'A'作为'M2'.
Subversion可能不支持纵向交叉合并的高级案例.
*---b-----B1--M1--*---M3 \ \ / / \ X / \ / \ / \--B2--M2--*
Git在实践中使用"递归"合并策略处理这种情况.我不确定Mercurial.
在"已知问题"中,警告合并跟踪不能与文件重命名一起使用,例如,当一方重命名文件(并且可能修改它)时,第二方修改文件而不重命名(在旧名称下).
Git和Mercurial在实践中都处理了这样的情况:Git使用重命名检测,Mercurial使用重命名跟踪.
HTH
Von*_*onC 17
在没有谈到通常的优点(离线提交,发布过程 ......)这里是一个我喜欢的"合并"示例:
我一直看到的主要场景是一个分支,其中...... 实际开发了两个不相关的任务
(它从一个功能开始,但它导致了另一个功能的开发.
或者它从一个补丁开始,但它导致了开发另一个功能).
如何只合并主分支上的两个功能之一?
或者,您如何在自己的分支中隔离这两个功能?
您可以尝试生成某种补丁,问题是您不再确定可能存在的功能依赖关系:
我认为Git(以及Mercurial)建议使用rebase --onto选项来重组(重置分支的根)部分:
- x - x - x (v2) - x - x - x (v2.1)
\
x - x - x (v2-only) - x - x - x (wss)
Run Code Online (Sandbox Code Playgroud)
你可以解决这种情况,你有v2的补丁以及新的wss功能:
- x - x - x (v2) - x - x - x (v2.1)
|\
| x - x - x (v2-only)
\
x - x - x (wss)
Run Code Online (Sandbox Code Playgroud)
,允许您:
我喜欢的另一个功能(影响合并)是能够压缩提交(在尚未推送到另一个仓库的分支中)以呈现:
这确保合并更容易,冲突更少.
我们最近从SVN迁移到GIT,并面临同样的不确定性.有很多轶事证据表明GIT更好,但很难找到任何例子.
我可以告诉你,GIT在合并时比SVN好很多.这显然是轶事,但有一个表可供遵循.
以下是我们发现的一些事情:
当我们评估GIT时,我们运行了以下测试.这些显示GIT在合并方面是赢家,但不是那么多.在实践中,差异要大得多,但我想我们还没有设法复制SVN处理不当的情况.
其他人已经涵盖了更多的理论方面.也许我可以提供更实际的观点.
我目前正在为一家在"功能分支"开发模型中使用SVN的公司工作.那是:
一般来说,它的工作原理.SVN可以用于这样的流程,但它并不完美.SVN的某些方面妨碍了人类的行为.这给了它一些消极方面.
^/trunk
.此垃圾合并整个树中的信息记录,并最终打破合并跟踪.虚假冲突开始出现,混乱占主导地位.svn merge
做你想要的.合并您的更改需要(我们被告知)--reintegrate
merge命令.我从来没有真正理解这个开关,但这意味着分支不能再次合并到主干.这意味着它是一个死分支,你必须创建一个新分支继续工作.(见说明)往往会发生的是工程师在第1天创建分支.他开始工作并忘记了它.一段时间后,一位老板走了进来,询问他是否可以将他的工作释放到行李箱.工程师一直担心这一天因为重新融合意味着:
......而且因为工程师尽可能少地做到这一点,他们不记得每一步的"神奇咒语".错误的交换机和URL发生了,突然间它们变得一团糟,他们就会得到"专家".
最终这一切都得到了解决,人们学会了如何处理这些缺点,但每个新的首发都会遇到同样的问题.最终的现实(与我在他开始时提出的相反)是:
...但...
值得庆幸的是,团队足够小,可以应付,但不会扩大规模.事实上,这并不是CVCS的问题,但更多的是因为合并不如DVCS那么重要,因此它们不是那么光滑."合并摩擦"导致行为,这意味着"特征分支"模型开始崩溃.良好的合并需要成为所有VCS的功能,而不仅仅是DVCS.
根据这个,现在有一个--record-only
可用于解决--reintegrate
问题的开关,显然 v1.8选择何时自动重新整合,并且它不会导致分支死后
归档时间: |
|
查看次数: |
22937 次 |
最近记录: |