git官方文檔中,將分支分爲了兩大類,後續介紹的分支管理策略都是基於這個分類進行拓展的。html
在整個項目開發週期的不一樣階段,按期把某些主題分支合併入其餘長期分支中。這些長期分支大概分爲三種類型:git
(1)分支上的代碼達到穩定狀態,多是已經發布了的或即將要發佈。例如master分支。github
(2)還有一些名爲develop或next的平行分支,用來作後續開發或測試穩定性,當這些分支達到穩定狀態就能夠合併入master分支。web
(3)還有一些proposed分支,可能包含一些不成熟的內容,當他們具備必定程度的穩定性後,再合併入更高穩定性的分支。shell
穩定性越高的分支,在代碼提交歷史中指針越靠後: bash
主題分支是一種短時間分支,用來實現單一特性或其相關工做。可能會被頻繁建立、使用、合併、刪除。這樣有利於快速而且完整地進行上下文切換,將工做分散到不一樣的流水線中,每一個流水線的分支都僅與其目標特性相關,在作代碼審查的時候能更加容易地看出你作了哪些改動。markdown
git-flow模型是Vincent Driessen在2010年提出的經典模型。他將分支分爲了幾種不一樣類型,每種類型都有明確的職責。併發
有兩個常駐分支:master和develop。ide
master分支中的最新代碼永遠都是能夠發佈到生產環境的穩定狀態。oop
develop分支中的最新代碼永遠反映了最新的變化,爲下一次發佈作準備。有些人也把這個分支叫作集成分(integration branch),這是構建任何夜間自動構建的地方。
當develop分支中的代碼達到穩定狀態並準備發佈時,須要合併到master,而後打上tag來標記發佈的版本號。 所以,每次變化合並進master分支時,也就是新版本發佈的時候。
支持分支的生命週期較短,而且最終會被刪除。主要用來幫助團隊成員之間進行並行開發,簡化功能跟蹤,爲產品發佈作準備並協助快速解決生產中的實際問題。
一般使用三種類型的支持分支:
這些分支中的每個都有特定的用途,並受嚴格的規則約束。 這些分支並無技術層面上的差異,只是根據咱們的使用方式進行了分類。
feature分支一般用來開發新的feature,最終會合並回到develop分支中或廢棄掉。
功能分支一般僅存在於開發人員的本地倉庫中,而不存在於origin中。
建立一個feature分支: $ git checkout -b myfeature develop
feature分支開發完成後須要合併回develop分支:
$ git checkout develop $ git merge --no-ff myfeature $ git branch -d myfeature $ git push origin develop 複製代碼
--no-ff
會建立一個合併的commit,來記錄這一次的合併分支信息;若是不加該參數,合併分支的時候不會再有合併的commit。
release分支爲一次新的版本發佈作準備,這個階段主要進行最後的檢查、小的bug修復,併爲發佈準備元數據(版本號、構建日期等)。
當develop分支近乎達到了新版本發佈的指望狀態,就能夠從中建立一個新的release分支了,此時全部新版本要發佈的功能都已經合併進develop。其餘將來發布版本的功能必須等到這次release分支建立後,才能夠合併進develop分支。
建立release分支時,肯定了即將發佈的版本號。例如當前版本是1.1.5,假以下一次是比較大的版本發佈,因此release分支能夠命名爲release-1.2。
$ git checkout -b release-1.2 develop $ ./bump-version.sh 1.2 $ git commit -a -m "Bumped version number to 1.2" 複製代碼
當建立完release分支時,咱們升級了版本號。在這裏,bump-version.sh是一個虛構的shell腳本,它更改工做副本中的一些文件以反映新版本。(固然,也能夠手動更改)而後,提交升級後的版本號。
這個新分支會一直存在,直到最終發佈,在此期間只容許bug修復,禁止添加大的新功能。當release分支的狀態達到能夠發佈的程度時,就合併進master分支。而後在master分支上的commit打上tag,來記錄版本號,方便未來回滾或追溯。最後,release分支上的改動還要合併回develop分支。在合併回develop分支的時候可能會出現衝突,由於develop分支可能合併了一些新的feature,這時須要解決衝突並提交。
$ git checkout master $ git merge --no-ff release-1.2 $ git tag -a 1.2 $ git checkout develop $ git merge --no-ff release-1.2 複製代碼
在打tag的時候還可使用-s或-u 標誌來對tag進行加密簽名。
最後能夠刪除這個release分支了。
$ git branch -d release-1.2 複製代碼
當生產版本出現了一個嚴重的bug必需要馬上修復時,能夠從當前master分支上建立一個hotfix分支來修復bug。
例如當前版本號爲1.2的生產環境中出現了一個嚴重的bug急需修復,能夠建立一個hotfix-1.2.1分支。
$ git checkout -b hotfix-1.2.1 master $ ./bump-version.sh 1.2.1 $ git commit -a -m "Bumped version number to 1.2.1" 複製代碼
git commit -a -m
合併了 git add
和 git commit
兩個步驟。
修復bug並提交:
$ git commit -m "Fixed severe production problem" 複製代碼
修復完,這些bugfix須要合併進master,同時還須要合併回develop。
$ git checkout master $ git merge --no-ff hotfix-1.2.1 $ git tag -a 1.2.1 $ git checkout develop $ git merge --no-ff hotfix-1.2.1 複製代碼
若是這時還有一個release分支同時存在,那麼hotfix分支就不須要合併回develop分支,而是合併到release分支,由於release分支最終仍是回合並回develop分支。但若是這個bug會影響到develop分支上的開發,則能夠合併到develop分支。
最後,刪除hotfix分支。
$ git branch -d hotfix-1.2.1 複製代碼
做者在2020年3月5日對該模型又作了一些說明:因爲gitflow-model更適合多個版本並存的場景,但現現在的web應用不多會須要多版本並存,更多的是一個版本持續交付,所以推薦使用更簡單的模型,例如GitHub flow。
優勢:各分支權責分明,清晰可控,是不少分支管理策略的啓蒙模型。
缺點:
GitHub flow是一個輕量級的、基於分支的工做流。是 Github 使用的工做流程。 它只保留一個主分支master,開發新功能時基於master建立一個feature分支,開發完成後發起Pull-Request。小組內進行討論和評審,並及時反饋,開發者在此期間能夠不斷提交代碼。評審經過後再合併回master分支,並進行部署。
優勢:
缺點:master分支發佈前,其餘代碼沒法提交,不然master分支就會與剛發佈的版本不一致。
吸收了Git flow 與 Github flow和優勢,Gitlab推薦的作法,具體可見阮一峯老師的這篇文章,此處再也不贅述。
存在一個分支做爲主幹分支,即master分支,開發人員直接向主幹分支提交代碼,或將feature分支只留在本地。原則上,代碼倉庫就只有一個master分支了。開發團隊成員能夠一天內屢次將代碼提交到主幹分支,使團隊的工做在24小時內就能夠被整合,保證了代碼版本隨時處於可發佈的狀態。避免長期存在多個分支,有利於持續集成和持續交付。
發佈時直接從主幹分支上建立release分支,並打上tag,發佈完成後刪除release分支。換句話說,發佈分支是主幹分支某個時點的快照。
主幹開發要求每次提交都是一個可上線的版本,所以也帶來了一些問題,下面給出相應的解決方案:
AoneFlow是阿里內部使用的代碼分支管理策略,「它基本上兼顧了 TrunkBased 的‘易於持續集成’和 GitFlow 的‘易於管理需求’特色,同時規避掉 GitFlow 的那些繁文縟節」。
AoneFlow 只使用三種分支類型:主幹分支、特性分支、發佈分支。一個完整的流程以下: