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