什么使DVCS中的合并变得容易? [英] What makes merging in DVCS easy?

查看:108
本文介绍了什么使DVCS中的合并变得容易?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Joel on Software 上阅读:


使用分布式版本控制,
分布式部分实际上不是
最有趣的部分。



有趣的部分是,这些
系统根据变化来考虑,而不是
版本。


HgInit


当我们必须合并时,Subversion
会尝试查看这两个修订版 - 我的
修改的代码和您修改后的
代码 - 并尝试猜猜如何将
粉碎成一大块不圣洁的
混乱。它通常会失败,产生
页面和页面的合并冲突
,这些并不是真正的冲突,只是
的地方,Subversion未能达到
, p>

相比之下,虽然我们在Mercurial中单独工作
,但Mercurial仍然忙于保存一系列变更集。
因此,当我们想要将我们的代码
合并在一起时,Mercurial实际上有一个
的更多信息:它知道
我们每个人都改变了什么,可以
重新申请这些变化,而不是
只是看最后的产品和
试图猜测如何把它
放在一起。


通过查看SVN的存储库文件夹,我感觉Subversion正在将每个修订版本维护为 changeset 。据我所知,Hg使用 changeset snapshot ,而Git纯粹使用 snapshot 存储数据。



如果我的假设是正确的,那么肯定还有其他方法可以使DVCS中的合并变得容易。这些是什么?



*更新:
$ b



检查以及如何和/或为什么在Git中合并比在SVN中更好?

解决方案

在Git和其他DVCS合并中很容易因为有一些神秘的一系列变化集视图(除非你使用Darcs,以它的补丁理论,或者一些Darcs灵感的DVCS;但它们是少数),Joel咕about着,合并跟踪 ,以及每个修订版都知道其父母的更基本的事实。为此,您需要(我认为)整棵树/完整的资源库提交...不幸的是,它限制了部分签出的能力,并且仅对文件的子集进行提交。



当每个修订(每次提交),包括合并提交,都知道它的父项(对于合并提交,意味着拥有/记住多个父项,即合并跟踪)时,可以重新构建图表(DAG =直接非循环图)修订历史记录。如果您知道修订的图形,则可以找到要合并的提交的共同祖先。当你的DVCS知道如何找到共同的祖先时,你不需要提供它作为参数,例如在CVS中。



<请注意,可能有两个(或更多)提交的不止一个共同的祖先。 Git使用所谓的递归合并策略,合并合并基础(共同祖先),直到你剩下一个虚拟/有效的共同祖先(在一些简化中),并且可以做简单的3路合并。 p>

使用重新命名检测创建Git可以处理涉及文件重命名的合并。 (这支持JörgW Mittag 的论点,即DVCS有更好的合并因为他们必须拥有它,因为合并比在CVCS中更常见,合并隐藏在'update'命令中,在update-then-commit工作流中,cf 了解版本控制(WIP)作者Eric S. Raymond )。


I read at Joel on Software:

With distributed version control, the distributed part is actually not the most interesting part.

The interesting part is that these systems think in terms of changes, not in terms of versions.

and at HgInit:

When we have to merge, Subversion tries to look at both revisions—my modified code, and your modified code—and it tries to guess how to smash them together in one big unholy mess. It usually fails, producing pages and pages of "merge conflicts" that aren’t really conflicts, simply places where Subversion failed to figure out what we did.

By contrast, while we were working separately in Mercurial, Mercurial was busy keeping a series of changesets. And so, when we want to merge our code together, Mercurial actually has a whole lot more information: it knows what each of us changed and can reapply those changes, rather than just looking at the final product and trying to guess how to put it together.

By looking at the SVN's repository folder, I have the impression that Subversion is maintaining each revisions as changeset. And from what I know, Hg is using both changeset and snapshot while Git is purely using snapshot to store the data.

If my assumption is correct, then there must be other ways that make merging in DVCS easy. What are those?

* Update:

  • I am more interested in the technical perspective, but answers from non-technical perspective are acceptable
  • Corrections:

    1. Git's conceptual model is purely based on snapshots. The snapshots can be stored as diffs of other snapshots, it's just that the diffs are purely for storage optimization. – Rafał Dowgird's comment

  • From non-technical perspective:

    1. It's simply cultural: a DVCS wouldn't work at all if merging were hard, so DVCS developers invest a lot of time and effort into making merging easy. CVCS users OTOH are used to crappy merging, so there's no incentive for the developers to make it work. (Why make something good when your users pay you equally well for something crap?)
      ...
      To recap: the whole point of a DVCS is to have many decentralized repositories and constantly merge changes back and forth. Without good merging, a DVCS simply is useless. A CVCS however, can still survive with crappy merging, especially if the vendor can condition its users to avoid branching. – Jörg W Mittag's answer

  • From technical perspective:

    1. recording a real DAG of the history does help! I think the main difference is that CVCS didn't always record a merge as a changeset with several parents, losing some information. – tonfa's comment
    2. because of merge tracking, and the more fundamental fact that each revisions knows its parents. ... When each revision (each commit), including merge commits, know its parents (for merge commits that means having/remembering more than one parent, i.e. merge tracking), you can reconstruct diagram (DAG = Direct Acyclic Graph) of revision history. If you know graph of revisions, you can find common ancestor of the commits you want to merge. And when your DVCS knows itself how to find common ancestor, you don't need to provide it as an argument, as for example in CVS.
      .
      Note that there might be more than one common ancestor of two (or more) commits. Git makes use of so called "recursive" merge strategy, which merges merge bases (common ancestor), till you are left with one virtual / effective common ancestor (in some simplification), and can the do simple 3-way merge. – Jakub Narębski's answer

Check as well How and/or why is merging in Git better than in SVN?

解决方案

In Git and other DVCS merges are easy not because of some mystical series of changesets view (unless you are using Darcs, with its theory of patches, or some Darcs-inspired DVCS; they are minority, though) that Joel rambles about, but because of merge tracking, and the more fundamental fact that each revisions knows its parents. For that you need (I think) whole-tree / full-repository commits... which unfortunately limits ability to do partial checkouts, and making a commit about only subset of files.

When each revision (each commit), including merge commits, know its parents (for merge commits that means having/remembering more than one parent, i.e. merge tracking), you can reconstruct diagram (DAG = Direct Acyclic Graph) of revision history. If you know graph of revisions, you can find common ancestor of the commits you want to merge. And when your DVCS knows itself how to find common ancestor, you don't need to provide it as an argument, as for example in CVS.

Note that there might be more than one common ancestor of two (or more) commits. Git makes use of so called "recursive" merge strategy, which merges merge bases (common ancestor), till you are left with one virtual / effective common ancestor (in some simplification), and can the do simple 3-way merge.

Git use of rename detection was created to be able to deal with merges involving file renames. (This supports Jörg W Mittag argument that DVCS have better merge support because they had to have it, as merges are much more common than in CVCS with its merge hidden in 'update' command, in update-then-commit workflow, c.f. Understanding Version Control (WIP) by Eric S. Raymond).

这篇关于什么使DVCS中的合并变得容易?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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