為什幺要用git flow
git flow 是一個分支管理的策略,使得版本庫的演進變得簡潔,主干清晰,各個分支各司其職、井井有條。
如下展示了分支混亂的場景:

git flow是什么
git flow是一個策略,核心其實就是下圖:

主分支

中心庫有2個可一直延續(xù)的分支:
- master分支
- develop分支
master分支的特點是隨時可發(fā)布,這意味著前后端研發(fā)、測試和部署都已完成,需要嚴格控制合并執(zhí)行
develop分支的特點是最新軟件變更,base于master分支,為master分支提供內(nèi)容。
輔助性分支
輔助分支與關鍵分支(master和develop)一起,用來支持團隊成員們并行開發(fā),使得易于追蹤功能,協(xié)助生產(chǎn)發(fā)布環(huán)境準備,以及快速修復實時在線問題。與關鍵分支不同,這些分支總是有一個有限的生命期,因為他們最終會被移除。
分支類型包括:
- 功能分支
- 發(fā)布分支
- 熱修復分支
每一種分支有一個特定目的,并且受限于嚴格規(guī)則,比如:可以用哪些分支作為源分支,哪些分支能作為合并目標。
功能分支

功能分支的特點如下:
- 命名方式為feature-xxx
- 通常情況下只存在本地
- 通?;赿ev分支創(chuàng)建,開發(fā)完成后被dev分支合并,然后刪除
發(fā)布分支
可以看作是master分支發(fā)布前的緩沖分支,確保發(fā)布質(zhì)量。
發(fā)布分支的特點如下:
- 命名方式為release-xxx
- 版本提測后基于dev分支創(chuàng)建,修改完成后被dev、master分支合并,然后刪除
- 允許小bugs的修改和準備發(fā)布元數(shù)據(jù)(版本號,開發(fā)時間等等),不允許新功能的疊加。
- 建議直接修改,不走pr方式
熱修復分支

當線上版本出現(xiàn)重大問題,團隊決定緊急修復盡快發(fā)布新版本,這個時候就要用到熱修復分支。
特點:
- 命名方式為hotfix-xxx
- 基于master分支或者tag創(chuàng)建,修改完成后被dev、master分支合并,然后刪除
- 建議直接修改,不走pr方式
實際操作
功能分支
創(chuàng)建一個功能分支
開始一項功能的開發(fā)工作時,基于develop創(chuàng)建分支。
$ git checkout -b feature-x develop
Switched to a new branch "feature-x"
合并一個功能到develop分支
完成的功能可以合并進develop分支,以明確加入到未來的發(fā)布:
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff feature-x
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d feature-x
Deleted branch feature-x (was 05e9557).
$ git push origin develop
--no-ff標志導致合并操作創(chuàng)建一個新commit對象,即使該合并操作可以fast-forward。這避免了丟失這個功能分支存在的歷史信息,將該功能的所有提交組合在一起。 比較:

后一種情況,不可能從Git歷史中看到哪些提交一起實現(xiàn)了一個功能——你必須手工閱讀全部的日志信息。如果對整個功能進行回退 (比如一組提交),后一種方式會是一種真正頭痛的問題,而使用--no-ffflag的情況則很容易.
Release 分支
創(chuàng)建一個release分支
$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)
完成一個release分支
master分支merge和tag
$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2
develop分支合并
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
?刪除release分支
$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).
熱修復分支
創(chuàng)建修補bug分支
$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)
修復bug和修改版本號在此階段完成
完成一個hotfix分支
首先合并到master分支,打上tag
$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1
其次合并到develop分支
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
如果一個release分支已經(jīng)存在,那么應該把hotfix合并到這個release分支,而不是合并到develop分支。當release分支完成后, 將bugfix分支合并回release分支也會使得bugfix被合并到develop分支。(如果在develop分支的工作急需這個bugfix,等不到release分支的完成,那你也可以把bugfix合并到develop分支
最后,刪除臨時分支:
$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).
工具
- gitflow-avh
- sourceTree
參考資料
http://nvie.com/posts/a-successful-git-branching-model/
http://www.ruanyifeng.com/blog/2012/07/git.html