之前发动态,希望自己入职后多发几篇文章记录所学知识。进入公司之后,发现大部分使用的是内部工具,而且教程大多比较规范,所以也没有找到什么动笔的理由和方向。今天主要想介绍一下公司代码版本控制系统。虽然是内部工具,但也跟外界开源工具有相当密切的关系。
公司有两套系统:一个叫Piper,相当于开源的Perforce;另一个是后来引进的Fig,相当于开源的Mercurial(以下简称hg)。虽然公司老兵更习惯用第一套,但是第二套有更完善的功能,在公司被广泛推广。我其实更好奇的是为什么第二套系统,公司采用hg而不是Git(以下简称git)。其实这是经过了大范围的旷日持久的讨论,而不是高层拍脑袋抛硬币在短时间内的决策。
有一个背景知识很重要,也是公司的文化:采用单个大仓库来管理代码。
我们先来看看需求。
- 窄克隆:只从Piper的目录中克隆部分目录,需要动态扩大/缩小的能力。
- 浅克隆:只在需要的时候惰性加载文件的历史。
- 修改.hg manifest或者.git index保证可扩展性。
- 与Clients in the Cloud(以下简称CitC)有良好的融合。
- 跨平台的支持:Linux, Windoes, Mac。
- IDE融合:Eclipse, Visual Studio, Android Studio。
- 保持安全特性比如对数据的遗忘的支持。
- 提供外部产品给企业(可选)。
在部分需求上,两种系统都有各自的问题。对于他们的改装都有不小的麻烦。对git而言,不停对.git目录进行改写可能导致较大的延迟。而且管理.git目录,可能需要垃圾回收机制解决长期客户端膨胀的问题。对hg而言,难以知道哪些改动已经被push到upstream里面。而且在外部的熟悉程度,git是远大于hg的(hg主要用户是Mozilla和Facebook),使用git能省去很大的学习成本。不过对于一个对git和hg都完全不熟悉的用户而言,hg的学习难度更小。而在对保持安全特性,两种方案都还不错。
我在下面列出总结之后选择hg的比较主要的原因。
- 从流程上而言,git与hg极其类似。但是hg与CitC的融合更合适,而git难以与CitC融合。
- git有三种实现(git-core, JGit, libgit2),且采用磁盘上的存储方式。需要对这三种实现都进行重写。而hg只有单个实现,对于非upstream的项目有较好的支持。
- git的存储方式是hash索引,而hg的存储方式是用路径。hg能与SrcProtect(与权限有关)更好融合。
- git在当时更专注于小型开源项目(之后有所改善),而hg有针对企业做的案例。而且hg团队协作起来更热情更舒服。
总结而言,两种方案没有绝对的优劣。不过公司已经选择了hg,不管git之后如何改进和演化,估计短时间都不会再被融合进来。