下午看到一篇介紹Git工作模型的文章咳蔚,覺得很不錯(cuò)。為了方便大家快速掌握文章的內(nèi)容箫攀,這里對(duì)這篇文章的要點(diǎn)進(jìn)行簡(jiǎn)單的介紹
原文地址:http://nvie.com/posts/a-successful-git-branching-model/
為何使用Git
關(guān)于Subversion和Git的優(yōu)劣比較有很多的文章已經(jīng)進(jìn)行了比較詳細(xì)的介紹昔搂,這并不是這篇文章的重點(diǎn)竹观。但是Git的一些優(yōu)勢(shì)卻是這種模型的基礎(chǔ)拍嵌,因此對(duì)于這一部分應(yīng)當(dāng)進(jìn)行必要的介紹遭赂。
分支
But with Git, these actions are extremely cheap and simple, and they are considered one of the core parts of your daily workflow, really. For example, in CVS/Subversion books, branching and merging is first discussed in the later chapters (for advanced users), while in every Git book, it’s already covered in chapter 3 (basics).
Git相比較Subversion而言,有一個(gè)顯著的優(yōu)勢(shì)就是對(duì)分支的使用非常的方便横辆。在Git中撇他,分支的使用是非常鼓勵(lì)和推薦的,因此在《Pro Git》中把分支的使用是作為基礎(chǔ)章節(jié)來介紹的狈蚤,也就是說分支是Git中經(jīng)常會(huì)用到的操作困肩。而本文所介紹的這種模型,就是建立在對(duì)分支頻繁操作(創(chuàng)建炫惩,切換僻弹,合并等)的基礎(chǔ)上的。
非集中式
非集中式的版本控制系統(tǒng)是Git的另一大優(yōu)勢(shì)他嚷。這就表示,在使用Git的時(shí)候芭毙,每一次代碼的提交都不必同步到遠(yuǎn)程服務(wù)器中筋蓖,開發(fā)人員可以在外部網(wǎng)絡(luò)環(huán)境(無法連接內(nèi)網(wǎng)),甚至離線的情況下進(jìn)行代碼的版本控制退敦。作為非集中式的版本控制系統(tǒng)粘咖,開發(fā)人員可以在本地創(chuàng)建分支而不必同步到服務(wù)器上,這一點(diǎn)是構(gòu)成文中Git分支模型的另一大基礎(chǔ)侈百。
主分支(Main Branch)
在Git分支模型中存在兩個(gè)主分支瓮下,這兩個(gè)分支是不可或缺的:
master分支
develop分支
master分支
master作為Git中默認(rèn)的主分支翰铡,是使用Git的開發(fā)者們非常熟悉的默認(rèn)主分支名稱。在Git分支開發(fā)模型中讽坏,master分支的HEAD節(jié)點(diǎn)始終處于“準(zhǔn)備好進(jìn)行生產(chǎn)的狀態(tài)”锭魔,即master分支的HEAD節(jié)點(diǎn)所指向的版本始終是可以用于生產(chǎn)環(huán)境的正式版本。當(dāng)其他分支的代碼版本合并到master分支時(shí)(隨后打上版本標(biāo)簽)路呜,通常意味著一個(gè)新的正式版本已經(jīng)發(fā)布迷捧。該過程的具體介紹詳見后文。
develop分支
develop分支作為另一個(gè)主分支胀葱,其HEAD節(jié)點(diǎn)總是指向下一個(gè)待發(fā)布版本的最新變化漠秋。develop分支的版本變更通常來源于輔助分支的合并(稍后介紹),因?yàn)閐evelop分支也常被稱為“整合分支”抵屿。當(dāng)develop分支達(dá)到某一穩(wěn)定點(diǎn)庆锦,可進(jìn)行新版本的發(fā)布時(shí),develop分支上的所有變更應(yīng)該被合并到master分支并打上tag標(biāo)簽轧葛,該過程詳見后文肥荔。
輔助分支(Supporting Branch)
除了master分支和develop分支這兩個(gè)主分支以外,Git分支模型中擁有一些“輔助分支”朝群,在團(tuán)隊(duì)開發(fā)中對(duì)develop分支和master分支進(jìn)行幫助燕耿,例如對(duì)新需求的研發(fā),新版本發(fā)布前的準(zhǔn)備工作以及新版本bug的緊急修復(fù)等姜胖。和主分支不同的是誉帅,這些分支的生命周期都是很有限的,最終都將會(huì)被刪除右莱。輔助分支中有以下三類分支:
- 需求分支(Feature Branch)
- 發(fā)布分支(Release Branch)
- 修復(fù)分支(Hotfix Branch)
上述三種輔助分支蚜锨,每一種都有其特定的功能,并遵守各自嚴(yán)格的規(guī)則,例如分支的輸入分支慢蜓、分支的輸出(合并)分支等等亚再。下文將逐一描述。
需求分支(Feature Branch)
分支來源:develop分支
分支去向:develop分支
分支命名:任意名稱晨抡,除master氛悬,develop,以“release-”開頭耘柱,以“hotfix-”開頭的分支以外如捅。
需求分支用于為未來的軟件版本開發(fā)新的功能需求。當(dāng)進(jìn)行一個(gè)需求的研發(fā)時(shí)调煎,該需求將被整合進(jìn)正式版本是未知镜遣,所以需要單獨(dú)創(chuàng)建分支對(duì)該需求進(jìn)行研發(fā),只要該需求尚在開發(fā)中士袄,該需求分支就會(huì)一直存在悲关。需求分支最終會(huì)被合并到develop分支中作為下一個(gè)待發(fā)布版本的功能之一谎僻,或者由于該需求無法實(shí)現(xiàn)從而被拋棄。
注:需求分支通常僅僅存在于開發(fā)者的代碼倉(cāng)庫中(本地倉(cāng)庫)寓辱,并不上傳到遠(yuǎn)程分支艘绍。
如何創(chuàng)建需求分支
創(chuàng)建需求分支時(shí),該分支必須從develop分支得到:
$ git checkout -b feature_branch develop
該命令從develop分支創(chuàng)建一個(gè)新的分支“feature_branch”讶舰,并從當(dāng)前分支切換到“feature_branch”分支鞍盗,相當(dāng)于:
$ git branch feature_branch develop
$ git checkout feature_branch
將已完成的需求分支合并到develop分支
已完成的需求分支需要被合并到develop分支,作為待發(fā)布版本的需求之一:
$ git checkout develop #切換到develop分支
$ git merge --no-ff feature_branch #合并分支
$ git branch -d feature_branch #刪除需求分支
$ git push origin develop #推送
--no-ff表示No Fast Forward跳昼,在合并使般甲,即使可能是fast forward方式,也會(huì)創(chuàng)建一個(gè)新的commit節(jié)點(diǎn)鹅颊。
關(guān)于fast forward
當(dāng)前分支合并到另一分支時(shí)敷存,如果沒有分歧解決,就會(huì)直接移動(dòng)文件指針堪伍。這個(gè)過程叫做fast forward锚烦。
例如,開發(fā)一直在master分支進(jìn)行帝雇,但忽然有一個(gè)新的想法涮俄,于是新建了一個(gè)develop的分支,并在其上進(jìn)行一系列提交尸闸,完成時(shí)彻亲,回到 master分支,此時(shí)吮廉,master分支在創(chuàng)建develop分支之后并未產(chǎn)生任何新的commit苞尝。此時(shí)的合并就叫fast forward,如下圖:
可以看到master在合并develop分支的時(shí)候并沒有產(chǎn)生新的節(jié)點(diǎn)
回到develop分支宦芦,對(duì)代碼進(jìn)行修改宙址,提交。切換到master分支调卑,使用git merge develop --no-ff 進(jìn)行合并抡砂,此時(shí)會(huì)產(chǎn)生一個(gè)commit節(jié)點(diǎn),如下圖:
刪除分支develop后,如下圖:
很明顯使用--no-ff合并時(shí)令野,在刪除develop分之后舀患,該分支的合并信息仍然被保留,在以后的代碼分析中可以便捷的查看到歷史信息气破,而fast forward方式則無法辨識(shí)代碼的合并信息。正如原文所說:
The --no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature.
發(fā)布分支(Release Branch)
分支來源:develop分支
分支去向:develop分支和master分支
分支命名:以"release-"開頭
發(fā)布分支用于輔助新版本(生產(chǎn)環(huán)境)發(fā)布的準(zhǔn)備工作餐抢,例如小bug的修復(fù)现使,或者版本號(hào)的修改等等低匙。使用發(fā)布分支的好處是,當(dāng)從develop分支中創(chuàng)建發(fā)布分支以后碳锈,develop分支便可以進(jìn)行新版本之后需求的研發(fā)工作顽冶,從而既不會(huì)影響到最新的研發(fā)進(jìn)度,也不會(huì)影響到新版本的發(fā)布售碳。
創(chuàng)建發(fā)布分支
發(fā)布分支以develop分支作為源分支强重。例如,目前develop分支上的所有需求將作為版本1.2發(fā)布贸人,這時(shí)可以創(chuàng)建一個(gè)分支"release-1.2"间景。此時(shí)可以繼續(xù)在develop分支上進(jìn)行新需求的研發(fā),而1.2版本的發(fā)布工作將由“release-1.2”分支來完成:
$ git checkout -b release-1.2 develop #創(chuàng)建并切換到"release-1.2"分支
$ vim file #表示對(duì)版本號(hào)的修改艺智,或者小bug的修復(fù)等
$ git commit -a -m "更新版本至1.2" #提交代碼
注: 如果在發(fā)布分支進(jìn)行小型bug的修改倘要,則需要將提交后的代碼合并到develop分支中
完成發(fā)布分支
當(dāng)發(fā)布分支完成代碼的提交(如果修復(fù)過bug,則要合并到develop分支)后十拣,需要將發(fā)布分支合并到master分支上封拧,并進(jìn)行tag操作,如:
$ git checkout master
$ git merge --no-ff release-1.2
$ git tag -a "v1.2"
PS:合并到develop的操作:
$ git checkout develop
$ git merge --no-ff release-1.2
完成合并操作以后夭问,刪除該發(fā)布分支:
$ git branch -d release-1.2
修復(fù)分支(Hotfix Branch)
分支來源:master分支
分支去向:develop分支和master分支
分支命名:以"hotfix-"開頭
修復(fù)分支用于正式版本的緊急修復(fù)泽西,在緊急修復(fù)完成以后必須同時(shí)被合并到master分支和develop分支,這是修復(fù)分支和發(fā)布分支不同之處(二者的來源也不同)缰趋,和發(fā)布分支類似捧杉,修復(fù)分支在修復(fù)bug,提交埠胖,被合并以后糠溜,也要進(jìn)行tag操作。
創(chuàng)建修復(fù)分支
$ git checkout -b hotfix-1.2.1 master
$ vim file #表示修復(fù)bug
$ git commit -a -m "修復(fù)bug"
$ vim file #表示更新版本號(hào)
$ git commit -a -m "版本更新為1.2.1"
完成修復(fù)分支
$ git checkout master
$ git merge --no-ff hotfix-1.2.1
$ git tag -a 1.2.1 #tag操作
不要忘記合并修復(fù)分支到develop分支
$ git checkout develop
$ git merge --no-ff hotfix-1.2.1
刪除修復(fù)分支:
$ git branch -d hotfix-1.2.1
總結(jié)
以上就是這篇文章的主要內(nèi)容直撤,原文作者充分利用了git的諸多優(yōu)勢(shì)非竿,為我們提供了一種優(yōu)雅的版本管理模型,希望能夠?qū)Υ蠹矣兴鶐椭笔U恼氯绻腥魏畏g解釋不到位的地方红柱,還請(qǐng)各位指出,謝謝蓖乘。最后锤悄,附上整個(gè)分支模型的示意圖,感謝閱讀嘉抒。 :)