gitlab 删除分支_初识gitlab工作流
git對(duì)我來(lái)說(shuō)挺難理解的,平時(shí)遇到問(wèn)題也是繞著走,倒也沒(méi)啥大問(wèn)題,但基于git軟件的工作流卻很重要,尤其對(duì)于一個(gè)組織來(lái)說(shuō)。
git工作流、github工作流、gitlab工作流都屬于特性分支(feature branches)的類別,今天主要理解gitlab工作流,它結(jié)合了特性驅(qū)動(dòng)開(kāi)發(fā)、特性分支、issuse跟蹤。
1:git工作流的問(wèn)題
git工作流比較古老,最大的問(wèn)題是太復(fù)雜,它包含master、develop分支,還包含了features、releases、hotfixes分支。
它從develop分支開(kāi)始,然后移動(dòng)到release分支,最終合并到master分支。
它有兩個(gè)最大的問(wèn)題:第一個(gè)問(wèn)題就是必須從develop分支開(kāi)始(而不是master分支,master is reserved for code that is released to production),這有點(diǎn)反人類,約定俗成大部分工具都是從master分支開(kāi)始的。
第二個(gè)問(wèn)題就是它引入了hotfixes和release分支,現(xiàn)在大部分組織都是基于master做CD(即master分支是可以直接部署的),而對(duì)于CD持續(xù)交付來(lái)說(shuō),是沒(méi)有hotfixes和release分支概念的,也不建議引入一些規(guī)范(比如將代碼合并回release分支),另外也會(huì)經(jīng)常犯錯(cuò)(比如把代碼合并到master,但沒(méi)有合并到develop分支)。
總之git工作流太復(fù)雜了,其實(shí)我也沒(méi)理解。
2:github工作流
非常簡(jiǎn)單,就兩個(gè)分支(master和features),要做的就是將features發(fā)送PR到master,提倡頻繁部署,減少未發(fā)布的代碼,良好踐行精益開(kāi)發(fā)和持續(xù)集成這些最佳實(shí)踐。
什么意思呢?就是鼓勵(lì)你盡可能的合并到master(代表可以部署了),這個(gè)工作流在github上沒(méi)有問(wèn)題,但對(duì)于一個(gè)組織來(lái)說(shuō),它還有很多問(wèn)題沒(méi)有解決,比如說(shuō)部署、多環(huán)境、發(fā)布、issues這些問(wèn)題(部署和發(fā)布不是一個(gè)概念,部署針對(duì)于代碼部署,發(fā)布針對(duì)于用戶)。
那如何解決呢?gitlab來(lái)了,它不僅僅是一個(gè)git管理工具,更包含一整套的工作流方法。
3:gitlab工作流之生產(chǎn)分支
gitlab工作流有三個(gè)變種,先說(shuō)生產(chǎn)分支。
github工作流假設(shè)一旦你將feature分支合并到master后就可以部署了,但現(xiàn)實(shí)并不是如此,因?yàn)楦鞣N原因并不能精準(zhǔn)控制release時(shí)間,比如說(shuō)IOS審核,你將代碼合并到master的時(shí)候其實(shí)整個(gè)服務(wù)還沒(méi)有release;再比如release時(shí)間是固定的,但merge時(shí)間可能并不是release時(shí)間點(diǎn)。
那怎么保障merge時(shí)刻的代碼就是真正要發(fā)布的代碼呢?同時(shí)又不影響持續(xù)集成,其實(shí)merge后,可以將master分支合并到生產(chǎn)分支。
通過(guò)這樣的工作流,如果想看線上代碼是什么,可以直接查看生產(chǎn)分支;如果想精確知曉release時(shí)間,還可以基于生產(chǎn)分支打一個(gè)tag。
有一個(gè)問(wèn)題,master是可以持續(xù)集成了,生產(chǎn)分支也打出來(lái)了,但還沒(méi)到發(fā)布時(shí)間,這時(shí)候突然有個(gè)bug,開(kāi)發(fā)人員基于master創(chuàng)建出一個(gè)特性分支(其實(shí)已經(jīng)包含了未發(fā)布的代碼),修復(fù)后要緊急上線,怎么辦?
第一可以直接將master合并到生產(chǎn)分支發(fā)布修復(fù)代碼;第二可以pick出修復(fù)的代碼(特性分支)到生產(chǎn)分支,
必須記住,代碼在master上就表示可以發(fā)布了(也許要做特性開(kāi)關(guān))。
4:gitlab工作流之環(huán)境分支
在真實(shí)的世界,每個(gè)分支對(duì)應(yīng)于基礎(chǔ)設(shè)施的環(huán)境(環(huán)境和分支的名稱不一樣),比如master分支對(duì)應(yīng)于staging環(huán)境,pre-production分支對(duì)應(yīng)于仿真環(huán)境,production分支對(duì)應(yīng)于線上環(huán)境。
如果想在仿真測(cè)試,將master合并到pre-production分支;仿真測(cè)試沒(méi)問(wèn)題后,再將pre-production分支合并到production分支上。
這種基于下行的工作流(This workflow, where commits only flow downstream)確保每個(gè)環(huán)境的代碼都是經(jīng)過(guò)測(cè)試的。
假如要修復(fù)一個(gè)bug,cherry-pick一個(gè)hotfix提交,通常的做法就是(從master還是production)創(chuàng)建一個(gè)feature分支,然后合并到master,此時(shí)先不要?jiǎng)h除feature分支,測(cè)試通過(guò)后,再將master合并到其它分支(當(dāng)然也可以提交一個(gè)MR到其他任何的downstream分支)。
我們的工作流有點(diǎn)類似環(huán)境分支,因?yàn)橐_保master分支是真正意義上可部署的,但開(kāi)發(fā)環(huán)境的代碼只是開(kāi)發(fā)人員自己測(cè)試,沒(méi)有把握直接merge到master,所以在master分支前還有一個(gè)qa分支,qa分支由測(cè)試人員測(cè)試,有幾點(diǎn)變化:
qa環(huán)境測(cè)試通過(guò)基本代表可發(fā)布
其他特性分支統(tǒng)一合并到qa做測(cè)試(而非master)
并不是將qa分支合并到master分支,而是qa測(cè)試通過(guò)后,將特性分支合并到master分支,master分支和qa分支是隔離的(這可能會(huì)有問(wèn)題)。
同理到production分支,不是master分支合并到production分支,也不是qa分支合并到production分支,而是基于特性分支合并到production分支。
對(duì)于共享的特性分支來(lái)說(shuō),盡量減少提交到遠(yuǎn)端,或者動(dòng)不動(dòng)就合并到qa,這是我們現(xiàn)在比較大的一個(gè)問(wèn)題(開(kāi)發(fā)和測(cè)試都在qa分支上)。
以上還需要理解的更透徹一些。
5:gitlab工作流之發(fā)布分支
這種工作流可能在互聯(lián)網(wǎng)公司并不常見(jiàn),這種場(chǎng)景下,每個(gè)分支包含一個(gè)版本號(hào)(比如2-3-stable, 2-4-stable)。
這些分支基于master,而且盡可能晚一點(diǎn)merge到發(fā)布分支,因?yàn)闇p少了bug修復(fù)的merge。一般情況下,只有非常嚴(yán)重的bug才會(huì)再發(fā)布一個(gè)版本,具體的做法是先合并到master,然后再cherry-pick到發(fā)布分支,這樣在后續(xù)的版本中就不會(huì)遇到相同的bug了,先merge到master再pick到release這種做法叫做upstream first策略,google和red hat就是這么做的。
在release分支中修復(fù)一個(gè)bug后,也會(huì)打一個(gè)tag并增加版本號(hào)。
6:Merge/pull requests
這兩個(gè)詞是由git管理應(yīng)用程序(比如gitlab和github)創(chuàng)建的,github上叫做pull request(因?yàn)榈谝粋€(gè)步驟是pull特性分支),gitlab叫做merge request(因?yàn)樽詈笠粋€(gè)動(dòng)作是合并特性分支)。
在特性分支工作了幾個(gè)小時(shí),為了分享工作成果,可以創(chuàng)建一個(gè)MR給任何人(也可以@某個(gè)人),這個(gè)動(dòng)作表示該請(qǐng)求并不是為了merge(標(biāo)題以[WIP]開(kāi)頭),而是希望得到反饋或code review。
團(tuán)隊(duì)成員能夠?qū)R進(jìn)行評(píng)論,如果發(fā)現(xiàn)問(wèn)題,任何人(一般是MR發(fā)起者)發(fā)送一個(gè)fix push,這個(gè)MR會(huì)立刻更新。
如果準(zhǔn)備將這個(gè)特性分支合并到master,一般將這個(gè)MR發(fā)給具有一定權(quán)限的人,他可以選擇merge或者直接關(guān)閉MR。
在gitlab中,一般會(huì)保護(hù)長(zhǎng)期存在的分支(比如master),所以開(kāi)發(fā)人員一般不會(huì)直接修改該分支,只有特定權(quán)限的人才能merge到master分支。
合并完成后,一般會(huì)刪除特性分支,確保gitlab上的分支大部分都是處于工作狀態(tài)的,另外再開(kāi)一個(gè)相同名的分支也不會(huì)出現(xiàn)問(wèn)題。
7:Issue跟蹤
gitlab工作流可以讓issue和代碼之間的關(guān)系更加透明。
任何的代碼修改都來(lái)源于一個(gè)issue(可能是bug,也可能是需求),并盡量讓特性分支范圍小一點(diǎn)。
在寫(xiě)代碼的時(shí)候,根據(jù)issue創(chuàng)建一個(gè)分支(名字和issue編號(hào)有關(guān),比如15-require-a-password-to-change-it),解決后發(fā)送MR,merge成功一般會(huì)產(chǎn)生一個(gè)合并提交(不產(chǎn)生Fast-Forward)。
8:從MR中l(wèi)ink或關(guān)閉 issue
發(fā)送MR的時(shí)候,“Fixes #16” ,一方面表示關(guān)聯(lián)issue,另外合并成功過(guò)后會(huì)自動(dòng)關(guān)閉該issue。
9:通過(guò)rebase壓縮commit
在git中,能夠使用交互式的rebase(rebase -i)將多個(gè)請(qǐng)求合并為一個(gè)(代表完成一個(gè)功能)或重新排序,這個(gè)功能很有用。
但如果你的提交已經(jīng)提交到遠(yuǎn)程倉(cāng)庫(kù)(相同的分支還有其他開(kāi)發(fā)者),則必須禁止rebase,因?yàn)閞ebase會(huì)產(chǎn)生新的commit(就是commit id會(huì)變化),從而導(dǎo)致合并沖突,因?yàn)橄嗤淖兓胁煌腸ommit id;也會(huì)導(dǎo)致合并錯(cuò)誤,因?yàn)閷?duì)于工作在相同分支上的人來(lái)說(shuō),他們的git歷史和你的提交并不匹配。
如果rebase已經(jīng)同步到遠(yuǎn)端的分支,對(duì)于作者和其他合作者都會(huì)很麻煩,一些人已經(jīng)review過(guò)代碼了,但rebase會(huì)讓人很難知道上次review后發(fā)生了什么。
由于我們現(xiàn)在很多人在一個(gè)分支上開(kāi)發(fā),會(huì)經(jīng)常遇到同一個(gè)分支merge的問(wèn)題,建議不要使用rebase -i或rebase合并(需要進(jìn)一步理解),而使用merge(雖然會(huì)導(dǎo)致git歷史不太好看)。
如果合并的時(shí)候有很多提交,恢復(fù)的時(shí)候比較難,可以通過(guò)gitlab的Squash-and-Merge功能,就是在合并的時(shí)候壓縮為一個(gè)提交。另外還有一個(gè)簡(jiǎn)單辦法可以撤銷(revert)所有的提交,就是總是使用“no fast-forward” (—no-ff) 策略。
這個(gè)工作流在工作中很常見(jiàn),需要仔細(xì)體會(huì)。
10:減少在特性分支上進(jìn)行merge操作
如果一個(gè)分支上有很多merge提交,會(huì)讓git歷史記錄很混亂,所以應(yīng)該盡量避免在特性分支上進(jìn)行merge操作。
通常在master分支上如果有新的提交,建議通過(guò)rebase重新排序或合并commit,從而避免merge操作(Often, people avoid merge commits by just using rebase to reorder their commits after the commits on the master branch)。題外音,很少會(huì)在master上提交。
在特性分支上,如果需要同步master的操作,應(yīng)該使用rebase master,盡量避免merge master,從而保持一個(gè)線性的提交。當(dāng)然上面也說(shuō)過(guò)了,如果你的分支已經(jīng)在遠(yuǎn)端和人分享了,應(yīng)該避免進(jìn)行rebase操作。
rebase操作會(huì)產(chǎn)生很多的工作,每次rebase的時(shí)候,會(huì)處理相同的沖突,而merge更合適,解決沖突只需要一次。
聽(tīng)了那么多,在本地開(kāi)發(fā)的時(shí)候建議rebase -i,在master的時(shí)候可以rebase,其他場(chǎng)景建議少用。
接下去回答為啥應(yīng)該減少在特性分支上進(jìn)行merge操作。一般情況下進(jìn)行在特性分支上進(jìn)行merge有三個(gè)原因。
(1)utilizing 新代碼,假如你想使用master上的一些新代碼(特性分支創(chuàng)建后產(chǎn)生的提交),可以使用cherry-picking一個(gè)commit。
(2)解決合并沖突,如果一個(gè)特性分支有很多開(kāi)發(fā)者,在更新代碼的時(shí)候比如會(huì)遇到?jīng)_突,所以合并也是合理的。
(3)同步master上的代碼
為了保證特性分支上的代碼較新(short-lived),有的時(shí)候會(huì)合并master上的代碼(有時(shí)候我經(jīng)常這么做),但其實(shí)應(yīng)該減少這樣的行為,大部分特性分支應(yīng)該小于一天的工作量(并不現(xiàn)實(shí),至少我沒(méi)見(jiàn)過(guò)),如果花費(fèi)很長(zhǎng)時(shí)間,建議將任務(wù)拆分的更小。
對(duì)于多余一天工作量的分支,有兩種策略保持代碼較新:
(1)將代碼merge到master做CI,CI/CD提倡自動(dòng)化測(cè)試,其實(shí)目前我們做不到,是不太敢直接提交到master分支,這種觀念很難扭轉(zhuǎn)過(guò)來(lái)。
(2)Another option is to only merge in from well-defined points in time, for example, a tagged release(沒(méi)理解)。
另外合并到master就代表引入了新功能,代表可以部署了,
有的時(shí)候特性分支經(jīng)常性合并到master做CI,雖然測(cè)試沒(méi)問(wèn)題,但可能功能還沒(méi)完成或不想暴露出來(lái),此時(shí)必須使用feature toggles隱藏未完成的測(cè)試。
總之,特性分支應(yīng)該盡量減少合并提交,但不要消除它們。codebase應(yīng)該保持干凈,但也要記錄實(shí)際發(fā)生的情況(歷史記錄很重要)。
這個(gè)工作流在工作中很常見(jiàn),需要仔細(xì)體會(huì)。
11:commit信息應(yīng)該有意義
commit不僅僅是提交代碼,還要體現(xiàn)出意圖,所以少用fix,improve這樣的字眼。
12:合并之前要測(cè)試
一般情況下,特性分支會(huì)做CI持續(xù)集成,測(cè)試通過(guò)才會(huì)發(fā)送MR,這個(gè)是沒(méi)有問(wèn)題的,但有個(gè)問(wèn)題,只測(cè)試特性分支而沒(méi)有測(cè)試merge后的代碼。
也就是說(shuō)merge后還要再測(cè)試一次,看上去很浪費(fèi)時(shí)間。
但其實(shí)如果合并沒(méi)有沖突,特性分支合并到master的風(fēng)險(xiǎn)是可控的,如果有沖突,應(yīng)該將master代碼merge到特性分支重新進(jìn)行測(cè)試,測(cè)試通過(guò)后,再merge到master。
13:在特性分支上進(jìn)行工作
一般情況下,初始化一個(gè)feature分支時(shí)總是從最新的master分支(upstream分支)拉取的代碼。
假如已經(jīng)知道你的分支依賴別的分支,則可從該依賴分支拉取代碼。
如果特性分支需要合并到別的分支,那么需要在merge commit的信息中寫(xiě)清楚原因。
如果還沒(méi)有把特性分支的commit提交的遠(yuǎn)程庫(kù),那么可以rebase master或其他分支(這樣歷史信息更有用)。
如果代碼正常工作且不需要合并,那么就不要再一次merge upstream分支,Merging only when needed prevents creating merge commits in your feature branch that later end up littering the master history.
參考:https://docs.gitlab.com/ee/topics/gitlab_flow.html
總結(jié)
以上是生活随笔為你收集整理的gitlab 删除分支_初识gitlab工作流的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: qiankun 微前端_qiankun
- 下一篇: hdfs读写流程_一文读懂HDFS分布式