github flow - mindpin/docs GitHub Wiki
github flow - 多人协作的代码合并管理策略
本策略参考池田尚史,藤仓和明,井上史彰所著《高效团队开发工具与方法》一书中的建议。以下简称《高》。
之前我们在 eshare 中尝试了 git-flow 工作策略,然而实践中发现,git-flow 操作较为繁琐。
它更适合发布间隔较长的项目,而不适合快速迭代和演化的项目。对人的要求也较高。
这一点上我们的认知和《高》一书的作者是一致的。
git-flow 的一些参考:
github-flow 是 github 团队建议的一种策略
关于单版本库策略还是多版本库策略
github 团队自己用的应该是单版本库策略,也就是所有人都不轻易去动 master 分支,要做任何修改就开新分支,然后在同一版本库的不同分支之间发 pull request 到 master 分支。
而《高》一书里日本人的建议是设置一个中央版本库,其他人要修改时 fork 这个版本库然后修改,在不同的版本库之间发 pull request 到中央版本库的 master 分支。
经过讨论后我们倾向于采用多版本库策略,这样比较容易控制权限。使得中央版本库的 master 分支不会轻易被改动。
操作步骤概述
- 必须使用 github
- 有一个中央版本库,每个参与开发的成员在各自的账号下 fork 自己的版本库。在自己的版本库里做开发。
- 所有发布和部署操作都在中央版本库的 master 分支进行。
- 各个开发人员在自己的版本库里怎么操作不做限制。
- 开发过程中或开发结束后,向中央版本库发 pull request.
- 代码评审后合并这些修改到中央版本库的 master 分支。
- 在中央版本库的 master 分支进行持续集成。
- 要发布时,在中央版本库另创建发布分支,进行预部署,人工测试等工作。
- 在这个过程中,其他开发人员依然可以向中央 master 发 pull request.
- 发布结束后,把发布分支合并回 master. 打 TAG. 然后删除发布分支。
操作举例
创建一个工程
- 集成负责人在 github 上创建中央版本库,添加 README 文件以及其他必要的初始化代码
- 各个开发者分别把中央版本库 fork 到自己的账号下,作为卫星版本库,clone 自己的工程到本地,开始开发
给一个工程添加功能
- 集成负责人在中央版本库的 issues 中创建一个 issue,记录这个功能的开发目的,以及描述其场景和交互过程。
- 集成负责人和其他开发者讨论开发思路,开发者把自己的开发思路回复在 issue 中。集成负责人反复确认开发者思路(视功能复杂度和前期调研准备充分程度而定,这个确认过程可能会很长)。
直到经过充分沟通,大家都认同这个思路后,尽快指定具体进行此编码任务的开发者,进行代码编写。
- 开发者保证在自己 fork 出来的卫星版本库下操作。而且开始开发新功能之前,必须先获取中央版本库 master 上的代码。
如果此时有开发到一半的其他内容,也应该以新分支来获取中央版本库 master 上的代码。 如果不同功能之前(这些功能可能是不同人负责的)存在逻辑依赖关系,就只能等待集成负责人的协调了。
- 开发者可以在卫星版本库的 master 分支下工作。
因为目前的修改都不会影响到核心版本库,所以分支管理比较自由。
但是很可能会出现一个开发者接到开发若干不同功能的任务。
所以建议一个功能对应一个分支,便于管理 pull request。
- 修改过程中,尽早向中央版本库提交 pull request.
注意:github 规定分支上至少要有一个新的 commit 才能创建 pull request.
注意:github 规定一个分支对应的 pull request 再被合并之前,不能创建新的 pull request. 而且,在被合并之前,所有新的提交都会陆续包含在 pull request 里。 在此过程中的围绕此功能的各种沟通都要记录在 pull request 上,以及对应 issue 上。
- 当功能添加完毕后。告知集成负责人可以合并代码了。
- 集成负责人在中央版本库基于当时的 master 新建一个分支用于进行合并操作,以及进行相关的测试(自动化测试,预发布环境的人工测试),以及若有必要,进行代码评审会。
集成负责人合并 pull request 的过程中,功能开发者仍然可以继续修改他自己的分支代码并进行 commit. 直到 github 上显示该 pull request 合并完,才认为合并完毕。 在一个 pull request 合并完成之前,不要去合并另一个 pull request. 所以要求每个人开发的内容都要独立解耦。
- 如果在这个检查过程中,发现开发内容存在 BUG 和不符合要求的地方。那么就不往 master 分支合并,而是修改完这些问题之后再合并。
所有的问题仍然是记录在 pull request 以及对应 issue 上。
排查修改问题的过程中,依然是不断提交 pull request.
当不能再发现问题,或者没有立即要修改的问题,检查无误后,合并代码到 master 分支。
- 关闭对应 issue.
版本发布
- 集成负责人认为集成到一定程度时,可以发布新版本。
在中央版本库的 issues 创建对应 issue,记录这次发布所包含的内容,以及相对于上次发布的变更。
所有发布过程中的问题也记录在 issue 里。
- 集成负责人在中央版本库建立新分支,命名为 pre-release-xxx.
- 在此分支上进行各种检查和测试。包括代码评审,自动测试,以及预发布环境的人工测试。
这个过程中的所有问题和解决过程都记录在对应 issue 里。
- 这个过程中,其他开发人员仍然可以向中央版本库发 pull request.
集成负责人来判断何时合并这些 pull request.
- 各种检查和测试通过后,将 pre-release-xxx 分支代码合并回 master 分支,并立即将 master 分支部署到产品环境。 在 master 分支上打 tag,标明版本号。
- 关闭对应 issue.
修改线上版本 BUG
- 集成负责人确认 BUG 来源,确认 BUG 确实存在。在中央版本库创建 issue.
记录 BUG 来源以及 BUG 对应的代码版本。
确认 BUG 复现的精确条件,记录在 issue 里。
- 在合适的时机(例如某 BUG 要立即修改,或者某版本的 BUG 积累到一定数量)时,
集成负责人在中央版本库从合适的位置出发(可能是旧版本,也可能是当前的 master,根据实际情况判断)建立新分支,命名为 bugfix_xxx 。
注意:确实会出现某个线上 BUG 在一个比较旧的版本里修改一次,又在后续新版本里修改的情况。这是不可避免的。 所以,BUG 的修改应尽量保证有自动化测试覆盖,以及同时有人工检查。
- 指定的修改 BUG 的开发者,在卫星版本库获取 bugfix_xxx 分支代码,在此基础上进行修改。
- 依然通过 pull request 形式来合并,参考给一个工程添加功能。
- BUG 修改完毕后,合并代码回中央版本库 master 分支。留待下一次发布。
- 根据最初记录的 BUG 来源,由运营人员进行反馈,告知此 BUG 何时修复/已修复。
- 直到包含该 bugfix 的代码正式上线,在线上版本确认已修复后,才关闭这个 issue.
几种情况下需要建立的分支以及命名
- 开发新功能时,卫星版本库应该为每一个新功能建立对应的分支,名字不限(可以以功能命名)
- 合并 pull request 时,中央版本库应该建立一个合并用的分支,分支名为 merge-开发者账号名-对应卫星版本库分支名
- 要进行发布时,中央版本库应该建立一个发布用的分支,分支名为 pre-release-xxx
- 要修改线上 BUG 时,中央版本库应该建立一个用户合并这个/这些 BUG 的分支,分支名为 bugfix-xxx. 卫星版本库改 BUG 之前应从此分支获得代码。
FAQ
- Q:如果一个线上 BUG 同时影响到用户使用和后续开发,应该如何确定在新旧版本中的修改顺序。
A:先尽快做到不影响用户使用(也就是说尽快修改线上版本),然后,再来解决影响后续开发的问题。
其他参考
how github uses github to build github
http://zachholman.com/talk/how-github-uses-github-to-build-github/