一种实用的 Git 工作流

2019-07-09 ⏳2.2分钟(0.9千字)

昨天回答了一个关于 Git 分支合并的问题。突然发现我们部门现行的 Git 工作流还是非常简单实用的。现整理出来分享给大家。

网上有一篇很有名的文章叫 A successful Git branching model。相信好多朋友都读过。此文介绍的 Git 分支模型可以说是很经典的,但是太复杂了。我们对其进行了简化。

我们的工作流如下图所示:

        v1.0.0                  v1.0.1                   v1.1.0
           |                       |                        |
master  ---o--o----o-----o---------o------o-------o------o--o---
               \          \       /        \            /
                \  hotfix1 o--o--o          \          /
                 \                           \        /
       release1   o-------------o--o----------o---o--o
                   \           /    \            /
                    o---o-----o      o-o---o----o
                     feature1           feature2 

只有一个 master 分支是一直存在的。

对于线上问题,从 master 上切出 hotfix 分支,开发测试完成后合 master,打一个 tag 发布上线;对于一些一个人就能完成的小功能,也可以从 master 分支切一个 featre 分支,完成后合 master。这两种情况仅适用于无需多人协作的情形。

对于一个大版本迭代,则需要从 master 分支切出 release 分支。开发不同功能的时候需要再从 release 分支切出 feature 分支,开发完成后 feature 合入 release 分支。大版本迭代时间比较长,如果线上出现影响线下开发和测试的 bug,则需要将 master 分支合并到 release 分支。最终在 release 分支进行测试。测试通过后将 release 分支合入 master 分支,打 tag 上线。

所有的 hotfix 分支、release 分支、feature 分支都是临时分支,合并之后即可删除。我们在实际工作中给 GitLab 设了一个 WebHook,只要创建 Merge Request,就自动勾上合并后删除原分支选项。

最后说说 rebase 的问题。其实我们 master 分支的提交记录是这个样子的:

        v1.0.0                  v1.0.1                   v1.1.0
           |                       |                        |
master  ---o--o----o-----o---------o------o-------o------o--o---

所有的往 master 分支的合并都是 fast forward 的,看上去非常整洁。

最早我们也用过 non-ff 方式合并,会产生如下效果:

        v1.0.0                  v1.0.1                   v1.1.0
           |                       |                        |
master  ---o--o----o-----o---------o------o-------o------o--o---
                          \       / \
                           o--o--o   \
                                      a

Git 会自动生成一个新提交(图中 a 点所指),提交的内容大概是:

Merge: f68f6231 5658d884
Author: 涛叔 <hi@taoshu.in>
Date:   Thu Mar 14 18:48:46 2019 +0800

    Merge branch 'fix_new' into 'master'

    fix

    See merge request comic/sniper!001

自动生成的提交会记录源分支和对应的 Merge Request。在日常开发中,大家的分支名取得都很随意,甚至有人自始至终中用一个分支名。我没法要求大家都取有意义的分支名,索性采用 fast forward 方式合并,不再记录源分支名。这样做的缺点是丢掉了 Merge Request 信息。

我们开启了 GitLab 的提交合并功能。feature 分支在合入到 release 分支的时候 GitLab 会自动合并所有提交记录,根据 Merge Request 信息生成一个新的提交。所以,release 分支长得是这个样的:

release ---o--o----o-----o---------o------o-------o------o--o---

在 release 分支上,一个功能只有一次提交。为什么要这样做呢?因为大家的提交记录大多乱七八糟,无法直视,所以就开启提交合并功能,我就可以通过编辑 Merge Request 修改提交记录。

最后,release 分支合 master 分支前需要做一次 rebase 操作,然后再做一次 fast forward 合并。

我们这种工作流非常简单实用。版本管理人员可以方便地控制 master 分支的提交历史,能够有效避免提交记录脏乱差的问题。但缺点也很明显,无法追踪开发者本地的提交记录