1 Git Flow介紹
我們都知道, 在 git 的分支功能相對(duì) svn 確實(shí)方便許多,而且也非常推薦使用分支來做開發(fā). 我的做法是每個(gè)項(xiàng)目都有2個(gè)分支, master 和 develop. master 分支是主分支, 保證程序有一個(gè) 穩(wěn)定版本, develop 則是開發(fā)用的分支, 幾乎所有的功能開發(fā), bug 修復(fù)都在這個(gè)分支上, 完成后再合并回 master.
但是情況并不是這么簡單. 有時(shí)當(dāng)我們正在開發(fā)一個(gè)功能, 但程序突然出現(xiàn) bug 需要及時(shí)去修復(fù)的時(shí)候, 這時(shí)要切回 master 分支, 并基于它創(chuàng)建一個(gè) hotfix 分支. 有時(shí)我們?cè)陂_發(fā)一個(gè)功能時(shí), 需要停下來去開發(fā)另一個(gè)功能. 而且所有這些問題都出現(xiàn) 的時(shí)候, 發(fā)布也會(huì)成為比較棘手問題.
也就是說, git branch 功能很強(qiáng)大,但是沒有一套模型告訴我們應(yīng)該怎樣在開發(fā)的時(shí)候善用這些分支。而Git Flow模型就是要告訴我們?cè)趺锤玫厥褂肎it分支。
簡單來說,git-flow 就是在 git branch git tag基礎(chǔ)上封裝出來的代碼分支管理模型,把實(shí)際開發(fā)模擬成 master develop feature release hotfix support 幾種場(chǎng)景,其中 master 對(duì)應(yīng)發(fā)布上線,develop 對(duì)應(yīng)開發(fā),其他幾個(gè)在不同的情況下出現(xiàn)。通過封裝,git-flow 屏蔽了 git branch 等相對(duì)來說比較復(fù)雜生硬的命令(git branch 還是比較復(fù)雜的,尤其是在多分支情況下),簡單而且規(guī)范的解決了代碼分支管理問題。
簡單來說, Git Flow將 branch 分成2個(gè)主要分支和3個(gè)臨時(shí)的輔助分支:

主要分支
master: 永遠(yuǎn)處在
即將發(fā)布(production-ready)狀態(tài);develop:
最新的開發(fā)狀態(tài);
輔助分支
feature:
開發(fā)新功能的分支, 基于 develop, 完成后merge 回 develop;release:
準(zhǔn)備要發(fā)布版本的分支, 用來修復(fù) bug. 基于 develop, 完成后merge 回 develop 和 master;hotfix:
修復(fù) master 上的問題, 等不及 release 版本就必須馬上上線.基于 master, 完成后merge 回 master 和 develop;
2 Git Flow使用
2.1 Git Flow安裝構(gòu)建
安裝 git-flow:
? brew install git-flow
作者還提供了 git-flow 命令工具,在一個(gè)全新目錄下構(gòu)建 git-flow 模型:
? git flow init
接著它會(huì)問你一系列的問題,蛋定!盡量使用它的默認(rèn)值就好了:
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? []
或者在現(xiàn)有的版本庫構(gòu)建:
? git flow init
Which branch should be used for bringing forth production releases?
- master
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? []
這樣一個(gè) git-flow 分支模型就初始化完成。
2.2 場(chǎng)景1:新功能開發(fā),代號(hào) f1
-
基于develop,開啟新功能分支開發(fā)
完成前面構(gòu)建操作,當(dāng)前所在分支就變成 develop. 任何開發(fā)都必須從 develop 開始:
? git flow feature start f1git-flow 從 develop 分支創(chuàng)建了一個(gè)新的分支 feature/f1,并自動(dòng)切換到這個(gè)分支下面。然后就可以進(jìn)行 f1 功能開發(fā),中間可以多次的 commit 操作。將一個(gè) f1 分支推到遠(yuǎn)程服務(wù)器,與其他開發(fā)人員協(xié)同開發(fā):
? git flow feature publish f1 或者 ? git push origin feature/f1 -
完成功能開發(fā),結(jié)束新功能分支并刪除:
? git flow feature finish f1feature/f1 分支的代碼會(huì)被合并到 develop 里面,然后刪除該分支,切換回 develop. 到此,新功能開發(fā)這個(gè)場(chǎng)景完畢。在 f1 功能開發(fā)中,如果 f1 未完成,同時(shí)功能 f2 要開始進(jìn)行,也是可以的。
2.3 場(chǎng)景2:發(fā)布上線,代號(hào) 0.1
-
基于develop,開發(fā)發(fā)布分支
? git flow release start 0.1 Switched to a new branch 'release/0.1' Summary of actions: - A new branch 'release/0.1' was created, based on 'develop' - You are now on branch 'release/0.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 '0.1' -
git-flow 從 develop 分支創(chuàng)建一個(gè)新的分支 release/0.1,并切換到該分支下,接下來要做的就是修改版本號(hào)等發(fā)布操作。完成后:
? git flow release finish 0.1 Switched to branch 'master' Merge made by the 'recursive' strategy. f1 | 1 + version | 1 + 2 files changed, 2 insertions(+) create mode 100644 f1 create mode 100644 version Switched to branch 'develop' Merge made by the 'recursive' strategy. version | 1 + 1 file changed, 1 insertion(+) create mode 100644 version Deleted branch release/0.1 (was d77df80). Summary of actions: - Latest objects have been fetched from 'origin' - Release branch has been merged into 'master' - The release was tagged '0.1' - Release branch has been back-merged into 'develop' - Release branch 'release/0.1' has been deleted -
git-flow 會(huì)依次切換到 master develop 下合并 release/0.1 里的修改,然后用 git tag 的給當(dāng)次發(fā)布打上 tag 0.1,可以通過 git tag 查看所有 tag:
? git:(master) git tag 0.1 0.2
2.3 場(chǎng)景3:緊急 bug 修正,代號(hào) bug1
-
基于master,開啟熱修復(fù)分支
? git flow hotfix start bug1 Switched to a new branch 'hotfix/bug1' Summary of actions: - A new branch 'hotfix/bug1' was created, based on 'master' - You are now on branch 'hotfix/bug1' Follow-up actions: - Bump the version number now! - Start committing your hot fixes - When done, run: git flow hotfix finish 'bug1' -
git-flow 從 master 分支創(chuàng)建一個(gè)新的分支 hotfix/bug1,并切換到該分支下。接下來要做的就是修復(fù) bug,完成后:
? git flow hotfix finish bug1 Switched to branch 'master' Merge made by the 'recursive' strategy. f1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Switched to branch 'develop' Merge made by the 'recursive' strategy. f1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Deleted branch hotfix/bug1 (was aa3ca2e). Summary of actions: - Latest objects have been fetched from 'origin' - Hotfix branch has been merged into 'master' - The hotfix was tagged 'bug1' - Hotfix branch has been back-merged into 'develop' - Hotfix branch 'hotfix/bug1' has been deletedgit-flow 會(huì)依次切換到 master develop 分支下合并 hotfix/bug1,然后刪掉 hotfix/bug1。到此,hotfix 完成。
git-flow 的 feature release 都是從 develop 分支創(chuàng)建,hotfix support 都是從 master 分支創(chuàng)建。
3 一種的經(jīng)典分支管理規(guī)范

如上圖所示:
最穩(wěn)定的代碼放在 master 分支上(相當(dāng)于 SVN 的 trunk 分支),我們不要直接在 master 分支上提交代碼,只能在該分支上進(jìn)行代碼合并操作,例如將其它分支的代碼合并到 master 分支上。我們
日常開發(fā)中的代碼需要從 master 分支拉一條 develop 分支出來,該分支所有人都能訪問,但一般情況下,我們也不會(huì)直接在該分支上提交代碼,代碼同樣是從其它分支合并到 develop 分支上去。當(dāng)我們需要開發(fā)某個(gè)特性時(shí),
需要從 develop 分支拉出一條 feature 分支,例如 feature-1 與 feature-2,在這些分支上并行地開發(fā)具體特性。當(dāng)特性開發(fā)完畢后,我們決定需要發(fā)布某個(gè)版本了,
此時(shí)需要從 develop 分支上拉出一條 release 分支,例如 release-1.0.0,并將需要發(fā)布的特性從相關(guān) feature 分支一同合并到 release 分支上,隨后將針對(duì) release 分支部署測(cè)試環(huán)境,測(cè)試工程師在該分支上做功能測(cè)試,開發(fā)工程師在該分支上修改 bug。待測(cè)試工程師無法找到任何 bug 時(shí),
我們可將該 release 分支部署到預(yù)發(fā)環(huán)境,再次驗(yàn)證以后,均無任何 bug,此時(shí)可將 release 分支部署到生產(chǎn)環(huán)境。待上線完成后,
將 release 分支上的代碼同時(shí)合并到 develop 分支與 master 分支,并在 master 分支上打一個(gè) tag,例如 v1.0.0。當(dāng)生產(chǎn)環(huán)境發(fā)現(xiàn) bug 時(shí),我們
需要從對(duì)應(yīng)的 tag 上(例如 v1.0.0)拉出一條 hotfix 分支(例如 hotfix-1.0.1),并在該分支上做 bug 修復(fù)。待 bug 完全修復(fù)后,需將 hotfix 分支上的代碼同時(shí)合并到 develop 分支與 master 分支。
對(duì)于版本號(hào)我們也有要求,格式為:x.y.z,其中,x 用于有重大重構(gòu)時(shí)才會(huì)升級(jí),y 用于有新的特性發(fā)布時(shí)才會(huì)升級(jí),z 用于修改了某個(gè) bug 后才會(huì)升級(jí)。針對(duì)每個(gè)微服務(wù),我們都需要嚴(yán)格按照以上開發(fā)模式來執(zhí)行。
與Git Flow模型分支管理的區(qū)別點(diǎn):
feature分支開發(fā)完成后,暫時(shí)不合并至develop,而是基于develop開啟release分支,將feature分支合并到release分支,進(jìn)行測(cè)試;
release分支測(cè)試通過后,部署到生產(chǎn)環(huán)境,將release分支代碼合并到develop分支與master分支,并在master分支打一個(gè)tag;