对于每个开发者来讲,git 仓库是我们几乎每天都要接触的东西,但是实际上大多数的 git 仓库管理都是非常随性且不规范的,在某些情况下这样做并没有太大的问题,但是当协作成员逐渐增多、仓库职责逐步扩展时,很多原本不规范的小问题会被逐渐放大乃至产生一些极为严重的问题。笔者所在的飞冰(ICE)团队在 2018 年 2 月开源了 alibaba/ice
这个仓库,经过不到一年的时间终于在 2018 年末达到了 1w+ stars 的里程碑,在管理这个仓库以及运营社区的过程中我们积累了一些或大或小的最佳实践,希望能分享出来帮助到其他开源或者没开源的 git 仓库管理者。注:对于 git 的操作,笔者自知还处于一个比较初级的阶段,如有错误的地方还望指出。
当我们说管理仓库的时候,其实面向的不是一个单一的仓库,而是一个产品、一个项目甚至一个业务,这背后可能会有多个仓库也可能只有一个仓库,因此在前期的规划上要尽量梳理清楚,核心避免两个误区:
这个方案可能是多数人的直觉反应,这种方式会让产品对应的仓库数快速增多,导致长期管理成本陡增:
实际上,飞冰(ICE)原先在内部的时候,我们开发了很多业务组件,每个业务组件都是一个单独仓库,然后最近在做统一升级(工具、规范或者其他变更导致)的时候给笔者个人带来非常大的困扰:
因此,我们需要避免过于零散的管理方式,然后结合实际场景做适当的聚合。
在前端社区里,随着 lerna 这个批量发布包工具的出现,这种方式越来越流行,一些非常热门的项目比如 babel、React、jest 等都逐渐迁移到这个方案。先抛开 lerna 这个工具提供的能力,这种聚合式的管理方式给仓库管理者节省了很多成本,比如:
但是在实践这种方式的时候有可能会走偏,还是以笔者所在的 ICE 团队做反面教材,踩了误区 1 的坑之后,在做开源版本的时候我们过段把所有包都放到同一个仓库,然后通过目录结构来保证职责清晰,这个方式也同样如上面所提到的给我们的管理带来了诸多便利,但在经历了一年的迭代之后目前也遇到了一些问题:
因此我们推荐「在方案 2 的基础上按照职责再做一层拆分」,结合 alibaba/ice
这个仓库,我们后续会把 React 物料代码、Vue 物料代码、Angular 物料代码分别拆出去成为三个独立仓库,一方面降低主仓库的体积,另一方面Vue 的贡献者不需要关心其他对他没有意义的文件目录。
笔者曾经有幸参与过淘宝前端团队的代码规范制定以及相关工具落地,因此深知规范之于团队的重要性,同时也有一些制定规范的原则:(1) 规范首先保证正确,其次提升质量;(2) 规范不能过多影响到效率(两者的权衡需要结合实际场景)。以下就是我们目前在遵循的一些规范:
根据仓库情况设定保护分支,禁止直接往保护分支提交代码,在非常特殊的情况下 admin 账户可以绕过。
好的 commit message 可以让人快速了解代码意图,加速 review 进程,未来对于整个代码仓库的历史追溯也会更加方便,关于这一点社区有足够多的规范可以参考,此处不再一一赘述,有兴趣可以参考末尾的参考链接。
github 默认提供了三种合并 PR 的方式,关于三种方式的区别可以参考文末的相关链接,我们认为大多数情况应该选择 Squash and merge,因为 squash 会将当前 PR 的多个 commit 合并,让整个提交历史更加干净清晰,但是在将上文提到的 release 分支合并到 master 时,是否应该将每个功能点的 commit 合并成一个 release commit,目前我们还没有思考清楚,希望能得到一些建议或者指导。同时在合并 PR 的时候 Reviewer 有责任重新编写 commit message 以保证语义更加准确。
这里简单追溯一点历史:在最早期的时候,github 还没有提供 squash merge 的方式,当我们向开源仓库提交一个 PR 时,在仓库作者 review 完成之后一般会要求提交者将 commit 合并,因此很多人都有谷歌过「如何合并 commit」这样的关键词,而如今只需要点一下按钮即可,这也是工具对效率提升的一个体现。
对于管理工具包的同学,都应该熟悉并且遵循 Semver 规范(语义化版本),这是原则,在此基础上需要遵循以下规范:
npm publish --tag beta
发布,很多同学包含笔者本人经常会忘记 --tag beta
,不知道有没有更加有效的方式约束?npm publish
发布,发布之后执行 tnpm sync
同步内部版本ice-scripts/1.0.2
结合曾经在淘宝前端团队推动的规范落地以及当下在 ICE 团队制定的规范,两点结论可供参考:
上文说的一些工具包的发版,假设我有一个工具包 ice-scripts 在 1.6.5 的基础发布了一个 break change 的版本 2.0.0,正常情况下我们肯定是在 master 分支(2.0.0 的代码)的基础上逐步迭代,但 1.x 的版本可能还有用户使用,当我们需要修复 1.x 的一个 bug 时如何去做?这里推荐一个流程:
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
分支上stable/ice-scripts-1.x
分支上进行发布运营社区的过程一定需要频繁面对用户的疑问,如何在满足用户的同时又能保证自身投入不影响到正常工具显得极为重要了,对于技术产品,根据面向用户群体的不同目前两种主流答疑方式:
作为常年活跃在答疑一线的开发者,自然知道答疑给维护者带来的成本,在这条道路上我们也处于探索阶段,目前倾向于的模式:
ICE 目前整体的 issue 管理做的不好,笔者也是近期开始治理这块,一些建议仅供参考:
ICE 团队目前维护着 5 个钉钉答疑群(每个 1000 人)以及技术论坛的官方帐号,但整体活跃度都比较一般,目前无论是精力上的投入还是运营产品的经验都比较缺失,希望能得到一些建议或者支持。
github 上有很多方便的机器人(or App?),这里推荐个人觉得比较有用的两个机器人:
其他有趣的机器人欢迎推荐。