如何管理一个大型开源仓库?淘系带你一探究竟

简介: 对于每个开发者来讲,git 仓库是我们几乎每天都要接触的东西,但是实际上大多数的 git 仓库管理都是非常随性且不规范的,在某些情况下这样做并没有太大的问题,但是当协作成员逐渐增多、仓库职责逐步扩展时,很多原本不规范的小问题会被逐渐放大乃至产生一些极为严重的问题。

image.png

作者|刘雄(大果)

出品|阿里巴巴新零售淘系技术部

导读:对于每个开发者来讲,git 仓库是我们几乎每天都要接触的东西,但是实际上大多数的 git 仓库管理都是非常随性且不规范的,在某些情况下这样做并没有太大的问题,但是当协作成员逐渐增多、仓库职责逐步扩展时,很多原本不规范的小问题会被逐渐放大乃至产生一些极为严重的问题。本文将为大家介绍在管理过程中的实践经验。

作者所在的飞冰(ICE)团队在 2018 年 2 月开源了 alibaba/ice 这个仓库,经过不到一年的时间终于在 2018 年末达到了 1w+ stars 的里程碑,在管理这个仓库以及运营社区的过程中我们积累了一些或大或小的最佳实践,希望能分享出来帮助到其他开源或者没开源的 git 仓库管理者。

合理的拆分仓库

当我们说管理仓库的时候,其实面向的不是一个单一的仓库,而是一个产品、一个项目甚至一个业务,这背后可能会有多个仓库也可能只有一个仓库,因此在前期的规划上要尽量梳理清楚,核心避免两个误区:

误区 1:每个职责都建一个仓库

这个方案可能是多数人的直觉反应,但是这种方式会让产品对应的仓库数快速增多,导致长期管理成本陡增:

  • 仓库权限管理成本高且容易混乱
  • 代码开发提交成本高
  • issue/PR 太过零散,难以统计管理
  • ……

实际上,飞冰(ICE)原先在内部的时候,我们开发了很多业务组件,每个业务组件都是一个单独仓库,然后最近在做统一升级(工具、规范或者其他变更导致)的时候给我带来非常大的困扰:

  • 有的组件(仓库)已经不再维护但没有任何标记
  • group 权限管理太过松散导致出现一些跟官方无关的组件
  • 升级过程中需要频繁切换仓库操作

因此,我们需要避免过于零散的管理方式,结合实际场景做适当的聚合。

误区 2:所有的职责都用一个仓库承载

在前端社区里,随着 lerna 这个批量发布包工具的出现,这种方式越来越流行,一些非常热门的项目比如 babel、React、jest 等都逐渐迁移到这个方案。先抛开 lerna 这个工具提供的能力,这种聚合式的管理方式给仓库管理者节省了很多成本,比如:

  • 只需要管理一个仓库
  • issue/PR/wiki 等都收敛到一个地方管理

但是在实践这种方式的时候有可能会走偏,还是以我所在的 ICE 团队做反面教材,踩了误区 1 的坑之后,在做开源版本的时候我们果断把所有包都放到同一个仓库,然后通过目录结构来保证职责清晰,这个方式也同样如上面所提到的给我们的管理带来了诸多便利,但在经历了一年的迭代之后目前也遇到了一些问题:

  • 职责多代表代码多,然后随着历史记录的增长,仓库 clone 速度一日不如一日,尤其在一些小公司的慢速网路环境下(即便加了 --depth)
  • 目录结构较为复杂,对有心贡献代码的社区同学不够友好

因此我们推荐「在方案 2 的基础上按照职责再做一层拆分」,结合 alibaba/ice 这个仓库,我们已经通过职责将 ice-devtools/ice-scripts/react-materials 等拆为独立仓库,这些仓库职责上足够清晰同时相关依赖聚合在一起不至于太过分散。

建立团队内的操作规范

笔者曾经有幸参与过淘宝前端团队的代码规范制定以及相关工具落地,因此深知规范之于团队的重要性,同时也有一些制定规范的原则:

(1) 规范首先保证正确,其次提升质量;

(2) 规范不能过多影响到效率(两者的权衡需要结合实际场景)。

以下就是我们目前在遵循的一些规范:

保护分支!

image.png

根据仓库情况设定保护分支,禁止直接往保护分支提交代码,在非常特殊的情况下 admin 账户可以绕过。

新建分支规则

image.png

  • 分支名称需要有语义,比如 ice-scripts/fix-foo-bug
  • 如果需求比较简单,时间周期比较短,那么直接从 master 切一个分支,然后通过 PR 合并后到 master,合并之后发布对应包的版本
  • 如果需求包含多个变更点,比如 iceworks 发布版本,往往涉及到多个功能点,开发周期一般会在一周左右,如果每个 PR 都往 master 上合并,很难把控整体的进度。因此我们有以下约定:

a.先从 master 切出 release 分支(如 release/iceworks-2.16.0),然后提一个基准 PR,PR 中需要补充当前版本包含的功能列表以及发布先后顺序等,该 PR 主要用于管理此次版本开发进度,release 分支不允许直接推送代码,同时合并到 master 时也无需 Review

b.然后每个功能变更都从 release 分支切出新分支,同时 PR 也需要合并到对应 release 分支,切出的分支不需要包含版本信息(比如 iceworks/fix-xxxx 即可)

c.等所有 PR Review 完成并且合并到 release 分支之后,在 release 分支进行发布,发布完成后再将 release -> master 的 PR 合并(此处不在 master 分支发布的原因是担心发布时可能会出各种问题,需要再次做代码变更)

commit message 规范

image.png

好的 commit message 可以让人快速了解代码意图,加速 review 进程,未来对于整个代码仓库的历史追溯也会更加方便,关于这一点社区有足够多的规范可以参考,此处不再一一赘述,有兴趣可以参考末尾的参考链接。

PR 合并流程

image.png

github 默认提供了三种合并 PR 的方式,关于三种方式的区别可以参考文末的相关链接,我们认为大多数情况应该选择 Squash and merge,因为 squash 会将当前 PR 的多个 commit 合并,让整个提交历史更加干净清晰。但是在将上文提到的 release 分支合并到 master 时建议使用普通 Merge,因此此时我们需要保留那些有效的 commit 记录。同时在合并 PR 的时候 Reviewer 有责任重新编写 commit message 以保证语义更加准确。

这里简单追溯一点历史:在最早期的时候,github 还没有提供 squash merge 的方式,当我们向开源仓库提交一个 PR 时,在仓库作者 review 完成之后一般会要求提交者将 commit 合并,因此很多人都有谷歌过「如何合并 commit」这样的关键词,而如今只需要点一下按钮即可,这也是工具对效率提升的一个体现。

发布流程

对于管理工具包的同学,都应该熟悉并且遵循 Semver 规范(语义化版本),这是原则,在此基础上需要遵循以下规范:

测试版本:版本号需要遵循 x.y.z-n 的规则,通过 npm publish --tag beta 发布,很多同学包含笔者本人经常会忘记 --tag beta,不知道有没有更加有效的方式约束?

正式版直接通过 npm publish 发布

正式版本发布之后,需要同时创建对应的 git tag,tag 命名规则:产品名/x.y.z,比如 ice-scripts/1.0.2,然后在 GitHub 上填写 Release 信息

其他

如何保证规范落地

结合曾经在淘宝前端团队推动的规范落地以及当下在 ICE 团队制定的规范,两点结论可供参考:

  • 规范需要保证多数人认可,然后由松到紧逐步迭代,人跟着规范逐步成长
  • 小团队靠素养,大团队靠工具:在小团队内制定规范,需要做的就是反复强调,逐渐让每个人形成习惯;而在大团队里显然是没法关注到每个人的,此时需要借助工具,比如 eslint,commit-check 以及像门神这种强流程的工具

如何迭代历史版本

上文说的一些工具包的发版,假设我有一个工具包 ice-scripts 在 1.6.5 的基础发布了一个 break change 的版本 2.0.0,正常情况下我们肯定是在 master 分支(2.0.0 的代码)的基础上逐步迭代,但 1.x 的版本可能还有用户使用,当我们需要修复 1.x 的一个 bug 时如何去做?这里推荐一个流程:

首先基于 git tag ice-scripts/1.6.5 切出一个 stable/ice-scripts-1.x 的分支(幸亏之前打了 tag,否则要找到对应的 commit 还是有点工作量的)

将 stable/ice-scripts-1.x 设为保护分支,可以理解为 1.x 版本的 master 分支

从 stable/ice-scripts-1.x 切出新分支 ice-scripts-1.x/fix-bar,然后修改代码提交 PR 到 stable/ice-scripts-1.x 分支上

Review 完成后合并代码,然后在 stable/ice-scripts-1.x 分支上进行发布

如何做好答疑

运营社区的过程一定需要频繁面对用户的疑问,如何在满足用户的同时又能保证自身投入不影响到正常工具显得极为重要了,对于技术产品,根据面向用户群体的不同目前两种主流答疑方式:

  • GitHub issue: 纯异步交流,保证所有问题讨论都能沉淀下来,同时因为异步沟通有成本,大家会努力一点表达清楚自己的意图,相对来讲沟通质量更高,但响应速度之类的无法保证
  • 类钉钉群:同步交流,响应速度快,但是对于维护者来说时间容易被打碎,降低工作效率

如何管理 issue

结合治理 ICE 的历史 issue 提供一些建议仅供参考:

  • 通过 issue 模板提升 issue 质量:ICE 仓库里早期的 issue 质量非常低,很多问题都无法复现
  • 基于产品纬度建立对应的标签分类,每个 issue 关联标签,然后由对应负责人统一处理
  • issue 不要求及时处理,但鼓励能通过沟通或其他方式快速明确问题,防止时间长了不理解 issue 的描述然后又无法跟 issue 作者沟通

如何运营社区

ICE 团队目前维护着 6 个钉钉答疑群(每个 1000 人)以及技术论坛的官方帐号,但整体活跃度都比较一般,目前无论是精力上的投入还是运营产品的经验都比较缺失,希望能得到一些建议或者支持。

有趣的机器人

github 上有很多方便的机器人(or App?),这里推荐个人觉得比较有用的两个机器人:

  • delete-merged-branch:合并 PR 之后会自动删除对应分支,防止无用分支的堆积
  • Weekly Digest:每周创建一个 issue,汇总仓库一周内的动态,比如:新增了哪些 issue/PR,有哪些人 star 了仓库等,示例 Weekly Digest (30 December, 2018 - 6 January, 2019)「https://github.com/alibaba/ice/issues/1264

今日话题

你认为还有那些有趣的机器人

欢迎推荐

对于 git 的操作,如果有不同的见解

欢迎评论区留言探讨

小编将针对有趣有价值的留言送出「淘系定制公仔1个咯」

相关链接

alibaba/ice 官方仓库

https://github.com/alibaba/ice

写出好的 commit message

https://ruby-china.org/topics/15737

5.1 代码合并:Merge、Rebase 的选择 (https://github.com/geeeeeeeeek/git-recipes/wiki/5.1-%E4%BB%A3%E7%A0%81%E5%90%88%E5%B9%B6%EF%BC%9AMerge%E3%80%81Rebase-%E7%9A%84%E9%80%89%E6%8B%A9

Semver 规范(https://semver.org/lang/zh-CN/

相关文章
|
23天前
|
存储 供应链 安全
《数据治理简易速速上手小册》第8章 数据生命周期管理(2024 最新版)
《数据治理简易速速上手小册》第8章 数据生命周期管理(2024 最新版)
38 1
|
2月前
|
自然语言处理 安全 数据挖掘
短剧系统开发/稳定版/海外版/多语言/成熟技术/方案项目/源码流程
The functions of the short drama system can include but are not limited to the following aspects:
|
8月前
|
消息中间件 缓存 Java
GitHub下载热榜,阿里技术官限时开源三份百亿级架构系统手册
在如今是属于高流量的时代,不知道各位了解高并发吗?今天给大家带来的是出自阿里大牛手写三份绝密手册,《百亿级并发系统设计》+《微服实战 +亿级流量网站架构核心技术》
243 0
|
4月前
|
消息中间件 缓存 算法
太全!不愧是Github爆火的阿里812页高并系统设计核心技术全解
某乎上有这样一个问答:现在好点的互联网公司招聘基本都要求有高并发经验,但没有高并发的经验的人感觉只有在好点的互联网才获得高并发经验,这难道不是死循环?没有高并发经验的人如何才能获取高并发方面的经验呢? 如何获取高并发经验? 其实并不是去了大公司就能获得高并发的经验,高并发只是一个结果,并不是过程。在来自全人类的高并发访问面前,一切都有可能发生,所以我们经常能看到顶级网站的颤抖。想要获得高并发经验基础最重要,这包括算法,操作系统,jvm,数据库,缓存,多线程等等。这些独立而又关联的知识其实书本里都有,我们需要时不时地去温习,不能一直痴迷于框架,框架只会挡住你的眼睛,让你觉得什么都不重要。大并发
|
4月前
|
缓存 算法 Java
首次公开!阿里巴巴最新高并发架构设计实录被我从Github扒下来了
前言 现在Java面试,问的是越来越底层。作为一名合格的Java程序员不仅要能“上天”,还要能“入地”!上天是指高并发,缓存,大流量,大数据量,能在更高的层面解决问题,入地是指从JVM,OS,算法,线程,IO这块刨根究底,对底层知识都能知其然还要知其所以然。 而本篇要跟大家探讨的就是“上天”这块的内容。据有关数据表明,现在基本工作年限超过5年的Java开发岗以及各大厂招聘岗位,对于这块内容是必定会考察的。这也就意味着,你想要在今年这个大环境下,找到一份薪水高且发展前景好的岗位,不关基础知识还要有良好的编码习惯和能力、排查问题、解决问题的能力以及整体系统的设计能力和架构能力。
69 1
|
7月前
02分布式电商项目 - 项目简介
02分布式电商项目 - 项目简介
28 0
|
7月前
|
架构师 Java 程序员
同事开源我的微服务深度实践笔记到GitHub,短短3天竟吸粉10W+
说Spring成就了Java,Spring是Java程序员必修课之一,应该没人反对吧? 前几年面试最常问的且可以顺利拿到高薪的技能是Spring,随着Spring体系的壮大,除非你在简历上添加Spring Boot和Spring Cloud的技能,才可以打动面试官,而现在,除非是Spring架构的扎实经验,否则难以让面试官高看。 一名合格的Java后端工程师或架构师,至少微服务架构是必须牢牢掌握的,这里也整理了整套微服务架构学习路线,准备作为福利送给大家,可以先看一下重点简图。
|
7月前
|
Dubbo Java 应用服务中间件
神作《Java多线程核心技术3》开源几分钟被下架!GitHub昙花一现
两天一次地分享好书环节又来了:高洪岩老师的 《Java多线程编程核心技术(第3版)》,网上还没有开源版本!阿嘴会在文末附电子版免费下载方式。
|
8月前
|
运维 Prometheus Cloud Native
GitHub强势置顶!阿里资深老专家微服务容器实战开发笔记限时开源
今天给大家带来的是:尹为强老师著的 《微服务容器化开发实战》,基于SpringCloud、Docker、Rancher、Prometheus和Kubernetes,从设计、开发、部署到运维的云原生整体解决方案
GitHub上疯传数万次的蚂蚁内部绝密分布式高可用算法笔记太香了
GitHub上疯传数万次的蚂蚁内部绝密分布式高可用算法笔记太香了!! 这份笔记包含10章的内容,每一章都分为若干小节,每个小节里面都包含更多细节化的内容。