|
|
发表于 2022-9-22 18:20:07
|
显示全部楼层
转载一个翻译 & 分析 (git vs mercurial),比较老了,仅供参考。
原译文地址(
http://blog.twpug.org/416)不可用,通过google-cache 获取;另有译言网同一篇(
译言网 | Git和Mercurial(Hg)的分析):
本文翻译自下面网址:
http://code.google.com/p/support/wiki/DVCSAnalysis
注意:这个分析在2008 年夏天进行,起因于Google Code 评估加入分散式版本管理功能
摘要
这份文件总结了Google Code 在希望加入分散式版本管理功能所做的初步研究,基于普及性,只考虑了两个分散式版本管理系统: Git 与Mercurial 。这份文件说明了两个系统的功能,也提供一个将它整合进Google Code 所需要进行的工作。
分散式版本控制
在传统的版本控制系统,一般会有一个集中的资料库控管所有记录,用户必须与这个资料库互动来验证档案的记录、检视其他分支与提交异动。通常用户端会复制一份资料进行处理,但是这个版本并不会储存早期版本与其他分支的资料。
分散式版本管理系统(以下简称DVCS)使用了不一样的结构,使用DVCS 时,每个使用者会有一个本地端的资料库、完整的专案异动记录、分支等等,切换到不同的分支、检验档案异动记录或什至提交异动都是在本地端进行操作。而个别的资料库间可以透过推(push)与拉(pull)操作进行资讯的交换,一个推的操作会将本地端的部份资讯传送到远端资料库,而拉的操作则会将远端的资料复制到本地端资料库。需要注意的是,没有任何一个资料库具有较高的权威性,两个资料库也许都会有些本地端的记录还不会出现在另一端,任何的DVCS 系统都有一个关键性功能,就是让资料库可以清楚传达本地端所拥有的记录(以及它所需要的记录),而Git 与Mercurial 两者都是透过SHA1 杂凑值来检验资料(档案、目录结构、版本异动等)。
DVCS 让开发者在工作流程上有更多的弹性,他们可以用传统版本控制系统的习惯进行操作,也就是透过一个集中、具有权威的资料库让开发者进行同步;而对于比较大的专案,它也可以提供具有阶层关系的资料库,只要每个资料库的维护者允许来自下层开发者的异动以及将这些异动提交给上层。 DVCS 还允许开发者彼此间分享工作成果,例如两个开发同样功能的开发者可以在相同的分支上进行开发,但是两者之间成果的分享不需要透过一个权威性的伺服器;当他们完成了开发,就可以将成果推到公开的资料库,让更多人使用。
因为没有集中的资料库,所以不会有所谓的主从架构,当谈论到两个资料库时,一般是指本地端与远端,而不是伺服端与用户端的关系。不过在Google Code 实作的概念中,在Google 的资料库还是会被当作伺服端,而使用者的资料库会被称为用户端。
功能比较
事实上, Git 与Mercurial 有许多相仿之处,因此在这里不会提供两者都有的冗长功能清单,这个部份希望点出两者间显著的差异。
Git 的优点
* 用户端储存管理, Git 与Mercurial 都允许使用者选择从其他资料库拉回分支,这提供了一个前端结构来减少本地端储存的异动记录。除此之外, Git 允许舍弃较早拉回的分支, Git 还允许从本地端资料库将旧有的版本异动删除(同时仍然会保留这些分支的最新版本资料)。而在Mercurial ,如果一个分支是储存在本地端资料库,所有版本异动(从最初提交的版本)都必须存在,除了建立一个新资料库选择性将分支推进资料库外,没有办法删除分支资料。虽然他们正在开发这个部份,但是还没正式推出。
* 父阶层的数量, Git 在合并时支援无限数量的父阶层版本异动,而Mercurial 只允许两层。如果希望在Mercurial 做到N 阶层合并,使用者必须执行N-1 次的两层合并,虽然一般合并N 个父阶层资料时会建议采用Mercurial 的作法,但使用Git 时使用者可以一次完成。
* 分支点变更(Rebasing), Git 提供一个rebase 指令,可以在一个本地端分支修改分支点到一个较新的版本,例如某个人在开发一个产品的新功能,本地端分支也许已经从1.0 版开始,而如果开发过程主要的产品线已经更新到1.1 ,也许需要将1.0->1.1 的异动拉回本地端功能开发中的版本,并且将分支点从1.0 改为1.1 。在其他系统中,会透过合并1.1 的异动进入分支,合并也是从版本控制系统角度看来正确的事情,如果将焦点放在"过去状态的重制能力"。不过如果焦点是“制作一个简洁的软体改版记录" ,分支点变更有时会比较好。 git-rebase 允许让一个过去未连续的异动记录能够连贯,让异动记录可以简洁些。正确的说,这个功能其实是将1.0 版的所有异动个别提交到1.1 版,分支点变更功能是安全的执行这些操作,并且删除1.0 版,因此不会让树状结构变得混乱。
备注: Mercurial 在这份文件完成后已经有加入了分支点变更功能。
Mercurial 的优点
* 学习曲线,基于许多的事实, Git 跟Mercurial 比起来有着比较陡峭的学习曲线。 Git 有比较多的指令与选项,这些功能的说明可能会让新使用者备感威胁。 Mercurial 的文件对于新手来说相对完整与容易阅读,Mercurial 的用词与指令也比较接近Subversion 与CVS ,因此对于从那些系统转移的人们来说会比较亲切。
* 支援Windows , Git 有着强大的Linux 包袱,在Windows 执行它的正式作法是透过cygwin ,对于一个Windows 使用者来说不是非常理想。一个使用MinGw 改写的Git 渐渐受到欢迎,但是Windows 在Git 世界中仍然是一个次等公民。在有限的测试中, 使用MinGW 改写的版本看来提供了完整的功能,但是有点迟钝。一些在Linux 或Mac OS X 几乎是即使反应的操作,在Windows 中可能需要十几秒。 Mercurial 是使用Python 开发,而且正式版本在Windows 下执行顺畅(在Linux, Mac OS X 等系统也是)。
* 维护, Git 需要定期维护资料库(例如git-gc),而Mercurial 不需要。不过需要注意的是, Mercurial 对于用户端磁碟空间的管理也比较没那么复杂(可以参考上面关于用户端储存管理的说明)。
* 记录是不容侵犯的, Git 非常强大,可以执行任何你想做的事情,不幸的是,这也意谓着Git 也很容易遗失记录。举例来说, git-push –force 会让远端资料库的版本异动消失;Mercurial 的资料库结构比较像是不可变物件持续成长的集合,虽然在部份情况下(像是rebase) ,改写记录是有优点的,但这也很危险,可能会导致无法预期的结果。不过需要注意的是, Git 伺服器可以透过设定来避免遗失资料,所以Mercurial 这个优点并不是那么明显。
其他差异
* 档名更改/复制的追踪, Git 并不会明确的追踪档名更改与复制,取而代之的是像git-log 指令用来比对资料库记录中是否有同样的档案来推论档名更改或复制。 Mercurial 以比较熟悉的形式,提供明确的档名更改与复制指令,并且将这些操作储存到档案的记录中。两种方式各有其优缺点,哪个比较好并没有比较明确且普遍的答案。
* 架构, Git 原本是以C 设计的大量shell scripts 与unix 指令,随着时间推演,在指令间共用的函式库已经开发完成,许多指令已经内建在主要的git 执行档。 Mercurial 大部分是用Python 设计(少部份使用C),包含一个外挂的应用程式介面,允许透过自行设计的Python 模组加强Mercurial 功能。
* 私有记录,在Git ,开发者操作的预设模式是使用自己本地端(与私有)的标签、分支与版本异动,而且在公开后可以运用许多控制。而Mercurial 强调另外一种方法,预设的推/拉行为会共享所有资讯,如果只想共享一部份就需要额外的步骤。这没有列在任一系统的优点,因为两者都支援另外一种操作。
* 分支命名空间,在Git ,每个资料库有自己的分支命名空间,使用者可以设定本地端分支名称与远端对应情形。在Mercurial ,所有资料库共用一个分支命名空间。
实作考量
资料储存
Git 与Mercurial 内部使用非常相近的资料:档案版本异动与少量的后设资讯(父层资料、作者等),两者都有代表整个专案提交的物件,这些物件也都有版本记录。两者都有记录每次提交所有档案的版本。在Git 使用的是一个树状物件(一个树状结构,包含目录的树状物件与档案版本参考的树叶结点)。在Mercurial ,使用一个物件清单(一个对应路径名称到档案版本物件的清单)。除了物件清单与树状结构的差异外,两者在物件的搜寻与走向都相当接近。
Git 直接在档案系统使用一个储存物件的集合(透过SHA1 杂凑索引) 并且将多个物件打包成更大的压缩档;而Mercurial 使用一个改版记录结构(基本上是一个连续的改版差异,加上定期的完整版本备份)。在实作时都不会使用原本的储存方式,物件都会储存在Bigtable 中,基于Git 与Mercurial 在基础资料物件的相似情形,无论使用哪个应该花费的时间一致。
在资料储存时的唯一主要差异是使用的语言,如果要重复运用大部分Git/Mercurial 的程式码, Git 的部份需要使用C ,而Mercurial 则是使用Python (或也许是C++ 与SWIG 的结合) 。
Mercurial 整合
Mercurial 在远端资料库的推拉操作提供基于HTTP 不依赖状态特性的良好支援,开发者花费了许多精神在减少用户端与伺服器间往返检查需要交换的资料,且一旦完成检查,所有相关资料会集合起来一次大量传输,这符合了Google 的架构,所以在用户端不需要任何改变。
Git 整合
Git 包含了推向HTTP 的功能(与推向WebDAV ),但是程式假设伺服器端对于Git 没有任何准备,它的设计是以Apache 将Git 资料库当作静态档案的情况下,这个方式需要大量为了同步化的请求往返,不适合用在Google Code 。
Git 也提供了一个自订的、依赖状态的协定,支援比较快速的资讯交换,但是不符合Google 的架构,因为Google 非常需要不依赖状态的HTTP 协定,因为已经在这个架构上投入了大量资源让它稳定且有效率的执行。
备注: 在这份文件完成后Git 社群已经开始有些改善HTTP 支援的讨论。
总结
基于实作上的差异, Mercurial 有着明显的优势,因为它对于HTTP 传输协定的支援。
不过就功能性而言, Git 确实比较强大,但也相对意谓着使用上更加复杂。 |
|