Subversion将版本化的树管理为一级对象(存储库是树的数组),而变更集是通过比较相邻树派生出来的。Arch或Bitkeeper等系统则相反:它们的设计是将变更集作为一级对象进行管理(存储库是补丁包),并且树是通过组合一组补丁得到的。
但是,不清楚Subversion存储库如何存储更改,是否包含版本文件的最早变体等。为什么我们不能像Git一样生成一堆补丁呢?这常常被提到作为svn和git之间的主要区别,它简化了/复杂了合并,但遗憾的是,我仍然不明白这个想法。
在Martin的博客中,有一个很好的解释关于基于变更集和快照的版本控制系统的主要区别。我不会在这里重复。
然而,我想强调一个可能一开始不太明显的点。基于变更集的版本控制系统使跟踪合并变得非常容易,而对于像基于快照的Subversion这样的系统,则更加困难。
在基于变更集的版本控制系统中,合并就是简单的变更集(或者如git中所称的提交),它们有多个父变更集。仓库的图形化表示通常显示一个DAG(有向无环图),其中节点表示变更集,箭头表示父子关系。当你看到一个有多个父节点的节点时,你就知道发生了什么样的合并。
在Subversion中,“合并跟踪”是一个新概念。直到1.4版本之前,没有这样的概念,因此为了了解合并的历史记录,您必须在提交的日志消息中做笔记。1.5版本实现了合并跟踪,以便更轻松地执行从一个分支到另一个分支的重复合并,而不需要强制用户明确指定修订范围等。这是通过与接收合并的目录相关联的属性(svn:mergeinfo)实现的。它跟踪已经从哪些分支合并了哪些修订版本。这足以推断出哪些修订版本应在后续合并中合并。但是,它并没有使绘制显示合并历史记录的图形变得容易,而这是您在与几个开发人员一起工作的复杂项目中经常需要看到的。
Git的原则是将版本树作为一级对象进行排列。也就是说,你需要处理一个提交对象的图形,每个提交对象与一个树具有一对一的关系,该树是该修订版本的状态。
请注意,这些实际上如何存储可能非常不同。Git最初只是压缩每个文件和树/提交对象。据我所知,将对象打包成单个文件并仅为某些对象存储增量是在添加之后才出现的。
因此,尽管补丁似乎在Git用户界面中无处不在,但它们实际上与数据存储方式没有关系-存储在包文件中的增量是二进制增量,而不是文本样式差异。 Git将应用增量以获取对象,然后再次对其进行差异处理,以根据需要生成补丁。这与CVS形成对比,例如,CVS从RCS继承了最新版本加反向增量存储系统。
根据您引用的内容,Git和SVN实际上比任何一方更类似于CVS。
回答晚了,而且只回答了部分问题。我认为以下内容还没有在上面澄清:
CVCS = Centralized Version Control System(集中式版本控制系统)
DVCS = Distributed Version Control System(分布式版本控制系统,Git使用的)
REPOSITORY = 项目的文件树,即一个目录及其一个或多个子目录,包含单个项目的所有许多文件。例如:
./Project1/README
./Project1/myprogram.c
./Project1/Makefile
./Project1/images/1.gif
./Project1/images/2.gif
所有人共享一个(集中式)代码库。
使用方法:
所有用户都被授予进行更改的权限。
所有人共享一个只读代码库,然后每个用户的位置至少有一个完整的代码库副本。
换句话说,每个用户都会将整个项目树复制到他们的本地计算机上,或者从主代码库复制整个文件树。
使用方法:
对于更改的权限由控制主要存储库的项目所有者控制。(在Git中,我们有“拉取请求”,或请求项目所有者控制中央存储库以拉入新更改。)
我已经过度简化了这个问题,以便关注集中式和分布式之间的主要区别。(现在我承认我仍在学习如何记录您所询问的更改,并希望在完全理解后更新此内容。)
参考:这篇文章更加详细。