为什么我反对使用 git flow
如果论知名度,git flow 绝对是现在数一数二的 git 协作模型。甚至直到不久之前,我也在用这个模型作为我在 github 上的几个项目的工作流。
但是一段时间后,我越来越觉得这个 work flow 不仅过于冗余、繁琐,而且在实际操作中充满了艰险。这种想法在我到新公司后,和多个同事(5-7人)一起协作开发一款 android 直播客户端时达到顶峰。
从核心点来看,git flow 的最大亮点是:
- 一个始终稳定且代表可发布产品时刻的 master 分支
- 各自独立的开发分支,例如各种 feature 分支
坑在何处
对于客户端项目来说,稳定可发布的 master 分支完全没有什么意义。因为客户端没有所谓的线上环境,产品发布有自己单独的发布渠道(例如应用市场,官方主页等),这部分版本更迭完全是天然隔离的。
而服务端项目,虽然确实需要一个稳定的,对应线上环境的分支,但是其他 work flow 也完全可以做到。例如一个简单的 master 分支和对应开发的 develop 分支。
其次,git flow 第二个所谓亮点会引发一个很严重的后果:后期合并代码时连锁的冲突问题。
git flow 最大的亮点导致的一个核心问题就是,大家在各自独立的分支上展开工作,工作完毕了才合并到 develop 分支,导致每个人距离共同分支(他人修改)太远。
这种对彼此的代码修改互相不可知的工作流程,在后期合并代码时简直是噩梦。通常来说,需要有一个专门的人负责合并代码,并且合并某个分支时,对应分支的开发人员要在场,否则对于大块大块陌生的代码,完全没法进行合并操作。
于是你就会发现,在这一期需求的收尾阶段,你浪费了大量的时间和精力在合并代码上,并且还伴随着潜在的合并出错的风险。
上一周不到三天的时间内,我已经做了两次修改远程仓库的历史,抹掉新来的同事提交的大块修改代码导致的问题,这只能用灾难来形容。
现在回过头来想想 git flow 这种独立多 feature 到底有效解决了什么问题?答案是有效解决了一个人为臆想的问题,即:某个要做的需求大大超前于产品的版本。
就现在的环境而言,出现这种需求,99%的情况下是产品需求不合理。所以正确的做法是,把产品按在地上暴打一顿。
化繁为简,返璞归真
个人建议的 git work flow 其实早在 SVN 时代就用的很普遍了:我们只需要一个用于开发的 master 分支。
对于客户端,只需要一个这样的 master 分支即可,每次到发版本,切出一个发布分支,并在 master 上打上 tag 即可。
而对于服务端,一个稳定的 master 分支,加上一个开发的 develop 分支即可。
这种模式下,每个人需要把修改 push 到远程分支时,都需要利用 fetch && rebase
同步他人修改,而就算此时发生冲突,冲突的范围也绝对是能在控制之中。
所以这里的核心就是:减少和公共分支的距离,尽量缩小冲突的大小。
Pop quiz: 多次解决小冲突比起一次性解决大冲突会有优势吗?
妈的简直废话,你没学过什么叫 divide/decrease-and-conquer 吗?
git flow 这种多分枝模型,给人的感觉就是,because I can,典型的不考虑实际生产环境。
多说一句,chromium 这种巨型项目,用的就是一个稳定的 master 分支这种工作流。难以想象如果他们用 git flow,最后冲突会出现什么样天崩地裂的景象啊。