CODING 代码多仓库实践
关于代码的管理问题已经讨论多年,随着企业业务的复杂度提高、软件行业技术栈的选择度变宽泛,现代软件的代码仓库也变得越来越庞大和复杂。一个中型项目,将测试代码、核心业务代码、编译构建、部署打包等基础设施的代码全部加起来,几十万行都是家常便饭。并且一个项目往往由多个团队进行协作,如何让多团队在对同一个项目的代码进行协作时不会相互干扰、相互制约,也是每个企业研发团队在实践中不断摸索的难题。
多仓库与单仓库
对于上文所说的一些问题,业界已经归纳了常见的代码仓库存放方式,常见的如单仓库和多仓库。大部分企业会针对不同的项目采用不同的仓库管理机制,所以对于企业来说,经常会两种方式并存:
- 单仓库
将所有项目代码存放在一个代码仓库当中,这个好处在于项目的所有开发者可以共享看到项目中的所有代码;在项目规模较小的时候,一个库可以更好地管理和维护,发版本只要统一发布即可;对于持续集成,也只需要针对一个库维护若干条流水线。但再好的实践以及工具都有它适用的范围。Git 已经是非常流行的代码托管工具,但 Git 会把所有历史记录以及代码同步到各个用户的本地机器,所以对于大型项目而言,如果使用单仓库,就意味着某个模块开发者的本地可能有大量冗余代码和提交记录的信息,这个时候拆分成更小的库显得更加合适。
谷歌与 Facebook 就是业界典型的单仓库派代表。作为代码行数已经超过数十亿行、commit 数量累计达到千万次的团队(2015 年的统计数据),如果没有强悍的基础设施,也很难运转顺利。Google 曾发表论文介绍其强大的代码管理系统 Piper 以及客户端工具 CitC,但对于大部分企业来说是否有必要投入如此之大的研发成本去自研一个代码管理系统值得商榷,所以谷歌的实践对于大部分企业来说不一定具备参考性。

*谷歌代码仓库每周的提交数量
- 多仓库
将项目代码进行一定的拆分放在多个库当中,好处就是将代码进行一定的解耦,对于体型较为庞大的项目来说管理上会更加清晰和富有弹性。将代码按照一定逻辑分库之后,仓库与模块有了自描述的特征,让一起协作的开发者可以一目了然。发布源码版本、持续集成构建时,负责各仓库的研发组织可以按照自己的节奏来发布,同时将一些“坏代码”的影响控制在某个仓库中,而不会影响项目全部代码。分库也有要注意的地方,在同一个项目里的代码多多少少都有业务上或者是技术上的联系,比如编译依赖:以一个Java 项目为例,客户端接口的调用代码究竟是直接依赖服务端接口代码的定义,还是间接依赖?如果是间接依赖,那么分库管理是非常方便的,但同时客户端就无法快速感知到服务端接口定义的变化。所以在进行多仓库划分时,要注意划分的一些常用原则。
多仓库在业界使用的非常广泛,在腾讯、华为、阿里的开源项目中我们都能看到,比如腾讯的 Tars 开源项目(RPC 开发框架)就按照不同编程语言以及技术栈进行了分库:包括 Java、Go、PHP 等子项目。作为开源项目,一个清晰的分库可以让开发者更好地协作,避免不必要的沟通成本。

*Tars 的开源项目子仓库
CODING 的多仓库实践
CODING 在多仓库实践上也遇到过问题。由于前端、后端、git-server 三个模块的代码放置在同一仓库中,以至于代码版本的 tag 需要保持同步,制约了各个团队的开发节奏。每个模块的进度都得齐头并进,才能保证最终版本是一致的。尽管它们在业务上紧密相连,但实际上这几个模块本身没有编译依赖,所以在没有多仓库功能时,我们只能建立了三个项目,使用三个项目的代码仓库能力,只集中在一个项目当中进行项目管理工作。
在千呼万唤中,CODING 近期终于正式上线了多仓库功能,我们的开发人员也终于可以告别傻乎乎地使用一个项目进行管理,又用多个项目进行代码仓库管理的尴尬问题,我们将那些没有编译依赖的项目,但在业务上又有联系的代码仓库,放置在同一项目的多仓库下,开发人员无需在多个项目中切换。

多仓库功能一直是 CODING 想要投入做的一个特性。随着近几年 CODING 企业用户的快速增长,CODING 的架构也面临着持续的挑战。如何让交付更加顺滑,让特性更快、更好地服务开发者,是我们进行架构演进的初衷。所以我们在很早之前就开始了容器化、微服务化的规划与实施,而在微服务化的过程当中,包括代码仓库管理在内的研发流程与组织方式也在配套前进着。多仓库这项基本能力就可以让多个微服务独立存放在独立的代码仓库当中,配套独立的持续集成流水线,让架构演进变得水道渠成。我们知道很多企业用户对多仓库有很大诉求,CODING 的多仓库已正式上线,欢迎大家前去体验。
业界常用实践
综上我们可以看到,代码仓库的组织方式往往和人员组织架构息息相关,而且代码库的拆分也往往和软件架构的演进息息相关。在现代软件架构逐渐由单体朝着分布式、微服务演化时,代码仓库和研发团队的粒度也在逐渐变小,从以前的集中式慢慢变为网状。但无论是单仓库还是多仓库,最终目的都是为了让开发者更加高效地进行研发。那究竟该如何选择?笔者总结了几条业界的通用实践来供大家思考:
- 技术栈不同的模块建议多库存放
不同技术栈的编译环境、构建环境、发布环境往往不同,代码之间的硬性依赖也不大,可以考虑分库存放。大部分的开发者还是倾向于在工作中持续使用某一种熟悉的编程语言,所以按照技术栈划分是一个常用的实践。
- 仓库的粒度最好和组织架构相匹配
拆库要拆到什么粒度呢?有些研发组织微服务化后,给每个微服务都分配了一个代码库,随着拆分深入,一个项目积攒了几百个代码库。但一个 two-pizza 团队往往会负责多个微服务,不仅仅是一个。所以建议不要盲目使用大量代码库,避免到后期难以管理,可以考虑按照团队组织来划分代码仓库。
- 拆库并不意味着建立部门墙
不少企业代码拆分之后可能顺便就把团队之间的代码权限也做了划分,建议研发团队慎重考虑。关闭了代码权限就意味着,团队与团队之间不再互相 review 代码,相应的工作上的交流也会逐渐减少。如果读者的企业属于内部开放型氛围的公司,或者想要成为开放型的公司,那么关于此点请三思。
CODING 代码多仓库实践的更多相关文章
- Coding 代码管理快速入门
当项目创建好了之后,我们该如何上传代码到 coding 上呢?Coding 网站使用“ Git 仓库”(类似 github )来管理代码.其操作原理在于:利用 git 服务,将本地的项目目录下的文件同 ...
- Coding 代码管理快速入门(转)
当项目创建好了之后,我们该如何上传代码到 coding 上呢? Coding 网站使用“ Git 仓库”(类似 github )来管理代码. 其操作原理在于:利用 git 服务,将本地的项目目录下的文 ...
- 通过git提交代码到仓库
昨天有一个妹子问我如何在还没有commit之前push本地的代码到仓库,现在写写,希望能够帮到大家. 当我们pull的时候会出现没有代码commit的错误提示,在这种情况下,我们需要再commit之前 ...
- 20145212 罗天晨 《网络对抗》Exp3 Advanced 恶意代码伪装技术实践
恶意代码伪装技术实践 木马化正常软件. 啊哈--原本以为很复杂--然后我看了一下蔡野同学的博客,发现原理竟然如此简单-- 对原先生成病毒的代码稍作修改: 于是--把生成的后门软件改成骗人的名字:这里改 ...
- (转)私有代码存放仓库 BitBucket介绍及入门操作
转自:http://blog.csdn.net/lhb_0531/article/details/8602139 私有代码存放仓库 BitBucket介绍及入门操作 分类: 研发管理2013-02-2 ...
- 20145208 蔡野《网络对抗》Exp3 Advanced 恶意代码伪装技术实践
20145208 蔡野<网络对抗>Exp3 Advanced 恶意代码伪装技术实践 木马化正常软件 思路: 在正常软件包中将原本的程序主文件(平时打开程序用的exe文件)改成dll后缀(或 ...
- 使用scm-manager搭建git/svn 代码管理仓库
使用 scm-manager 搭建 git/svn 代码管理仓库 1.在官网上下载scm-manager 下载地址https://www.scm-manager.org/download/ 2. 配置 ...
- (转载)PyTorch代码规范最佳实践和样式指南
A PyTorch Tools, best practices & Styleguide 中文版:PyTorch代码规范最佳实践和样式指南 This is not an official st ...
- gitee上传代码到仓库步骤(最简洁图文+命令说明)
gitee上传代码到仓库步骤(最简洁图文+命令说明) 目录 1.初始化项目 2.将当前目录下所有需要上传的文件代码等资源添加到缓存区 3. 提交缓存区里面的主要内容到本地仓库 4.添加一个远程仓库的地 ...
随机推荐
- 安卓开发之Java学习
Java之素数(这里附上王智超大佬的博客地址)https://blog.csdn.net/weixin_43862765/article/details/103311286
- 品优购详情页---产品详细信息区域 iteminfo_wrap
产品详细信息区域为整个大盒子命名为: iteminfo_wrap 1号盒子命名为:sku_name 2号盒子命名为:news 3号盒子命名为:summary step1:3个盒子搭建框架,以及完成前两 ...
- X86架构CPU常识(主频,外频,FSB,cpu位和字长,倍频系数,缓存,CPU扩展指令集,CPU内核和I/O工作电压,制造工艺,指令集,超流水线与超标量)
1.主频 主频也叫时钟频率,单位是MHz,用来表示CPU的运算速度. CPU的主频=外频×倍频系数.很多人认为主频就决定着CPU的运行速度,这不仅是个片面的,而且对于服务器来讲,这个认识也出现了偏差. ...
- 安装破解版IntelliJ IDEA
1.下载IntelliJ IDEA http://www.jetbrains.com/idea/download/#section=windows 选择Ultimate版本 2.注册码破解 http: ...
- 微信SDK接入报undefined symbol错误
按照官方SDK接入 编译后报如下错误 是因为没有link libc++库导致的.
- 使用 nginx 实现虚拟主机
当多个系统需要部署的时候,有系统访问很小,为了节省成本,就需要将多个系统部署到同一台服务器上,怎么在同一台服务器上,完成不同系统的部署和访问,就需要使用虚拟主机实现. 使用端口实现虚拟主机 配置 ng ...
- maven与ecplise的整合
Maven 概念: Maven 使用项目对象模型(POM)的概念,可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. Maven 除了以程序构建能力为特色之外,还提供高级项目管理工 ...
- dotnet core gbk 编码错误解决方案
.Net Core GBK解码 1.添加引用 System.Text.Encoding.CodePages 2.注册 Encoding.RegisterProvider(CodePagesEnco ...
- Nginx目录结构与配置文件详解
Nginx安装 具体安装nginx请移步:[nginx部署] 安装依赖 安装pcre依赖软件 [root@ubuntu ~]# yum install -y pcre pcre-devel //外网情 ...
- CSUOJ 1952 合并石子
现在有n堆石子,第i堆有ai个石子.现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数.求合并所有石子的最小代价. Input 第一行包含一个整数T(T<=50 ...