概述

在 Git flow 中,有两条贯彻始终的分支,分别是 masterdevelop,其中,master 是不允许自行合并代码的,而 develop 是平时开发的基础分支以及特性合并的分支。理解这两个概念对于使用 Git flow 有很大帮助。

开发流程

使用 Git 最为常见的场景就是开发了,在 Git flow 中,开发流程为在 develop 分支中切出一个 feature 分支,例如 feature/post-tag 表示开发博客的标签功能。然后你就在对应的 feature 分支上进行各种开发和提交,当你觉得完成了之后,那么你就将你的 feature 分支合并到 develop 分支中。

这就是 Git flow 的开发流程,看上去操作很繁琐,但实际上这些操作都有现成的工具可以完成,在这篇文章中,我主要还是介绍清楚一些概念,所以就忽略了实际操作,可以留个坑后面慢慢填。

发布流程

当你在某个阶段觉得自己的代码已经测试稳定了,准备发布出去给用户使用了,那么你就可以在 develop 分支上切出来一个 release 分支,例如名字 release/v1.2.3,然后可以往 release 分支上添加一些发布说明之类的,然后就将 release 分支合并到 master 分支之中,合并之后,就在 master 分支上给刚刚合并的这个 commit 打 tag,tag 的名字就是 release 分支的名字:v1.2.3

同时,也要将 release 分支合并回 develop 分支之中,这样才能保证 master 分支和 develop 分支代码的一致性。最后,就删除掉 release/v1.2.3 分支,整个发布流程就这样啦!

补丁流程

当你的产品发布出去一段时间之后,多多少少都会遇到线上的 Bug,那么,这个时候的操作就是从 master 分支中切换出 hotfix 分支,例如:hotfix/too-many-water,然后在这个 hotfix 分支上修复问题,当修复完成之后,那么你再将 hotfix 分支分别合并回 masterdevelop 分支。

hotfix 合并回 master 之后,还需要在 master 分支之上打上一个 tag:too-many-water,表示这是一个 hotfix 的合并。

问题

从上面的描述看上去很整洁美好,但是实际操作下来还是有不少问题的,我这里就列举一些我遇到过的问题进行一个探讨吧。

master 和 develop 分支

从上面看,似乎 master 分支和 develop 分支略显冗余,保留一个就可以了。

我的看法是不然,在 Git flow 中:

这也就是说,任何一个时候,你都可以从 master 中运行一个稳定的系统,就如同 Linux 的 stable version,如果你将 developmaster 合并掉,那么你还需要主动切换到某个 Tag 上才能达到类似的效果。

这在很多场景下都是很有价值的,例如一些动态伸缩的系统,你可以在创建容器/虚拟机的时候直接从 master 上拉代码部署运行;而 develop 分支则是你 CI/CD 工作的分支。

toB 产品 hotfix 不好处理

如果你是一个 toC 的互联网产品,那么 Git flow 可能比较适合你,但是,如果你做的是 toB 的产品,尤其是你的产品可以让用户自行决定部署的情况,那么 Git flow 的问题就凸出了。

如果你发布了 v1.1.0 和 v1.2.0 两个版本的产品,其中 v1.2.0 是最新的 release,按照 Git Flow 的工作流,你的 hotfix 只能在 v1.2.0 的基础上进行。那么问题就来了,作为一个 2B 的产品,很可能用户在他们的机器上运行的是 v1.1.0 版本的产品,你不大可能强迫用户直接升级到 v1.2.0,你见过强迫用户将 CentOS 7 升级到 CentOS 8 的产品么(有这么刚的公司还请告诉我一下)?那么如果是 v1.1.0 版本出现了 bug 需要 hotfix 怎么办?

就依照目前的 Git flow 是没办法直接在 v1.1.0 版本上直接打 hotfix 的,当然,社区一直有关于此的讨论,例如来个 support 分支之类的,但是,我前面介绍的那款工具是没有支持的,而具体的操作规范,也没有制定出来。如果你有兴趣,不妨看一下以下这些讨论:

release 分支合并困难

从前面看上去 release 分支合并到 master 应该是一个很简单的事情,但是实际上操作下来会发现有不少问题。例如你在 develop 分支上开发了一些特性了,这个时候 develop 分支和 master 分支代码肯定是不同步的,那么,如果这个时候来了一个 hotfix,按照 Git flow 规范是需要同时合并到 mastserdevelop 分支的,那么这个时候就会造成 develop 分支和 master 分支的代码不同步。

masterdevelop 代码不同步会有什么问题?首先,你必须知道 Git 是基于文件变更来进行版本控制的,如果你的基础代码不一致,那么合并代码的时候,很可能就会无法自然合并成功,就需要人工地解决冲突。其实,这也是很多人吐槽要区分 masterdevelop 两个分支的原因之一。

解决办法?我没有去探究其他人的解决办法,但是,我认为一个可行的办法就是 hotfix 先不着急合并进 masterdevelop,而是合并进下一个 release 分支,这样,可以较低程度减少冲突的发生,但是如果客户急需一个 fix patch 的话,这就又变得不好搞了。

小结

OK,这就是我对于 Git flow 的一些理解了,关于 Git flow 或者 Git 工作流,如果你有一些不错的实践或者建议,不妨一起留言交流一番。