简述Git Flow
首先,Git Flow并不是Git的替代品,Git Flow只是把标准的Git命令用脚本组合了起来,形成比较有效而简单的命令。
Git Flow只是给我们提供一个更简便的工作流程命令,而更重要的是我们需要去学习和理解关于版本控制系统的工作流程,才能有效的迭代产品,避免混乱。
而当项目处于一个多人协作的状态下,工作流程显得非常之重要。假设当两个甚至多个开发者同时再开发各自新功能时,如果在同一分支上进行协作时,这必然会产生大量的冲突。而工作流程的做法,就是每个开发者可以各自切出一个独立分支,当各自功能实现并且测试成功后,再自行合并到master分支中,甚至无需等待其他功能实现再一起发布。
分支应用情境
在Git Flow中,主要的分支有master、develop、hotfix、release、feature 这五种分支。master和develop分支是我们最常见的分支,它们被称作长期分支,一直存活在整个工作流程中,而其它的分支大部分会因任务结束而被删除。
master分支
该分支主要用来存放稳定、随时可以上线的版本。
这个分支的来源只能从别的分支合并过来,开发者不会直接commit到这个分支上。
通常我们也会在这个分支上的提交打上版本号标签。
develop分支
这个分支主要是所有开发的基础分支。
当要添加功能时,所有功能都是从这个分支切出去的,而功能分支实现后,也都会合并回来这个分支中。
hotfix分支
当线上产品发生了紧急问题的时候,就会从master分支中开一个hotfix分支出来进行修复。
当hotfix分支修复完成之后,就会合并到master分支中,并且也会合并到develop分支中。
release分支
当develop分支完成需求后,就可以从develop分支中开一个release分支,进行上线前最后的测试。
测试完成后,释放release分支将会同时合并到master以及develop分支中。
feature分支
当我们需要补充功能的时候,就会从develop分支中开一个feature分支进行功能开发。
当功能实现后,在将feature分支合并到develop分支中,等待最后的测试发布。
示意图
安装与使用
安装
Mac
brew install git-flow
如果没有安装brew的话可使用下列命令进行安装:
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
Win
初始化
先将项目克隆到本地。
git clone <project-url>
初始化Git Flow。
git flow init
命令行会提示你是否修改Git Flow提供的默认分支前缀。不同场景的分支前缀不同,默认情况下分支前缀是这样的。
| 场景 | 分支前缀 |
|---|---|
| 新功能 | feature |
| 预发布 | release |
| 热修复 | hotfix |
| 打标签 | 空 |
Which branch should be used for bringing forth production releases?
- develop
- master
Branch name for production releases: [master]
Which branch should be used for integration of the "next release"?
- develop
Branch name for "next release" development: [develop]
How to name your supporting branch prefixes?
Feature branches? [feature/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
分支前缀的作用是区分不同分支的使用场景,同时当你使用Git Flow命令时就不需要手动增加分支前缀,Git Flow会帮你加上。
通常情况下不需要修改默认的命名前缀,只需要加上-d就可以跳过修改命名步骤。
git flow init -d
feature场景
[图片上传失败...(image-e844a5-1609829360387)]
当我们需要开发一个新功能的时候,此时需要基于develop分支拉出feature分支进行开发,即feature场景的生命周期开始。
通常来说,一种场景的完整生命周期至少包含以下几种行为:
- start :开始开发
- publish :发布到远程分支
- finish :完成开发、合并分支
start
新功能开始开发前,需准备好开发分支。
git flow feature start <feature-name>
执行上面命令后,将会在本地创建一个名为<feature-name> 的分支,并切换到该分支。
而且无论你当前处于哪个分支,它都会基于本地develop分支创建的。
上述命令相当于执行了下面的Git操作。
git checkout -b feature/<feature-name> develop
需要注意的一点是,该分支是基础本地的
develop分支创建,所以执行此命令钱一般需要拉取最新的远程代码。
publish
在本地开发完成新功能并进行commit操作后,需要将本地代码提交到远程仓库。
git flow feature publish <feature-name>
该命令主要做了三件事情:
- 创建一个名为
feature/<feature-name>的远程分支 - 本地分支
track远程分支 - 如果本地存在还没提交的代码,就进行代码提交
git push origin feature/<feature-name>
git push --set-upstream origin feature/<feature-name>
git push origin
当你执行后publish操作后,后续还需要进行代码提交的话,只需执行正常的push命令既可。
git push
finish
当功能开发完毕后就将进入测试阶段,此时需要将该分支合并到develop分支。
git flow feature finish <feature-name>
该命令也主要做了三件事情:
- 切换到
develop分支 - 合并代码到
develop分支 - 删除本地
feature/<feature-name>分支
git checkout develop
git merge feature/<feature-name>
git branch -d feature/<feature-name>
Git Flow的merge操作与默认的git merge操作有些不同。
默认情况下它会检查本次merge有多少commit记录,如果仅有一条的话采用fast-forward模式,即只移动HEAD指针而不会生成提交记录;如果超过一条commit的话,这采用no-ff模式,该模式下则会多生成一条merge的commit记录。
这样做的好处是当有多条提交记录时方便进行代码回退和记录监察,而只有单条提交记录的时候则简化代码提交记录从而便于管理。
当finish操作过程中,如果merge发生了冲突,则会终端finish操作,不会删除feature/<feature-name>分支,同时也处于develop分支上。
当本地冲突解决并commit后,重新进行finish操作即可。
另外,finish指令还支持三个附加参数:
-
-r:即merge前先执行rebase,但即使rebase后符合fast-forward条件也不一定会用fast-forward。 -
-F:即合并完成连同远程分支一并删除。 -
-k:即保留本地feature分支,不执行delete动作。
release场景
[图片上传失败...(image-e5c7e0-1609829360387)]
当新功能开发完成后,将进入测试阶段,此时需要基于develop分支拉出release 分支进行集成测试,也有将release场景作为预发布环境进行测试。
在这种情况下,一般而言release只有少数改动。
start
使用start开启一个release场景。
git flow release start <release-name>
该命令会基于本地的develop分支创建一个release/<release-name>分支,并切换到这个分支。
需要注意一点是,如果本地还有未
finish的release分支的话,将不允许使用start指令开启新的release分支,这一点是对并行发布的一个限制。
publish
为了让其他协同人员能够看到该分支并一同测试,需要将其发布出去。
git flow release publish <release-name>
finish
待测试通过后需要发布正式版:
git flow release finish <release-name>
该命令的动作会比较多,大致是:
-
git fetch,拉取最新的代码 - 将分支合并到
master分支 - 生成名为
<release-name>的tag - 将分支合并到
develop分支 - 删除
release/<release-name>分支 - 切换回
develop分支
如果merge产生冲突不会终止流程,只是不会将本地的release分支删除。待解决完冲突后需再次执行finish操作。
finish只是完成了本地代码的一系列操作,可使用下列命令进行推送所有的分支和tag。
git push origin --all
git push origin --tag
hotfix场景
如果在线上发现了bug,需要进行紧急修复的时候,就需要用到了hotfix场景。
start
git flow hotfix start <hotfix-name>
该命令将从master分支创建了一个hotfix/<hotfix-name>的分支并切换到该分支。
finish
hotfix没有publish命令,因为Git Flow认为hotfix应该是小范围的改动,不需要其他协同人员参与。
但本地修改结束并进行commit操作后,则执行finish操作。
git flow hotfix finish <hotfix-name>
该命令所做任务与release基本相同,先拉取代码,然后将分支合并到master、develop分支中,并且打上tag,然后删除该分支,最后切回develop分支。
其他代码工作流
与Git Flow相似的代码管理工作流还有Github Flow和[Gitlab Flow][https://docs.gitlab.com/ee/topics/gitlab_flow.html]。
-
Github Flow是简化版的Git Flow,它使用了main和feature来管理代码,它只有一个长期分支,就是main。 -
Gitlab Flow更关注代码的持续集成,一个版本需要创建测试环境、预览环境、生成环境的分支,最后汇总到stable branch分支用于发布。