Git Flow工作流程
目录
转载请备注来源: 《Git Flow工作流程》 | shuwoom.com
在团队开发中,使用版本系统时,约定一个统一的开发流程是很重要的。而目前应用最多的就是Git Flow的模型。
Git Flow是在Git之上构建的一个软件开发最佳实践,它是一套使用Git进行源代码管理时的一套行为规范和简化部分Git操作的工具。Git Flow的开发模型如下图所示:

Git Flow分支应用情境
遵循Git Flow的建议,主要的分支有master、develop、hotfix、release以及feature这五种分支,各种分支负责不同的功能。
Git Flow初始化以后,默认会创建两个主分支在仓库中,这两个分支会一直存活在整个Git Flow里,也被称作长期分支,而其他分支大多会因为任务的结束而被移除,仅仅只是临时存在的。
$ git branch * develop master

1.Git Flow master分支
master分支只用用来包括产品代码。我们不能直接在master分支上工作,而是在其他指定的独立分支中工作。同时,也不能直接提交改动到master分支上,这些都是很多工作流程的一个共同原则。
2.Git Flow develop分支
develop分支是所有开发的基础分支。当要开发新功能的时候,所有的feature分支都是从这个分支切出去的,而feature分支的功能完成后也都会合并会这个分支。所以,develop分支上汇总了所有已完成的功能,它最终是会被整合到master分支中。

3.Git Flow hotfix分支
中文名叫做补丁分支。当线上产品发生紧急问题的时候,会从master分支切除一个hotfix分支来进行修复,hotfix分支修复完成后,会合并回master分支,同时也会合并一份到develop分支,保持develop分支代码最新。这里大家肯能会有疑问,为什么不是基于develop分支切出去hotfix分支。这里是因为产品的代码是在master分支,修复自然也就是基于master分支进行。
4.Git Flow release分支
中文名叫预发分支。当我们认为develop分支足够成熟了,就可以把develop分支合并到release分支上,在这边进行上线前的最后测试。测试完成后,分支会同时合并到master以及develop两个分支上。master分支是上线版本,而合并会develop分支的目的,是因为在release分支上可能走了一些修正之类的提交,所以需要跟develop分支同步,避免后续版本出现同样问题。
5.Git Flow feature分支
中文名叫功能分支。当要开发新功能时,就是用feature分支。feature分支是从develop分支切出来的,开发完成以后会再合并会develop分支。
接下来,我们通过实际的一个案例来了解git flow在实际运用过程中使用的命令。

Git Flow案例实践
1.初始化Git Flow
在使用初始化命令时,会有一系列分支创建的提示,建议一路默认即可。
$ git flow init Initialized empty Git repository in C:/Users/snowwen/Desktop/test/.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/] Bugfix branches? [bugfix/] Release branches? [release/] Hotfix branches? [hotfix/] Support branches? [support/] Version tag prefix? [] Hooks and filters directory? [C:/Users/snowwen/Desktop/test/.git/hooks]
2.Git Flow-功能开发
对于开发人员来说,平时最常做的事情就是新功能开发。
(1)创建一个功能
下面,让我们来模拟一个新功能(rss-feed)开发时,要怎么应用git flow。
$ git flow feature start rss-feed Switched to a new branch 'feature/rss-feed' Summary of actions: - A new branch 'feature/rss-feed' was created, based on 'develop' - You are now on branch 'feature/rss-feed' Now, start committing on your feature. When done, use: git flow feature finish rss-feed
使用git flow命令,会创建一个feature/rss-feed的功能分支,这个分支是在develop分支上创建。同时我们也可以看到执行这个命令后返回的一系列提示。
这时候,我们可以看到一共有3个分支,而我们目前处于功能分支中:
$ git branch develop * feature/rss-feed master
执行如下git flow的功能分支命令,
git flow feature start feature_branch
相当于执行了下面一系列的git命令:
git checkout develop git checkout -b feature_branch
(2)完成一个功能
经过一段时间的开发,我们终于完成了一个功能。这里,我们本地模拟提交一个文本:
$ git log --pretty=oneline 5884bd9ecff7c2e9223dad28d7356cfa68099c07 (HEAD -> feature/rss-feed) rss feed d535460970a12f94f43fea6c5ea8c415425b58d1 (master, develop) Initial commit $ ll total 1 -rw-r--r-- 1 snowwen 1049089 8 七月 5 08:54 test1.txt
接下来,我们就要结束并提交这个功能模块
$ git flow feature finish rss-feed Switched to branch 'develop' Updating d535460..5884bd9 Fast-forward test1.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test1.txt Deleted branch feature/rss-feed (was 5884bd9). Summary of actions: - The feature branch 'feature/rss-feed' was merged into 'develop' - Feature branch 'feature/rss-feed' has been locally deleted - You are now on branch 'develop'
这时候,我们会发现已经切回develop分支,而功能分支“feature/rss-feed”也已经合并到develop中和移除。
$ git branch * develop master $ git log --pretty=oneline 5884bd9ecff7c2e9223dad28d7356cfa68099c07 (HEAD -> develop) rss feed d535460970a12f94f43fea6c5ea8c415425b58d1 (master) Initial commit
执行如下git flow的功能分支命令,
git flow feature finish feature_branch
相当于执行了下面一系列的git命令:
git checkout develop git merge feature_branch git branch -d feature_branch
3.Git Flow-管理releases

(1)创建release
当你任务现在的develop分支已经是一个比较成熟稳定的release版本时,这意味着它包括了偶有的功能和必要的修复,同时它也被彻底测试过。如果这两点都满足,那就可以生成一个新的release分支了。
$ git flow release start 1.1.1 Switched to a new branch 'release/1.1.1' Summary of actions: - A new branch 'release/1.1.1' was created, based on 'develop' - You are now on branch 'release/1.1.1' Follow-up actions: - Bump the version number now! - Start committing last-minute fixes in preparing your release - When done, run: git flow release finish '1.1.1'
这时,我们切到'release/1.1.1'分支。
$ git branch develop master * release/1.1.1
注意:这里release分支的命名最好使用版本号,这时一个明智的选择,因为这个命名方案还有一个很好的附带功能,就是当我们完成release后,Git flow会自动去标记哪些release提交,也就是创建tag。
有了一个release分之后,我们就可以做最后的准备工作(例如修改项目里某些文件的版本号)或者在预发环境里测试,并进行最后的编辑提交。
执行如下git flow的release分支命令,
git flow release start release_branch
相当于执行了下面一系列的git命令:
git checkout develop git checkout -b release_branch
(2)完成release
现在,我们可以完成release。
$ git flow release finish 1.1.1 Switched to branch 'master' Merge made by the 'recursive' strategy. readme.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 readme.md Already on 'master' Switched to branch 'develop' Merge made by the 'recursive' strategy. readme.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 readme.md Deleted branch release/1.1.1 (was 2902070). Summary of actions: - Release branch 'release/1.1.1' has been merged into 'master' - The release was tagged '1.1.1' - Release tag '1.1.1' has been back-merged into 'develop' - Release branch 'release/1.1.1' has been locally deleted - You are now on branch 'develop'
这个完成操作会把内容合并到master和develop两个分支上,同时保持产品代码和新的功能分支代码最新。同时也会创建tag标签标记这个版本号。
$ git tag 1.1.1
我们可以看到develop分支和master分支已经保持代码最新。
snowwen@snowwen-PC0 MINGW64 ~/Desktop/test (develop) $ git log --pretty=oneline ec5171debc287675775b37ffd9c4b1738a48c734 (HEAD -> develop) Merge tag '1.1.1' into develop 40ea315e7dcd10aaa667b36800205bfed4d37ef7 (tag: 1.1.1, master) Merge branch 'release/1.1.1' 2902070face43025fc06a75e3d09ae05dd83c96e add version file 8fbf8bf9b895d1d45f9226847516a2b1376b23f8 Merge branch 'release/1.1.1' 910289c2398448ead53b8e0e556560a99036cf5b add test2.txt 5884bd9ecff7c2e9223dad28d7356cfa68099c07 rss feed d535460970a12f94f43fea6c5ea8c415425b58d1 Initial commit snowwen@snowwen-PC0 MINGW64 ~/Desktop/test (master) $ git log --pretty=oneline 40ea315e7dcd10aaa667b36800205bfed4d37ef7 (HEAD -> master, tag: 1.1.1) Merge branch 'release/1.1.1' 2902070face43025fc06a75e3d09ae05dd83c96e add version file 8fbf8bf9b895d1d45f9226847516a2b1376b23f8 Merge branch 'release/1.1.1' 910289c2398448ead53b8e0e556560a99036cf5b add test2.txt 5884bd9ecff7c2e9223dad28d7356cfa68099c07 rss feed d535460970a12f94f43fea6c5ea8c415425b58d1 Initial commit
在这个过程中,会弹出三个输入注释的编辑框,第一个需要我们对合并操作进行备注说明。修改确认后,直接在vim输入:wq保存即可。
Merge branch 'release/1.1.1' # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
第二个编辑框会提示我们输入tag的标签名,编辑后保存退出:wq。
1.1.1 # # Write a message for tag: # 1.1.1 # Lines starting with '#' will be ignored.
最后一个输入框还是需要说明合并的意图。
执行如下git flow的release分支命令,
git flow release finish release_branch
相当于执行了下面一系列的git命令:
git checkout master git merge release_branch git checkout develop git merge release_branch git branch -d release_branch
4.Git Flow-hotfix修复

(1)创建hotfix
有时候,当我们在发布产品以后,可能用户或后期使用发现了一些问题。这时候,git flow提供了一个特定的hotfix处理流程,这时候使用功能分支或者release分支都是不合适的,因为我们是在产品的代码上出现问题。所以这个hotfix是基于master分支创建的。
$ git flow hotfix start missing-link Switched to a new branch 'hotfix/missing-link' Summary of actions: - A new branch 'hotfix/missing-link' was created, based on 'master' - You are now on branch 'hotfix/missing-link' Follow-up actions: - Start committing your hot fixes - Bump the version number now! - When done, run: git flow hotfix finish 'missing-link'
这时候我们就切刀了hotfix分支:
$ git branch develop * hotfix/missing-link master
执行如下git flow的hotfix分支命令,
git flow hotfix start hotfix_branch
相当于执行了下面一系列的git命令:
git checkout develop git checkout -b hotfix_branch
(2)完成hotfix
完成修复后,提交到hotfix分支,接下来完成它。
$ git flow hotfix finish missing-link Switched to branch 'master' Merge made by the 'recursive' strategy. test1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Switched to branch 'develop' Merge made by the 'recursive' strategy. test1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Deleted branch hotfix/missing-link (was 592fd3e). Summary of actions: - Hotfix branch 'hotfix/missing-link' has been merged into 'master' - The hotfix was tagged 'missing-link' - Hotfix tag 'missing-link' has been back-merged into 'develop' - Hotfix branch 'hotfix/missing-link' has been locally deleted - You are now on branch 'develop'
同样的,他也会弹出编辑框,跟我们提交完成release分支类似。
执行如下git flow的release分支命令,
git flow release finish hotfix_branch
相当于执行了下面一系列的git命令:
git checkout master git merge hotfix_branch git checkout develop git merge hotfix_branch git branch -d hotfix_branch
总结
所以,我们可以看到实际上git flow就是一系列git命令的集合,当我们使用习惯并形成自己的一套工作模式后,可以完全不实用Git flow来实现。下面,我们对Git flow的一些关键知识再做一遍总结。
- develop分支是从master分支上创建
- release分支是从develop分支上创建
- feature分支是从develop分支上创建
- hotfix分支是从master分支上创建
- 当feature分支完成后,它会合并到develop分支
- 当release分支完成后,它会合并到develop和master分支
- 当hotfix分支完成后,它会合并到develop和master分支
转载请备注来源: 《Git Flow工作流程》 | shuwoom.com