# Gitflow 工作流程
* 它是git工作流程的抽象概念;
* 它适合具有预定发布周期的项目;
* 它不会添加超出功能分支工作流程所需的任何新概念或命令;
* 相反,它为不同的分支分配非常具体的角色,并定义它们应该如何以及何时进行交互;
* 除功能分支外,它还使用独立的分支来准备,维护和记录版本;
* 当然,您仍可以充分利用功能分支工作流程的所有优势:拉取请求,隔离实验和更有效的协作;
* 除了抽象的Gitflow Workflow想法之外,还有一个更有形的git-flow工具集,它与Git集成以提供专门的Gitflow Git命令行工具扩展。
### gitflow工具集:
macOS安装: `$ brew install git-flow`
windows安装:需下载,https://git-scm.com/download/win
使用gitflow工具: `$ git flow init`
* * * * *
### 如何运行的?
#### 开发分支(develop)和主分支(master)
利用两个分支来记录项目历史:开发分支和主分支。
主分支(master)存储正式发布历史,而开发分支(develop)则用作功能(feature)的集成分支。
使用版本号标记(tag)主分支(master)中的所有提交也是很方便的。
![开发分支和主分支](https://git.kancloud.cn/repos/shellway/vbuild/raw/e1318e70c29dde3196c14e4e9fe71e23a873e2c4/images/screenshot_1530759456256.png?access-token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MzIzNzMyMTQsImlhdCI6MTUzMjMzMDAxNCwiYm9vayI6eyJ1cmkiOiJzaGVsbHdheVwvdmJ1aWxkIiwiaXNfYXV0b19yZWxlYXNlIjpmYWxzZX0sInVzZXIiOnsidXNlcm5hbWUiOiJzaGVsbHdheSIsIm5hbWUiOiJTaGVsbHdheSIsImVtYWlsIjoic2hlbGx3YXlAcXEuY29tIiwidG9rZW4iOiI0OWUxZTU2ZmRlYmFiOWMxODVhMTExYWQ1ZDk3MjNiMSIsImF1dGhvcml6ZSI6eyJwdWxsIjp0cnVlLCJwdXNoIjp0cnVlLCJhZG1pbiI6dHJ1ZX19fQ.dpjk50klCjWiJBRC_boNgtLURpVBUFk0pVXtWNJ3TLE)
图1:开发分支与主分支
操作步骤:
从主分支(master)扩展一个空的新分支,命名为开发分支(develop)。然后推送到服务器。
```bash
$ git branch develop
$ git push -u origin develop
```
在已有的仓库中执行 `$git flow init` ,将会自动创建开发分支(develop)。
如果是全新的仓库,会同时创建主分支(master)和开发分支(develop)。
```bash
$ git flow init
Initialized empty Git repository in ~/project/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
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 branch
* develop
master
```
* * * * *
### 功能分支(feature)
功能分支(feature)应该从开发分支(develop)拉取,并在开发完成后推送回开发分支。
功能分支(feature)不应该与主分支(master)直接交互。
![功能分支](https://git.kancloud.cn/repos/shellway/vbuild/raw/e1318e70c29dde3196c14e4e9fe71e23a873e2c4/images/screenshot_1530761414997.png?access-token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MzIzNzMyMTQsImlhdCI6MTUzMjMzMDAxNCwiYm9vayI6eyJ1cmkiOiJzaGVsbHdheVwvdmJ1aWxkIiwiaXNfYXV0b19yZWxlYXNlIjpmYWxzZX0sInVzZXIiOnsidXNlcm5hbWUiOiJzaGVsbHdheSIsIm5hbWUiOiJTaGVsbHdheSIsImVtYWlsIjoic2hlbGx3YXlAcXEuY29tIiwidG9rZW4iOiI0OWUxZTU2ZmRlYmFiOWMxODVhMTExYWQ1ZDk3MjNiMSIsImF1dGhvcml6ZSI6eyJwdWxsIjp0cnVlLCJwdXNoIjp0cnVlLCJhZG1pbiI6dHJ1ZX19fQ.dpjk50klCjWiJBRC_boNgtLURpVBUFk0pVXtWNJ3TLE)
图2:功能分支(feature)
每个新的功能分支都应该创建自最新的开发分支。
#### 1、创建功能分支
* 不使用git-flow扩展:
```bash
$ git checkout develop
$ git checkout -b feature-branch
```
* 使用git-flow扩展:
```bash
$ git flow feature start feature-branch
```
#### 2、完成功能分支
* 不使用git-flow扩展:
```bash
$ git checkout develop
$ git merge feature-branch
```
* 使用git-flow扩展:
```bash
$ git flow feature finish feature-branch
```
* * * * *
### 发布分支(release)
![发布分支](https://git.kancloud.cn/repos/shellway/vbuild/raw/e1318e70c29dde3196c14e4e9fe71e23a873e2c4/images/screenshot_1530762292885.png?access-token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MzIzNzMyMTQsImlhdCI6MTUzMjMzMDAxNCwiYm9vayI6eyJ1cmkiOiJzaGVsbHdheVwvdmJ1aWxkIiwiaXNfYXV0b19yZWxlYXNlIjpmYWxzZX0sInVzZXIiOnsidXNlcm5hbWUiOiJzaGVsbHdheSIsIm5hbWUiOiJTaGVsbHdheSIsImVtYWlsIjoic2hlbGx3YXlAcXEuY29tIiwidG9rZW4iOiI0OWUxZTU2ZmRlYmFiOWMxODVhMTExYWQ1ZDk3MjNiMSIsImF1dGhvcml6ZSI6eyJwdWxsIjp0cnVlLCJwdXNoIjp0cnVlLCJhZG1pbiI6dHJ1ZX19fQ.dpjk50klCjWiJBRC_boNgtLURpVBUFk0pVXtWNJ3TLE)
图3:发布分支(release)
当开发分支中积累了一定的发布功能,或者临近预定的发布日期时,我们可以从开发分支中分离出一个发布分支。
创建此分支将启动下一个发布周期,此时开始发布分支不应再添加任何新功能,只能做一些错误修复,文档生成或其他面向发布的任务。
一旦准备好发布,发布分支就会合并到主服务器并标记版本号。
此外,它应该合并回到开发分支中,以同步发布分支创建以来可能已经取得的进展。
使用专用分支准备发布使一个团队可以完善当前版本,而另一个团队继续为下一个版本开发功能。
它还创建了明确定义的开发阶段(例如,很容易说,“本周我们正在为版本4.0做准备”,并且实际上在存储库的结构中看到它)。
发布分支是另一种简单的分支操作。与功能分支一样,发布分支基于开发分支。
#### 创建发布分支
可以使用以下方法创建新的发布分支。
* 不使用git-flow扩展:
```bash
$ git checkout develop
$ git checkout -b release/0.1.0
```
* 使用git-flow扩展:
```bash
$ git flow release start 0.1.0
Switched to a new branch 'release/0.1.0'
```
#### 完成发布分支
使用以下方法完成发布分支:
* 不使用git-flow扩展:
```bash
$ git checkout develop
$ git merge release/0.1.0
```
* 使用git-flow扩展:
```bash
$ git checkout master
$ git checkout merge release/0.1.0
$ git flow release finish '0.1.0'
```
* * * * *
### 紧急修复分支(hotfix)
![修复分支](https://git.kancloud.cn/repos/shellway/vbuild/raw/e1318e70c29dde3196c14e4e9fe71e23a873e2c4/images/screenshot_1530769335523.png?access-token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MzIzNzMyMTQsImlhdCI6MTUzMjMzMDAxNCwiYm9vayI6eyJ1cmkiOiJzaGVsbHdheVwvdmJ1aWxkIiwiaXNfYXV0b19yZWxlYXNlIjpmYWxzZX0sInVzZXIiOnsidXNlcm5hbWUiOiJzaGVsbHdheSIsIm5hbWUiOiJTaGVsbHdheSIsImVtYWlsIjoic2hlbGx3YXlAcXEuY29tIiwidG9rZW4iOiI0OWUxZTU2ZmRlYmFiOWMxODVhMTExYWQ1ZDk3MjNiMSIsImF1dGhvcml6ZSI6eyJwdWxsIjp0cnVlLCJwdXNoIjp0cnVlLCJhZG1pbiI6dHJ1ZX19fQ.dpjk50klCjWiJBRC_boNgtLURpVBUFk0pVXtWNJ3TLE)
图4:紧急修复分支(hotfix)
紧急修复分支基于主分支(master),用于快速发布产品补丁。此分支是唯一直接从主分支(master)分离出来的分支。
紧急修复分支完成后应该马上合并回主分支,并合并到开发分支(develop)或者发布分支(release)。
然后,主分支应该马上被打上新的版本号tag。
通过专门的紧急修复开发,您的团队可以解决问题,而无需中断工作流的其余部分或等待下一个发布周期。
您可以将维护分支/紧急修复分支视为直接与主分支(master)一起工作的临时发布分支。
可以使用以下方法创建紧急修复分支:
* 不使用git-flow扩展:
```bash
$ git checkout master
$ git checkout -b hotfix_branch
```
* 使用git-flow扩展:
```bash
$ git flow hotfix start hotfix_branch
```
如同结束发布分支(release)一样,我们应该将紧急修复分支(hotfix)合并回主分支(master)和开发分支(develop)。
```bash
$ git checkout master
$ git merge hotfix_branch
$ git checkout develop
$ git merge hotfix_branch
$ git branch -D hotfix_branch //删除本地和远程分支
```
或者使用git-flow扩展:
```bash
$ git flow hotfix finish hotfix_branch
```
* * * * *
### 示例代码
#### 功能分支完整示例:
假设有一个包含主分支(master)的仓库:
```bash
$ git checkout master
$ git checkout -b develop
$ git checkout -b feature_branch
// 在feature_branch分支上进行新功能开发工作...
// ...
// 完成新功能开发
$ git checkout develop
$ git merge feature_branch
$ git checkout master
$ git merge develop
$ git branch -d feature_branch // 删除本地功能分支;若要同时删除远程,参数改成-D
```
在功能开发(feature)和发布开发(release)流程之间,紧急修复流程示例如下:
```bash
// 新建紧急修复分支
$ git checkout master
$ git checkout -b hotfix_branch
// 紧急修复bug
// ...
// 修复完成
// 合并到开发分支
$ git checkout develop
$ git merge hotfix_branch
// 合并到主分支
$ git checkout master
$ git merge hotfix_branch
// 删除紧急修复分支
$ git branch -d hotfix_branch // 参数-D,同时删除本地和远程分支
```
### 总结
gitflow整体流程:
1. 开发分支(develop)创建自主分支(master);
2. 发布分支(release)创建自开发分支(develop);
3. 功能分支(feature)创建自开发分支(develop);
4. 功能分支(feature)开发完成后,合并回开发分支(develop);
5. 发布分支(release)完成后,合并回开发分支(develop)和主分支(master);
6. 若主分支(master)发现问题需要修复,从主分支(master)创建紧急修复分支(hotfix);
7. 紧急修复(hotfix)完成后,合并回开发分支(develop)和主分支(master);