參考資料
介紹一個(gè)成功的 Git 分支模型
Git分支管理策略
簡(jiǎn)介
規(guī)范的分支管理策略可以使得版本庫(kù)的演進(jìn)保持簡(jiǎn)潔纵势,主干清晰,各個(gè)分支各司其職管钳、井井有條钦铁。
常駐分支
整個(gè)版本庫(kù)中應(yīng)該有兩個(gè)一直演進(jìn)的常駐分支,分別是 master 和 develop才漆。
master
主分支上的代碼提交都是處于可發(fā)布狀態(tài)的牛曹,是所有提供給用戶使用的正式版本。我們使用版本庫(kù)初始化時(shí)默認(rèn)創(chuàng)建的 master 分支醇滥。
develop
主分支只用來(lái)發(fā)布版本黎比,日常的工作都應(yīng)該提交到開發(fā)用的 develop 分支。該分支 HEAD 源碼始終體現(xiàn)下個(gè)發(fā)布版的最新軟件變更鸳玩。當(dāng) develop 分支的源碼到達(dá)了一個(gè)穩(wěn)定待發(fā)布狀態(tài)時(shí)阅虫,就可以合并到 master 分支中。
輔助分支
除了常駐分支外不跟,開發(fā)流程中還需要各種輔助性分支颓帝,用來(lái)支持團(tuán)隊(duì)成員們并行開發(fā),使功能易于追蹤窝革,協(xié)助生產(chǎn)發(fā)布環(huán)境準(zhǔn)備购城,以及快速修復(fù)實(shí)時(shí)在線問題。與常駐分支不同聊闯,輔助分支的生命期是有限的工猜,當(dāng)它們的提交被合并到常駐分支后,就會(huì)被移除菱蔬。輔助分支包括:feature、fix、release 和 hotfix拴泌。
feature
feature 分支從 develop 分支分出魏身,為了實(shí)現(xiàn)某個(gè)特定的功能,并最終合并到
develop 分支中蚪腐。
fix
fix 分支從 develop 分支分出箭昵,為了修復(fù)測(cè)試過(guò)程中發(fā)現(xiàn)的某個(gè) bug ,并最終合并到 develop 分支中回季。
release
在 develop 分支達(dá)到了發(fā)布的理想狀態(tài)時(shí)家制,就分出一個(gè) release 分支。release 分支是為新版本的發(fā)布做準(zhǔn)備的泡一,它允許我們?cè)谧詈髸r(shí)刻做一些細(xì)小的修改颤殴,如一些 bug 的修改和準(zhǔn)備發(fā)布元數(shù)據(jù)(版本號(hào)等)。在確定發(fā)布后鼻忠,就將 release 分支合并到 master 分支和 develop 分支涵但,并移除 release 分支。
hotfix
hotfix 分支與 release 分支相似帖蔓,他們都為新的生產(chǎn)環(huán)境發(fā)布做準(zhǔn)備矮瘟,盡管這是未經(jīng)計(jì)劃的。當(dāng)生產(chǎn)環(huán)境發(fā)現(xiàn) bug 且必須馬上修復(fù)時(shí)塑娇,從 master 分支分出 hotfix 分支澈侠,在修復(fù)提交后,將 hotfix 分支合并到 master 分支和 develop 分支埋酬,并移除 hotfix 分支埋涧。
工作流程
開發(fā)人員通過(guò) issue 列表獲取新功能開發(fā)任務(wù),然后從 develop 分支分出 feature_[issue number] 分支奇瘦,在新功能開發(fā)完成后棘催,將 feature_[issue number] 分支合并到 develop 分支,并將其移除耳标。
git checkout -b feature_[issue number] develop
git checkout develop
git merge --no-ff feature_[issue number]
git branch -d feature_[issue number]
在新功能被測(cè)試后醇坝,開發(fā)人員通過(guò) issue 列表獲取修復(fù) bug 的任務(wù),然后從 develop 分支分出 fix_[issue number] 分支次坡,在修復(fù)工作完成后呼猪,將 fix_[issue number] 分支合并到 develop 分支,并將其移除砸琅。
git checkout -b fix_[issue number] develop
git checkout develop
git merge --no-ff fix_[issue number]
git branch -d fix_[issue number]
待新功能穩(wěn)定將要發(fā)布時(shí)宋距,從 develop 分支分出 release_[version number] 分支,version number 是將要發(fā)布的版本號(hào)症脂,在確定 release_[version number] 分支上不會(huì)有其他改動(dòng)后谚赎,就可以將其合并到 develop 分支和 master 分支淫僻,并移除。在 master 分支的新提交點(diǎn)上添加版本號(hào) tag壶唤。
git checkout -b release_[version number] develop
git checkout master
git merge --no-ff release_[version number]
git tag -a v[version number]
git checkout develop
git merge --no-ff release_[version number]
git branch -d release_[version number]
如果生產(chǎn)環(huán)境發(fā)現(xiàn) bug 且必須馬上修復(fù)時(shí)雳灵,從 master 分支分出 hotfix_[version number] 分支,在修復(fù)提交后闸盔,將 hotfix_[version number] 分支合并到 master 分支和 develop 分支悯辙,并移除 hotfix_[version number] 分支。在 master 分支的新提交點(diǎn)上添加版本號(hào) tag迎吵。
git checkout -b hotfix_[version number] master
git checkout master
git merge --no-ff hotfix_[version number]
git tag -a v[version number]
git checkout develop
git merge --no-ff hotfix_[version number]
git branch -d hotfix_[version number]
關(guān)于 merge 命令中的--no-ff
參數(shù)躲撰,即使該操作可以快進(jìn)式合并(fast-farward),但仍然會(huì)采用正常合并击费,在分支上生成一個(gè)新的節(jié)點(diǎn)拢蛋。這樣就不會(huì)丟失輔助分支的歷史信息,保證了版本演進(jìn)的清晰荡灾。
團(tuán)隊(duì)協(xié)作開發(fā)
大部分的軟件開發(fā)工作都不是由一個(gè)人獨(dú)立完成的瓤狐,而是需要一個(gè)團(tuán)隊(duì)協(xié)作完成。一般我們需要在服務(wù)器端搭建一個(gè)中心代碼庫(kù)批幌,而團(tuán)隊(duì)中的成員都是通過(guò)本地代碼庫(kù)不斷的和中心代碼庫(kù)之間實(shí)現(xiàn)拉取和推送代碼的操作來(lái)協(xié)作完成任務(wù)的础锐。
中心代碼庫(kù)可能只存在 master 和 develop 兩條常駐分支。其他的輔助分支荧缘,開發(fā)人員可以在任務(wù)完成后皆警,先并入本地的常駐分支,之后再推送到中心代碼庫(kù)來(lái)同步更新截粗。向中心代碼庫(kù)提交代碼時(shí)要注意的一點(diǎn)是信姓,一定要將本地的提交 rebase 到服務(wù)器端最新的提交之后再推送代碼,這樣可以避免不必要的合并分支節(jié)點(diǎn)绸罗,使演進(jìn)歷史更清晰意推。
一般團(tuán)隊(duì)中都會(huì)通過(guò)代碼審查來(lái)提高整個(gè)軟件的代碼健壯性。這時(shí)珊蟀,完成任務(wù)的開發(fā)者不能自己將輔助分支合并入常駐分支菊值,而要由審查人員在通過(guò)后將其并入。審查代碼的開發(fā)者可以直接從完成任務(wù)的開發(fā)者的本地版本庫(kù)拉取分支育灸,也可以通過(guò)讓完成任務(wù)的開發(fā)者將分支提交到中心代碼庫(kù)來(lái)獲取腻窒,但要在并入常駐分支后,將中心代碼庫(kù)中的輔助分支刪除磅崭。
為了使代碼提交歷史更加清晰儿子,可進(jìn)一步規(guī)范,將任務(wù)單元?jiǎng)澐值谋M量小砸喻,即每一個(gè)輔助分支最終在并入常駐分支時(shí)都只有一次提交柔逼。開發(fā)人員在完成任務(wù)前蒋譬,可根據(jù)需要執(zhí)行多次提交,但在合并入常駐分支時(shí)卒落,要通過(guò)rebase -i
命令將提交變?yōu)橐淮蜗鄄M瑫r(shí)要對(duì)提交信息的格式規(guī)范化蜂桶,如:
[功能輔助分支名][模塊名]:簡(jiǎn)短的描述信息[issue number]
在提交信息格式化后儡毕,每次將輔助分支合并入常駐分支時(shí),不需要使用--no-ff
參數(shù)扑媚,因?yàn)樘峤恍畔⑼耆梢哉f(shuō)明輔助分支的歷史腰湾,在去掉這些空的合并節(jié)點(diǎn)后,會(huì)使提交歷史更加簡(jiǎn)潔清晰疆股。
2020.02.10 更新:關(guān)于 iOS 項(xiàng)目分支管理的想法
當(dāng)前工作中费坊,iOS 應(yīng)用發(fā)布新版本的方式與 web 開發(fā)不同,需要通過(guò) Xcode 手動(dòng)歸檔旬痹,然后向 App store 提交附井,待審核通過(guò)后,才算是發(fā)版成功两残。在這種情況下永毅,無(wú)法利用鉤子自動(dòng)發(fā)布 master 分支上的代碼,那么其存在的意義就不大了人弓,考慮僅維護(hù) develop 一個(gè)常駐分支沼死。develop 分支保持著程序的最新可用狀態(tài),當(dāng)一部分開發(fā)工作完成后崔赌,develop 分支上的某次提交會(huì)作為對(duì)外發(fā)布的版本意蛀。當(dāng)然,需要人為控制的一點(diǎn)是健芭,必須注意并入的提交的順序县钥,不能讓下一版本的提交在本次版本的提交之前并入,否則就會(huì)把下一版本的內(nèi)容提前發(fā)布出去了慈迈。
當(dāng)確定了要發(fā)版的提交后若贮,假設(shè)發(fā)版的相關(guān)提交、可能出現(xiàn)的緊急修復(fù)的提交吩翻、下一版本的需求提交是按先后順序操作的兜看,那么僅需要 develop 分支就夠了,在對(duì)應(yīng)的提交打版本標(biāo)簽即可狭瞎。但現(xiàn)實(shí)中细移,很多時(shí)候情況并不是這樣的,發(fā)版的操作可能有一定的延后性熊锭,而需要緊急修復(fù)的 bug 的出現(xiàn)弧轧,更是具有不確定性雪侥。在確定了要發(fā)版的提交后,后續(xù)的工作會(huì)繼續(xù)進(jìn)行精绎,下一版本的需求提交就會(huì)開始并入 develop 分支中速缨,正是因?yàn)檫@樣,所以發(fā)版的提交或緊急修復(fù)的提交就不能直接并入 develop 分支了代乃,這會(huì)導(dǎo)致將下一版本的部分提交提前發(fā)布出去旬牲。
當(dāng)發(fā)版時(shí),我們需要在發(fā)版提交上新建 release 輔助分支搁吓,之后發(fā)版的相關(guān)提交在該分支上操作原茅,發(fā)布新版本后將 release 分支上新的提交并入到 develop 分支上,之后即可刪除 release 分支堕仔,而版本標(biāo)簽就應(yīng)該打在 release 分支的最后一次提交上擂橘。iOS 開發(fā)因?yàn)閷徍说膯栴},在將 release 分支的最新提交打包到 App store 審核時(shí)摩骨,發(fā)版工作并沒有完成通贞,還不能將 release 分支并入 develop 分支。假如審核未通過(guò)恼五,需要修改代碼昌罩,則在 release 分支上繼續(xù)進(jìn)行提交,因?yàn)檫@還是對(duì)同一個(gè)版本的發(fā)布唤冈,直到審核通過(guò)后峡迷,將 release 分支的提交并入 develop 分支。如果并入 release 分支時(shí)你虹,develop 分支上沒有下一版本的提交绘搞,那么快進(jìn)式合并則會(huì)使 release 分支的提交像需求提交一樣直接在開發(fā)分支的直線上,但為了與不能快進(jìn)合并的情況以及可能的緊急修復(fù)的情況統(tǒng)一傅物,并且可以更醒目地標(biāo)出發(fā)布的版本夯辖,合并時(shí)使用--no-ff
參數(shù),強(qiáng)制創(chuàng)建新的提交董饰。
對(duì)于緊急修復(fù)的操作蒿褂,如果主分支上沒有下一版本的提交,那么緊急修復(fù)完全可以當(dāng)做下一個(gè)版本來(lái)操作(因?yàn)?iOS 改動(dòng)一定要提交新版本)卒暂。而如果已經(jīng)有了下一版本的提交啄栓,則應(yīng)該在當(dāng)前版本對(duì)應(yīng)的提交(release 分支上的最后一次提交)上新建 hotfix 輔助分支,然后在該分支上提交修復(fù) bug 也祠、修改發(fā)版信息昙楚、可能的對(duì)審核未通過(guò)的修改。待針對(duì)緊急修復(fù)的新版本上架后诈嘿,將 hotfix 分支并入 develop 分支中堪旧,之后即可刪除 hotfix 分支削葱,版本標(biāo)簽應(yīng)該打在 hotfix 分支的最后一次提交上。