Git Flow超详细版
为什么要用git flow?
- 在实际生产开发的过程中,如果每个人都随意的创建分支,随意的提交commit,必将导致整个git仓库非常的混乱,不易于团队协作
git flow的提出
- Vincent Driessen 同学为了解决这个问题提出了A Successful Git Branching Model,最后形成了业内普遍采用的git 工作流程,大家都在约定的流程内使用git,使得团队协作效率大大提高
Git Flow 的常用分支
生产分支(master)
Master分支是仓库的主分支
- 这个分支包含最近发布到生产环境的代码,最近发布的Release
- 这个分支只能从其他分支合并,不能在这个分支直接修改
补丁分支(hotfix)
当我们在生产环境发现新的Bug时候
- 我们需要基于master分支创建一个Hotfix分支
- 然后在Hotfix分支上修复bug
- 完成Hotfix后,我们要把hotfix分支合并回Master和Develop分支
发布分支(release)
当你需要发布一个新功能的时候
- 要基于Develop分支创建一个Release分支
- 在Release分支测试并修复bug
- 完成release后,把release合并到master和develop分支
开发分支(develop)
这个分支是我们的主开发分支
- 包含所有要发布到下一个Release的代码
- 这个主要合并与其他分支,比如Feature分支
功能分支(feature)
feature分支主要是用来开发一个新的功能
- 一旦开发完成,我们合并回Develop分支进入下一个Release
Git Flow的使用
初始化
当我们新建git仓库之后
- 默认会创建一个主分支也就是master分支,由于master分支是用于发布生产环境,所有必须保证master上代码的稳定性,所以我们不能直接在master分支上修改提交。
- 我们要基于master分支创建一个develop分支,develop分支用于保存开发好的相对稳定的功能
- master分支和develop分支是仓库的常驻分支,一直会保留在仓库中
新开发任务
当新的开发任务来了之后,就要编写代码了
- 我们尽量不要在develop分支上写代码,要保证develop分支的相对稳定,所以这时我要就要基于develop 分支创建一个临时的开发分支,然后在开发分支上编写代码,等功能开发完之后我们再把开发分支合并到develop上
新功能发布
新功能合并到develop分支之后,我们想把新功能发布到生产环境
- 首先基于develop分支创建release分支
- 然后在release分支测试完成之后
- 把release分别合并到master分支和develop分支
- release分支合并到master分支之后,在master分支上打标签用于发布
BUG修复
我们把代码发布到了生产环境,用户在使用的时候给我们反馈了一个bug
- 这时我们需要基于master分支创建一个hotfix 分支,用于修复bug
- bug修好之后,把hotfix 分支分别合并到master分支和develop分支
Git Flow 应用
初始化
管理员
第一步为master分支配套一个develop分支
- 简单来做可以本地创建一个空的develop分支,push到服务器上
1 | git checkout –b develop |
代码说明
- git push -u origin develop:加了参数-u后,以后即可直接用git push 代替git push origin develop
其他开发者
以后这个分支将会包含了项目的全部历史,而master分支将只包含了部分历史。
- 其它开发者这时应该克隆中央仓库,建好develop分支的跟踪分支
- 因为克隆仓库后只有一个master分支,所以需要自己建develop分支的跟踪分支
1 | git clone <项目链接> |
开发
现在每个开发都有了这些历史分支的本地拷贝。
- 从develop分支拉一个特性分支进行开发
1 | git checkout -b some-feature develop |
用老套路添加提交到各自功能分支上:编辑、暂存(commit)、提交(push)
1 | git status |
开发完一个功能
添加了提交后,如果团队使用Pull Requests,这时候可以发起一个用于合并到develop分支。
否则就直接合并到本地的develop分支后push到中央仓库(如下)
1 | 切换到dev分支 |
git merge 三种合并状态
- fast-forward
- 直接合并
- squash:把多次分支commit历史压缩为一次
- 在分支开发很多commit而合并后不想要那些混乱的时使用
- 禁用 fast-forward:保留分支的commit历史
准备发布
用一个新的分支来做发布准备。
- 确定发布的版本号
- 在这个分支完成清理发布、执行所有测试、更新文档和其它为下个发布做准备
- 只要创建这个分支并push到中央仓库,这个发布就是功能冻结的。任何不在develop分支中的新功能都推到下个发布循环中。
1 | git checkout -b release-1.0.0 develop |
准备好了对外发布,合并修改到master分支和develop分支上,删除发布分支
1 | git checkout master |
打标签
发布分支是作为功能开发(develop分支)和对外发布(master分支)间的缓冲。
- 只要有合并到master分支,就应该打好Tag以方便跟踪。
1 | git tag -a 1.0.0 -m "Initial public release" master |
发现bug
对外发布后,发现了当前版本的一个Bug,从master分支上拉出了一个Hotfix分支,提交修改以解决问题,然后直接合并回master分支
1 | git checkout -b issue-#001 master |
就像发布分支,维护分支中新加这些重要修改需要包含到develop分支中,然后才删除这个Hotfix分支
1 | git checkout develop |
Git flow工具
如果你理解了上面的流程,你完全可以不使用Git flow工具,但是如果你想更标准化的执行git flow,可以尝试使用git flow工具
安装
最新版的git都自带git flow
- 输入git flow有以下输出即为安装好的
1 | git flow |
Mac OS X
1 | $ brew install git-flow |
Linux
1 | $ apt-get install git-flow |
Windows
1 | $ wget -q -O - --no-check-certificate https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | bash |
使用
初始化
1 | git flow init |
Feature
开始新Feature:
1 | git flow feature start <MYFEATURE> # MYFEATURE:新的feature分支名 |
Publish一个Feature(也就是push到远程)
1 | git flow feature publish <MYFEATURE> # MYFEATURE:feature分支名 |
获取Publish的Feature:
1 | git flow feature pull origin <MYFEATURE> # MYFEATURE:feature分支名 |
完成一个Feature
1 | git flow feature finish <MYFEATURE> # MYFEATURE:feature分支名 |
Release
开始一个Release
1 | git flow release start RELEASE [BASE] |
Publish一个Release
1 | git flow release publish RELEASE |
发布Release
1 | git flow release finish RELEASE # 别忘了git push --tags |
Hotfix
开始一个Hotfix
1 | git flow hotfix start VERSION [BASENAME] |
发布一个Hotfix
1 | git flow hotfix finish VERSION |