为什么选择 git 来作为代码版本控制系统

本文最后更新于:3 年前

版本控制系统

代码作为软件研发的核心产物,在整个开发周期都在递增,不断合入新需求以及解决 bug 的新 patch,这就需要有一款系统,能够存储、追踪文件的修改历史,记录多个版本的开发和维护。于是,版本控制系统(Version Control Systems)应运而生,主要分为两类,集中式和分布式。

集中式版本控制系统

集中化的版本控制系统,诸如 CVS,SVN 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。

这么做最显而易见的缺点是中央服务器的单点故障。如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。要是中央服务器的磁盘发生故障,碰巧没做备份,或者备份不够及时,就会有丢失数据的风险。最坏的情况是彻底丢失整个项目的所有历史更改记录。

集中式版本控制系统的优点:

  1. 操作简单,使用没有难度,可轻松上手。
  2. 文件夹级权限控制,权限控制粒度小。
  3. 对客户端配置要求不高,无需存储全套代码。

集中式版本控制系统的缺点:

  1. 网络环境要求高,相关人员必须联网才能工作。
  2. 中央服务器的单点故障影响全局,如果服务器宕机,所有人都无法工作。
  3. 中央服务器在没有备份的情况下,磁盘一旦被损坏,将丢失所有数据。

分布式版本控制系统

分布式版本控制系统的客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份。可能有人会问,我们公司使用 git 工具,也有”中央服务器”啊?其实,这个所谓的”中央服务器”仅仅是用来方便管理多人协作,任何一台客户端都可以胜任它的工作,它和所有客户端没有本质区别。

分布式版本控制系统的优点:

  1. 版本库本地化,版本库的完整克隆,包括标签、分支、版本记录等。
  2. 支持离线提交,适合跨地域协同开发。
  3. 分支切换快速高效,创建和销毁分支廉价。

分布式版本控制系统的缺点:

  1. 学习成本高,不容易上手。
  2. 只能针对整个仓库创建分支,无法根据目录建立层次性的分支。

svn or git?

svn 和 git 作为集中式和分布式版本控制系统的代表,都有广大的使用群体,两者的优缺点经常被比较。其实,工具对我们来说,就是帮助我们有效提升工作的效率与质量,最适合的就是最好的。我们引用几个开发场景来看看两个版本控制工具的适用范围。

场景一

公司 A,非纯技术开发,项目包含大量媒体设计文件,相关人员只需下载自己关注的部分文件;员工 PC 电脑配置不高,没有空间拷贝整个项目资料。

适用:svn

分析:只需公司有一个足够大的服务器硬盘,员工本地只存储自己相关的文件夹,不必下载不想关的媒体文件,避免浪费文件传输时间。

场景二

公司 B,嵌入式底层开发,项目人员较多并且分布在两个城市,代码庞大;用分支管理多机种并行开发,机种间经常相互合并新特性,新 patch。

适用:git

分析:

  1. git 有能力高效管理类似 Linux 内核一样的超大规模项目;
  2. git 实现了离线开发、代码审核特性,解决了跨地域协同开发中代码质量和编码协同的问题;
  3. 分支管理功能强大,便于查询和追溯分支间的提交历史;
  4. git 基于 DAG(有向非环图)的设计比 svn 的线性提交提供更好的合并追踪,避免不必要的冲突,提高工作效率。

场景三

公司 C,某行业软件开发,包含敏感重要数据,代码仓库和版本发布权限掌握在客户手中,代码安全要求高,公司开发人员先将代码提交到本地仓库,只有在客户审核通过才能提交到发布仓库。

适用:git

分析:

  1. git 通过哈希加密保证数据的完整性,防止恶意篡改;
  2. 代码分布存储,异地容灾,保证数据安全;
  3. git 支持团队成员自建本地版本库和分支,只有客户发出合并请求,开发人员才能提交代码,客户可以对提交说明、代码规范等方面逐一审核。

讨论

可以参考此 博客 和 Linus 2007 年在 Google Talk 中对 Git 的 介绍

上文首先介绍了集中式管理系统的缺点:

  • 工程师必须都需要连接网络才能开发,在网络状况不好或者无网络的情况下无法进行提交;
    • 很多人可能认为自己并没有离线工作的需求,但是这实际上在我们的日常工作中也比较常见,百兆带宽虽然已经能够满足日常开发的需求,不过在复杂的网络环境下,很多时候我们还是会遇到无法联网或者网络极差的场景,例如在飞机和火车上;
    • 对于一个较大的分布式开发团队,在实际生产中我们也难以保证所有成员都能同时通过骨干网等高速网络连接到同一个主仓库;
  • 对中心仓库的提交和改动,例如创建分支等操作对于所有的开发人员都是可见的;
    • 当我们使用集中式的开发模型时,无论是提交代码还是创建新的实验分支,这些操作其实都会改变所有人共享的代码库,这也就意味着如果某个开发者创建了很多的实验分支,所有开发者的代码库也都会变大;
    • 虽然我们能在中心仓库中创建分支,但是由于中心仓库中不存在名空间,如果开发者创建分支没有遵循特定的命名规则,就非常容易出现命名冲突的问题,例如各种 test 分支;
  • 当前仓库的所有开发者都需要有直接向主仓库提交代码的权限,否则他们就无法进行开发;
    • 同时让项目中的所有开发者具有写权限其实是一件危险的事情,我们并不是知道这些开发者是否有着足够的经验操作主仓库,一旦出现操作上的失误,所有的成员都将面临这一失误带来的风险;

接着 Git 完美的解决了以上问题:

  • Git 作为分布式的版本控制系统能够让开发者离线工作和本地提交,不仅能够避免直接提交大量代码带来的风险,还能帮助我们限制对主仓库的授权,减少由于命名空间导致的冲突问题;
  • Git 在优化性能时选择了合并分支作为主要的性能衡量指标,将合并分支变成了成本非常低的操作以鼓励分支的使用;
  • Git 通过 SHA-1 哈希来保证仓库中数据的可靠性,我们通过 SHA-1 就可以对数据进行校验,保证整个提交链条上的所有数据的稳定性和可靠性,也帮助我们抵御了来自攻击者的恶意篡改;

此外也可参考此 知乎上大家的讨论

总结

不难看出,git 凭借自身的优势,完美解决了大多数公司对版本控制工具的诉求。在当今敏捷开发成为主流,研发周期短,跨地域协同开发多的大形势下,选择 git 是大势所趋。

参考资料


为什么选择 git 来作为代码版本控制系统
https://tanxinyu.work/git-or-svn/
作者
谭新宇
发布于
2020年11月9日
许可协议