基于 Gerrit 的 Git 工作流

v1.0 2016-09-03

李飞于 2016年9月3日

1. Git 分支模型及工作流

1.1. git flow

Vincent Driessen 在 2010年1月《A successful Git branching model》 [1] 提出了著名的 Git 分支模型,并为其提供了 Git 扩展工具 git flow [2]

git model@2x.png
Figure 1. git flow 示意图

git flow 分支模型及开发工作流成为了多数人认可的开发工作流,在日常研发中用的非常多。

1.2. GitHub Flow

最大的开源社区 GitHub 基于其产品提出了 GitHub Flow 分支模型及工作流 [3], 这个模型非常简单,和最基本的 Git 分支差别不大,随着 GitHub 在开源界的流行,GitHub Flow 也受到了大家的认可。

20160815131532796
Figure 2. GitHub Flow 示意图

1.3. GitLab Flow

GitHub 的开源实现 GitLab 在 git flow 及 GitHub Flow 的基础上,提出了 GitLab Flow 分支模型及工作流 [4]。 并依托 GitLab 软件,打造了开发、测试、部署、项目管理等一系列解决方案。

gitlab flow.png
Figure 3. GitLab Flow

1.4. Gerrit Workflow

Gerrit 一款功能强大的 Code Review 工具 [5],与 GitHub/GitLab 相比,算是 Git 的另外的一个流派,有许多独特的特性。许多开源软件采用 Gerrit 作为其 Code Review 工具,如:Android、Eclipse、OpenStack、Qt 等。

Note
Gerrit 采用 Change 作为 Review 单元,使用 Change-Id 将一次 Review 过程中的所有的变更和调整都记录下来,而提交到主干的代码却是经过 Review 和测试过的高质量代码,深受有代码洁癖项目的喜爱。
Note
Gerrit 的权限控制非常强大,可以控制代码仓库的方方面面。
code review.png
Figure 4. Gerrit Workflow
Note
作为有追求的团队,采用 Gerrit 作为 Code Review 工具是最好的选择。围绕 Gerrit 打造合适的研发工作流。

2. 分支模型

Gerrit 中采用了虚拟分支来实现一些特性,如:push 到 refs/for/* 分支视为提交一次 Patchset,refs/changes/10/1010/1 用于下载已经提交的 Patchset 代码。一般情况下,如果只围绕这 master 分支开发的话,可以不需要任何其他分支。

非分支开发
  1. 使用远端的 master 分支代码覆盖本地代码:git fetch origin master && git checkout FETCH_HEAD

  2. 在此基础上进行开发,开发完成后提交 Patchset:git push origin HEAD:refs/for/master

  3. Review 未通过,被打回重新修改:git fetch origin refs/changes/<change-id> && git checkout FETCH_HEAD

  4. 修改完成后,再次提交 Patchset:git add -u && git commit --amend --no-edit && git push origin HEAD:refs/for/master

  5. Review 通过,合并到 master 分支;

  6. 开发下一个特性,重复上述步骤;

但是,如果碰到很多的大型的特性,一个 Change 无法完成,那就不得不启用分支开发了,所以分支模型对于 Gerrit Workflow 来讲也是需要的。

2.1. 主要的分支

Gerrit 开发工作流中主要遇到的分支:

Gerrit 的分支梳理
  1. sandbox/<username>/* 表示个人分支;

  2. feature/* 表示功能分支,开发新特性时,工程师们会将代码提交到 feature 分支中;

  3. hotfix/* 表示修复分支,非必须;

  4. master 分支表示主干分支,功能开发完后,将代码合并到主干分支;

  5. test 分支是测试分支,用于预上线、小流量发布;

  6. production 分支表示生产分支,为部署到生产环境的代码;

Note
sandbox 系列分支
sandbox/<username>/* 是供个人开发测试用的分支,较为开放。

3. Gerrit Workflow

一种理想的可能的工作流方案

  1. Developer A(后端)在自己分支 sandbox/A/X(基于远端的 feature/X 分支)下开发特性 X 的功能;

  2. Developer B(前端)在自己分支 sandbox/B/X 下开发特性 X 的功能;

  3. Developer A/B 将代码提交到 refs/for/feature/X 中,供组内其他成员进行代码评审(此时,可删除自己的分支);

  4. 评审完成后,由 Gerrit submit 代码到 feature/X 分支,特性分支不允许 merge 节点存在,必须采用 rebase 的方式合并;

  5. 重复上述 4 步直至功能开发完成;

  6. 长期的特性分支可能会存在合并主干分支的情况,这个后续讨论;

  7. feature/X 分支合并到 master 分支中,采用 --no-ff 进行合并,不使用 rebase。

  8. 回滚时,找到 merge 节点,对其进行 revert 操作,提交回滚。

Note
简化的工作流方案

大部分情况下,一名研发同事可以完成一个特性的开发,而且仅需要一次提交; 这种情况下,可以采用「简化的工作流方案」;

  1. 上述第三步调整为将代码提交到 refs/for/master

  2. 代码评审完毕后直接合并到主干分支,采用 rebase 的方式;

results matching ""

    No results matching ""