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. 然后删除发布分支。

操作举例

创建一个工程

  1. 集成负责人在 github 上创建中央版本库,添加 README 文件以及其他必要的初始化代码
  1. 各个开发者分别把中央版本库 fork 到自己的账号下,作为卫星版本库,clone 自己的工程到本地,开始开发

给一个工程添加功能

  1. 集成负责人在中央版本库的 issues 中创建一个 issue,记录这个功能的开发目的,以及描述其场景和交互过程。
  1. 集成负责人和其他开发者讨论开发思路,开发者把自己的开发思路回复在 issue 中。集成负责人反复确认开发者思路(视功能复杂度和前期调研准备充分程度而定,这个确认过程可能会很长)。
    直到经过充分沟通,大家都认同这个思路后,尽快指定具体进行此编码任务的开发者,进行代码编写。
  1. 开发者保证在自己 fork 出来的卫星版本库下操作。而且开始开发新功能之前,必须先获取中央版本库 master 上的代码。
    如果此时有开发到一半的其他内容,也应该以新分支来获取中央版本库 master 上的代码。 如果不同功能之前(这些功能可能是不同人负责的)存在逻辑依赖关系,就只能等待集成负责人的协调了。
  1. 开发者可以在卫星版本库的 master 分支下工作。
    因为目前的修改都不会影响到核心版本库,所以分支管理比较自由。
    但是很可能会出现一个开发者接到开发若干不同功能的任务。
    所以建议一个功能对应一个分支,便于管理 pull request。
  1. 修改过程中,尽早向中央版本库提交 pull request.
    注意:github 规定分支上至少要有一个新的 commit 才能创建 pull request.
    注意:github 规定一个分支对应的 pull request 再被合并之前,不能创建新的 pull request. 而且,在被合并之前,所有新的提交都会陆续包含在 pull request 里。 在此过程中的围绕此功能的各种沟通都要记录在 pull request 上,以及对应 issue 上。
  1. 当功能添加完毕后。告知集成负责人可以合并代码了。
  1. 集成负责人在中央版本库基于当时的 master 新建一个分支用于进行合并操作,以及进行相关的测试(自动化测试,预发布环境的人工测试),以及若有必要,进行代码评审会。
    集成负责人合并 pull request 的过程中,功能开发者仍然可以继续修改他自己的分支代码并进行 commit. 直到 github 上显示该 pull request 合并完,才认为合并完毕。 在一个 pull request 合并完成之前,不要去合并另一个 pull request. 所以要求每个人开发的内容都要独立解耦。
  1. 如果在这个检查过程中,发现开发内容存在 BUG 和不符合要求的地方。那么就不往 master 分支合并,而是修改完这些问题之后再合并。
    所有的问题仍然是记录在 pull request 以及对应 issue 上。
    排查修改问题的过程中,依然是不断提交 pull request.
    当不能再发现问题,或者没有立即要修改的问题,检查无误后,合并代码到 master 分支。
  1. 关闭对应 issue.

版本发布

  1. 集成负责人认为集成到一定程度时,可以发布新版本。
    在中央版本库的 issues 创建对应 issue,记录这次发布所包含的内容,以及相对于上次发布的变更。
    所有发布过程中的问题也记录在 issue 里。
  1. 集成负责人在中央版本库建立新分支,命名为 pre-release-xxx.
  1. 在此分支上进行各种检查和测试。包括代码评审,自动测试,以及预发布环境的人工测试。
    这个过程中的所有问题和解决过程都记录在对应 issue 里。
  1. 这个过程中,其他开发人员仍然可以向中央版本库发 pull request.
    集成负责人来判断何时合并这些 pull request.
  1. 各种检查和测试通过后,将 pre-release-xxx 分支代码合并回 master 分支,并立即将 master 分支部署到产品环境。 在 master 分支上打 tag,标明版本号。
  1. 关闭对应 issue.

修改线上版本 BUG

  1. 集成负责人确认 BUG 来源,确认 BUG 确实存在。在中央版本库创建 issue.
    记录 BUG 来源以及 BUG 对应的代码版本。
    确认 BUG 复现的精确条件,记录在 issue 里。
  1. 在合适的时机(例如某 BUG 要立即修改,或者某版本的 BUG 积累到一定数量)时,
    集成负责人在中央版本库从合适的位置出发(可能是旧版本,也可能是当前的 master,根据实际情况判断)建立新分支,命名为 bugfix_xxx 。
    注意:确实会出现某个线上 BUG 在一个比较旧的版本里修改一次,又在后续新版本里修改的情况。这是不可避免的。 所以,BUG 的修改应尽量保证有自动化测试覆盖,以及同时有人工检查。
  1. 指定的修改 BUG 的开发者,在卫星版本库获取 bugfix_xxx 分支代码,在此基础上进行修改。
  1. 依然通过 pull request 形式来合并,参考给一个工程添加功能
  1. BUG 修改完毕后,合并代码回中央版本库 master 分支。留待下一次发布。
  1. 根据最初记录的 BUG 来源,由运营人员进行反馈,告知此 BUG 何时修复/已修复。
  1. 直到包含该 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/