1. 从开始工作到现在,我经历过没有代码版本管理、代码集中式管理,以及现在的分布式管理,我深刻体会到它在软件开发过程中的重要性;

  2. 我在工作中遇到的很多客户都存在对于代码版本管理的各种问题、困惑和不同的需求。

所以我希望将我在这个方面的经验分享给更多人,希望能帮助更多的团队解决在代码版本控制方面的问题和疑惑。

一、代码版本管理系统的历史

代码版本管理系统大致可以分为三个时代:

第一代:本地式

这代主要的特点提供本地代码版本控制,比如SCCS(1972)、 PVCS(1985)等。

这代主要实现了基本的代码版本管理,但缺点是无法让多人同时对一个版本库进行修改。这个也和当时软件规模不够大有关,也没有这样的需求。

第二代:客户端-服务器式

这代主要的特点是提供集中式服务器端代码版本控制,比如 CVS(1986), ClearCase(1992), Visual SourceSafe(1994), Perforce(1995), Subversion(2000) 等。

这代主要是实现了中心服务器端的代码版本管理,特点是可以让多人同时对一个代码版本库进行同步和修改,但缺点也相当明显:

  1. 在无法连接服务器的情况下,无法查看日志以及提交和比较代码版本(慢速网络和远程异地工作的程序员的痛),以及当服务或者网络出现问题的时候很多人员就会无法工作。

  2. 不支持local branch,导致branch创建管理复杂,并且一旦创建就很难修改(快速迭代开发中的程序员的痛)

  3. 由于只有一个中心端服务器,一旦发生灾难性问题,那么所有日志都会丢失,所以需要经常做备份(备份需要不小的成本)

  4. 如果软件代码量过于庞大,一般会出现速度缓慢的情况,因为每次的日志查询、不同版本之间的代码比较和代码提交等操作都需要和服务器通信,造成服务器端的负载过大。

第三代:分布式

这代主要的特点是提供分布式代码版本控制,比如Git(2005), Mercurial(2005)等。

这代结合了第一代和第二代的优点并实现了分布式的代码版本管理。

这代的优点:分布式管理,在没有和服务器有连接的情况下仍然可以查看日志,提交代码,创建分支;支持local branch,可以快速方便的实现各种分支管理;支持分布式,从而可以实现分块管理,以及负载分流管理。

缺点是有一定的学习曲线,比如分布方式下的代码同步,local branch的理解与运用,分布式代码管理的理解与运用等。详细的比较可以参考:这里。

二、大型分布式团队

曾经有这样一个分布式团队,他们在多个城市都有小分队,并且正在开发一个大型项目,见下图

他们使用的代码版本管理工具是第二代代码管理工具SVN,管理方案如下:

但是他们在使用的过程中却遇到了下面这些问题与痛点。

由于是分布式团队,所以:

  • 基于团队的代码模块分离困难

当服务器不可用时:

  • 不能查看提交记录

  • 不能比较文件

  • 不能提交代码

创建代码分支时:

  • 分支创建速度慢

  • 多分支管理困难

在提交代码时:

  • 希望有Code Review

  • 希望有CI Review

因为代码庞大:

  • 查看日志慢

备份代码库的时候:

  • 需要停机备份

  • 备份成本高

针对以上问题,可以使用新一代的分布式的代码版本管理系统来解决,见下图:

其中每一个团队都有自己独立的代码库,有一个中心库用于同步这些独立的代码库,并且每个库都由团队自己管理和维护。而且代码版本管理系统需要支持轻量分支,代码评审,离线提交,离线查看日志等功能。

但是由于当前没有一个单一的代码版本管理工具能同时满足以上所有需求,所以很多公司都基于它们开发集成管理系统,比如Gerrit,GitLab,GitHub,BitBucket等。其中的Gerrit由于其开源,免费,以及由Google开发和维护,并管理着Android,OpenStack等大型项目源代码的特点,成为了大型分布式团队优先选择的系统。

三、Gerrit

Gerrit是由Google开发的,用于管理Google Android项目源代码的一个系统。它是基于Java和Prolog等开发的,支持Git,权限管理,代码评审等综合的一个管理系统。它与GitLab和GitHub最大的不同是它隐藏了代码分库管理的细节,使得开发人员不需要进行fork这样的手工分库和同步操作就可以进行代码开发和提交,节省了开发人员的时间,见下图。

由于Android本身是一个开源项目,所以贡献者非常多,开发团队也遍布多个地方(存在时差),导致“如何保证代码质量”成为一个很大的问题。为此Google在Gerrit中加入了功能强大并且十分严格的代码评审系统。

首先当代码提交以后并不会直接merge到中心库里面,它会暂时存在一个临时库里面,同时生成一个代码评审记录,并向特定的评审人员发送请求评审的邮件。当评审者在评审代码之后,如果通过就需要在Gerrit系统里面对代码进行打分,如果通过了就可以将代码merge到中心库里面去,如果没有通过,那么这个代码提交就需要被返还给开发者进行修改。

与此同时它还可以自动触发一次包含本次代码提交的CI构建(前提需要手工预先配置),如果CI自动构建和测试通过,也可以自动在Gerrit系统里面进行打分,可以给最终进行merge的人员进行参考。示意流程见下图。

由于Android源代码由上百个独立的代码库组成,并且编译一个Android系统需要大部分代码库里面的代码,所以如何管理如此多的代码库也是一个难题,比如如何一次性同步需要编译一个需要支持特定设备的代码库组合。为此Google基于Python语言开发一个工具叫Repo ,这个工具可以自定义你需要的代码库的组合,并且一次性对这些代码库进行同步,比如pull和push,见下图。

四、SVN到Git的迁移

对于想从集中式代码管理系统迁移到分布式代码管理系统的团队来讲,如果团队规模小,那么问题一般都不大,但是对于大型分布式团队却是困难重重。最主要的两个困难:

  1. 代码量太大,很难一次性将所有的代码和日志等在短时间内迁移成功。

  2. 由于下属团队太多,很难同一时间让所有团队都切换至新的代码管理工具。

为了解决这些难题,一般都会首先选用1个团队来使用新的代码版本管理工具。如果这个团队转换成功,再将其作为标杆向其他团队推广,从而逐步的将所有团队切换到新的工具上去。

SVN到Git的迁移方案一般主要会使用两种工具:

  1. 开源免费的git-svn;

  2. 商业收费的Subgit。

其中使用Subgit的迁移方案如下图:

如果团队组资源充足,还可以使用Gerrit搭建一个独立的Git服务器,从而以分布式的方式进行代码迁移,如下图:

五、多产品线的管理

使用同一个中心代码库管理多产品线一直是大型项目的一个困难点,特别是使用SVN这样的工具更是难以管理,因为SVN这种工具的Branch本质上是一个目录拷贝,并且速度慢,而且代码回迁也需要手动进行。但是如果使用Git的特性来管理多产品线,比起SVN是事半功倍。具体方案见下图:

总结

分布式代码版本管理系统并不一定适合所有团队,比如中小团队可能更关心的只是成本更低,简单易用,那么SVN等这类集中式版本管理工具还是更为适合。但是不管团队最终选用什么代码版本管理工具,只要适合自己的团队的开发流程和工作方式,并且代码管理顺畅就可以了。

Git学习总结(17)——大型分布式团队的代码版本管理相关推荐

  1. Git 学习笔记:5 分布式工作流程

    Git 学习笔记:5 分布式工作流程 分布式工作流程 集中式工作流 集成管理员工作流 司令官与副官工作流 工作流程总结 向一个项目贡献 提交准则 私有小型团队 John's Machine 私有管理团 ...

  2. git学习(九)跨团队协作-非团队成员参与git项目开发

    资料来自 B站 尚硅谷,侵权删 跨团队协作开发流程 fork流程 1.拿到源仓库的HTTPS地址 微信或其他的途径,将HTTPS链接发送给协作开发的人(非团队内部人员) 这里登录另外一个账户为例 登录 ...

  3. 三路合并 —— Git 学习笔记 17

    三路合并 和其他版本控制系统不同,Git 提供的合并冲突解决方案并不会聪明过头,不会尝试自动将所有问题都解决.Git 的设计哲学是智能判断一个合并是否可以非常容易地自动完成,如果自动化方案不可行,就不 ...

  4. 分布式版本控制系统Git学习资源收集汇总

    伴随着知乎上一个问题:GitHub 是怎么火起来的?被顶起200+的回答说到:Github不是突然火起来的,在Ruby社区Github其实从一开始就很流行,我们2009年搞Ruby大会就邀请了Gith ...

  5. 敏捷开发“松结对编程”实践之六:大型团队篇|后记(大型研发团队,学习型团队,139团队,师徒制度,人员招聘,职业生涯规划)...

    本文是"松结对编程"系列的第六篇.(之一,之二,之三,之四,之五,之六,之七,之八) 松结对编程是小型团队的实践,大约运行在1个师傅+1-3个徒弟的尺度上,当面临更大尺度的时候,就 ...

  6. Git 学习之团队协作(Gitee实操)

    前言 原先都是自己独立开发,所以在协作开发这块的技能有所欠缺,对Git命令的使用还停留在独立开发上,平常用的最多的命令就是: git status git add --all git commit - ...

  7. Git详解之五:分布式Git

    原文链接:http://blog.jobbole.com/25660/ 原文:<Pro Git> 为了便于项目中的所有开发者分享代码,我们准备好了一台服务器存放远程 Git 仓库.经过前面 ...

  8. git拉取tag代码_10年经验17张图带你进入gitflow企业项目代码版本管理的最佳实践...

    前言 对于项目版本管理,你是否存在这样的痛点:项目分支多而杂不好管理,git log界面commit信息错乱复杂无规范,版本回退不知道选择什么版本合适--. 项目版本管理的最佳实践系列,笔者将以两篇文 ...

  9. git学习指南_GIT 学习指南

    创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录: $ mkdir learngit $ cd learngit $ pwd /Users/michael/learngit pwd命令 ...

最新文章

  1. windows优化大师8周年纪念版_《数码宝贝》20周年纪念:当年的八神太一与亚古兽你还记得吗?...
  2. 爬一爬 iPhone 11为何嘴上说真丑,销量却真香?
  3. 一、JVM及Java体系结构
  4. 记个maven无法识别JAVA_HOME的问题 Error: JAVA_HOME is not defined correctly.
  5. matlab-画个拱桥和倒影?
  6. Android学习笔记之SoftReference软引用,弱引用WeakReference
  7. php入门的ppt,php学习 字符串课件
  8. 5G 芯片的“春秋五霸”
  9. windows Windows Defender彻底删除屏蔽后台启动占用内存 win10防火墙 windows10防火墙
  10. 《C语言到底能干什么》1.3 窗口程序的编写
  11. 单片机3种烧录方式解析
  12. 【题解】UVA177 分治
  13. 魔兽版无间道,5区一骗情骗装备的垃圾战士(zz)
  14. java摇两个色子代码_摇个骰子 - mokuang - 博客园
  15. npm 包解析 eml 文件
  16. 分析了一个小说站,速度挺不错的,顺便学习下js
  17. potplayer默认专辑加载同一文件夹下所有视频,只读取一部分视频,加载视频目录不完整
  18. Vcc、Vee、Vdd、Vss傻傻分不清楚?
  19. c语言如何输入一篇英文文章,(急急,救命啊!c语言)输入一篇英语文章,求输出这篇文章的所有英语单词的个数。...
  20. Effective Python -- 第 2 章 函数(下)

热门文章

  1. 53. 最大子数组和(JavaScript)
  2. microsoftstore连不上网_win10系统下微软商店连不了网如何解决
  3. OpenCV4每日一练day9:单目相机标定
  4. c语言字符型数据怎么输入输出,C语言基础之数据类型与输入/输出
  5. android华为指纹开发_2020指纹芯片行业市场调研分析报告
  6. linux系统如何禁用网卡,Linux 中如何启用和禁用网卡?
  7. python3多进程写时拷贝_python利用进程池,多进程拷贝文件
  8. php折半查找算法,二分查找 [折半查找] 算法 PHP 版
  9. 抢红包 动画 android,疯狂猜动画红包版
  10. java socket 消息中转,Java中Socket实现消息传输(传输原型)