git工作流没有银弹

目前,git主流的工作流有3种:

  • git flow 模型
  • github 模型
  • gitlab 模型

阮一峰的这篇 Git 工作流程 针对这几种都有简单的介绍,网上的资料也很多,这里不做赘述了。该文主要是想说说我们团队在使用这些工作流的一些经验和思考。

有一个观点我非常赞同:

用什么模型,只和团队能力中的工程技术能力和团队协作(纪律)能力有关,和团队规模大小都没有关系。能力强,就使用简单模型。能力弱,就使用复杂模型。

我认为,这里所指的能力不仅仅是开发的能力,包括产品经理、供应商、设计等等围绕该产品的所有有关人员。这些能力的下限等于使用什么git模型时候的能力。

git flow

先挑个硬柿子,来聊聊git flow,它是这3中模型中最复杂、最难上手的模型。设计这套模型的哥们,我相信他很可能是被混乱的发布流程折腾的够呛,所以想出了一套大而全,而又滴水不漏的模型。我们早期很多项目都是基于git flow的魔改的工作流。

为什么要魔改?

因为开发、测试往往走在版本发布前面很多,我们开发完了 feature/afeature/b,而又都合并到了develop测试 ,但是在发布的时候,我们又只想发布feature/a,但我们知道 git flow 发布模型是从develop检出release,是处理不了这种情况的。所以我们在从 develop 基础上又检出了一个叫做 test的分支,测试环境用的是test的代码,所有需要测试的 feature 合并到 test即可,然后发布的时候再选择需要发布的 feature 合并到develop

加了test分支,看起来似乎解决了发布部分功能的问题,但又遇到了新的问题,假如合并到test的时候,遇到了冲突,你拉上同事到你座位上面基了半天,终于解决了冲突。过了几天,你想发布新版本,然后发现合到develop的时候,仍然需要再解决一次冲突,而你同事正好出差了,这非常令人沮丧。

而且,本身git flow的分支已经够多了,又加一个新的分支,实在是太复杂了。

不用test分支,还有一种方案可以解决上述的问题,就是给每个feature建立一套测试环境,保证每个feature都是经过测试过的,然后发布的时候按照git flow流程就好。这也是我之前在一次分享上听到的,但依然不是银弹,主要有2点原因:

  1. 部署流程需要自己开发,有开发成本,比如web应用,可能需要开发一个host管理扩展(没有那么多域名,只能模拟)
  2. 如果 feature/a 依赖 feature/b,比如购买商品模块依赖注册登录模块,测试覆盖不到所有情况,那创建分支的时候就不能按照功能创建了,只能按照某一个小的闭环去创建。

上面只是我们在使用git flow过程中遇到的问题,它其实还有很多通用的问题,如bugfix可能忘合回develophotfix概念太复杂等等,其他文章都有讲到,就不重复了。

github flow

先欣赏一下真正的大神的git提交记录:

vue

git log非常的干净整洁,版本迭代也很清晰。github flow是这三种中最简单的模型,也是对开发人员要求最高的模型。它很适合第三方库、框架、组件的开发,但不适合业务开发。

github flow是持续发布的,举个例子,假设我发布了1.1.0版本,突然我又有个想法,给代码加了个补丁,发布了1.1.1。此时,使用我仓库的用户可以选择性的升级成1.1.1,只要他愿意承担新版本的风险。比如在代码里添加圣诞帽什么的。

但如果这个仓库是业务代码,我们就不能对用户说,你能选择新的版本,但可能不稳定哦。用户才不管这些呢,他只会选择新的产品。

gitlab flow

gitlab flow 是上面两种工作流的折中方案,简单来说就是下面这张图:

gitlab

gitlab官方有对该工作流的介绍,Introduction to GitLab Flow。

可惜的是,文章中没有详细介绍从开发到发布的完整闭环,和一些常常会遇到的问题,可能他们不希望把工作流当作强制约束,又或者每个团队情况不同没办法定制一套完美的方案吧。

我通过一些文章的启发,和自己的实践,总结了一套还算不错的实践方案。

首先,从master检出分支开发,完成后通过merge request,让他人来 code review,通过后rebase进master。什么?这个项目只有你一个人?那你就自己review吧,在阅读自己代码过程中,应该也是能保持愉悦的吧。

然后,通过 git cherry-pick 命令把需要测试的代码合到 pre-production,保证pre-production都是测试过的,需要发布的时候再从pre-production通过 cherry-pickproduction

整个过程,看起来简单,实际操作的时候,如果我们能深入的理解 cherry-pickrebase的话,好像确实挺简单的。cherry-pick过程中,如果忘记哪些没pick的话,可以用这个命令 git cherry branch,how-to-see-which-commits-in-one-branch-arent-in-the-other。整个操作用命令行就完全可以搞定,无需借助什么gui工具。

但是,如果代码提交log混乱,git cherry-pick的时候就会非常痛苦,完全不知道这个 commit 是在干什么,所以我们需要借助 commitizen,帮我们约束每次的提交,这样也能够更方便每次的 code review。

我们现在后端项目使用的就是gitlab flow,前端还是git flow。为什么呢?因为经常前端测试环境改个样式、改个文案,每次commit实在不知道写什么,还不如先随便写点,最后merge的时候rebase合并提交记录比较方便。
而且gitlab flow也最好是让一个固定的人去负责cherry-pick比较好,现在项目服务端前后端,管理端前后端,一共4个仓库,1个人很难全部顾及到。

最后,对比下gitlab flow改造后的log记录和之前项目的log记录:

old:

old

new:

new

其他git常见问题

1. 如果避免乱七八糟的分支名?

在gitlab中的 设置-基础设置-分支设置,可以在为 允许的分支名称 配置正则,我们之前git flow使用的正则是:(^(feature|bugfix|hotfix|release)\/{1}[a-z0-9-]+|(release|test))$

var s1 = 'feature/a' // true
var s2 = 'feature1' // false
var s3 = 'test' // true
var s4 = 'release/a/f' // false
var s5 = 'bugfix/a' // true
var s6 = 'bugfix' // false

2. 如何合并多次无意义的提交?

用git rebase,彻底搞懂 Git-Rebase。
像很多部署工具,往往需要指定一个分支进行发布,测试环境由于功能不稳定,或者bug太多,经常会产生很多无意义的提交,如上图的各种debugdebugdebug,在merge前,一定要合并提交。

3. merge的时候为什么一定要加--no-ff

一图胜千言:

noff

4. git gui工具推荐?

GitKraken

你可能感兴趣的:(git工作流没有银弹)