许多有关分布式版本控制系统的文章声称其支持更好的分支和合并是从svn转移到分布式版本控制系统的原因之一。这些系统究竟如何以不同的方式进行分支和合并,使得它更加优越?
许多有关分布式版本控制系统的文章声称其支持更好的分支和合并是从svn转移到分布式版本控制系统的原因之一。这些系统究竟如何以不同的方式进行分支和合并,使得它更加优越?
历史上,git 和 svn 在合并跟踪方面的区别在于:git 有合并跟踪功能,而 svn 直到版本1.5之前根本没有。如果你想进行合并操作,你必须始终明确指定要合并的具体变更内容。如果你将一个分支合并到另一个分支超过一次,你就必须手动跟踪哪些修订版本已经被合并,手动选择尚未合并的变更,以避免冲突。如果您曾使用cherry-pick命令选取任何更改,则祝你好运。
从版本1.5开始(发布于2008年),如果你的客户端、服务器和仓库都是最新的,那么svn可以表现得更加智能;它使用属性来跟踪分支的来源以及已经合并到其中的变更。结果是,在许多情况下,你只需要执行svn merge BRANCHNAME
就可以做正确的事情。但由于它的“附加”性质,它仍然不够快,并且不是完全健壮的 (参见这里)。另一方面,由于其DVCS性质,Git 必须很好地处理合并场景,因此它从一开始就设计了适合此任务的数据结构(如它使用的特定类型的有向无环图)和算法(如递归合并和章鱼合并)。
这就是区别。假设你和我在一起编写代码,我们创建了一个分支,然后各自进入我们的工作空间并单独对该代码进行了大量更改,因此它们已经有很大不同了。
当我们需要合并时,Subversion试图查看两个版本——我的修改代码和你的修改代码——并尝试猜测如何将它们合并成一个巨大的混乱。它通常会失败,产生许多“合并冲突”的页面,这些页面实际上并不是冲突,只是Subversion无法弄清楚我们所做的事情的地方。
相比之下,在Mercurial中单独工作时,Mercurial会忙于保留一系列更改集。因此,当我们想要合并我们的代码时,Mercurial实际上拥有更多的信息:它知道我们每个人都做了哪些更改,并且可以重新应用这些更改,而不仅仅是查看最终产品并尝试猜测如何组合它们。
在SVN中,分支或标记仅是将特定目录及其子目录复制到同一存储库内的另一个位置。然而,在Git中,分支(和标记)被描述为元数据(类似于CVS),但不是将所有这些数据放入单个文件中,而是使用许多文件(允许更快的更新,因为您无需重写大型“foo.c,v”文件)。此外,Git大量使用指针,所以当某些内容发生变化(例如进行提交)时,实际上需要更新的内容很少。(http://eagain.net/articles/git-for-computer-scientists/)
区别在于大多数分布式版本控制系统使用的存储库格式 - 有向无环图。
SVN只会将您的历史记录存储在一系列行中,每个分支都是自己的一行。但是,DVCS将其存储在包含更好合并信息的DAG中。