一個成功的Git分支模型

jopen 10年前發布 | 15K 次閱讀 Git 版本控制系統


下午看到一篇介紹Git工作模型的文章,覺得很不錯。為了方便大家快速掌握文章的內容,這里對這篇文章的要點進行簡單的介紹

原文地址: http://nvie.com/posts/a-successful-git-branching-model/

為何使用Git

關于Subversion和Git的優劣比較有很多的文章已經進行了比較詳細的介紹,這并不是這篇文章的重點。但是Git的一些優勢卻是這種模型的基礎,因此對于這一部分應當進行必要的介紹。

分支

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而言,有一個顯著的優勢就是對分支的使用非常的方便。在Git中,分支的使用是非常鼓勵和推薦的,因此在《Pro Git》中把分支的使用是作為基礎章節來介紹的,也就是說分支是Git中經常會用到的操作。而本文所介紹的這種模型,就是建立在對分支頻繁操作(創建,切換,合并等)的基礎上的。

非集中式

非集中式的版本控制系統是Git的另一大優勢。這就表示,在使用Git的時候,每一次代碼的提交都不必同步到遠程服務器中,開發人員可以在外部網絡環境(無法連接內網),甚至離線的情況下進行代碼的版本控制。作為非集中式的版本控制系統,開發人員可以在本地創建分支而不必同步到服務器上,這一點是構成文中Git分支模型的另一大基礎。

主分支(Main Branch)

在Git分支模型中存在兩個主分支,這兩個分支是不可或缺的:

  • master分支

  • develop分支

master分支

master作為Git中默認的主分支,是使用Git的開發者們非常熟悉的默認主分支名稱。在Git分支開發模型中,master分支的HEAD節點始終處于“準備好進行生產的狀態”,即master分支的HEAD節點所指向的版本始終是可以用于生產環境的正式版本。當其他分支的代碼版本合并到master分支時(隨后打上版本標簽),通常意味著一個新的正式版本已經發布。該過程的具體介紹詳見后文。

develop分支

develop分支作為另一個主分支,其HEAD節點總是指向下一個待發布版本的最新變化。develop分支的版本變更通常來源于輔助分支的合并(稍后介紹),因為develop分支也常被稱為“整合分支”。當develop分支達到某一穩定點,可進行新版本的發布時,develop分支上的所有變更應該被合并到master分支并打上tag標簽,該過程詳見后文。

輔助分支(Supporting Branch)

除了master分支和develop分支這兩個主分支以外,Git分支模型中擁有一些“輔助分支”,在團隊開發中對develop分支和master分支進行幫助,例如對新需求的研發,新版本發布前的準備工作以及新版本bug的緊急修復等。和主分支不同的是,這些分支的生命周期都是很有限的,最終都將會被刪除。輔助分支中有以下三類分支:

  • 需求分支(Feature Branch)
  • 發布分支(Release Branch)
  • 修復分支(Hotfix Branch)

上述三種輔助分支,每一種都有其特定的功能,并遵守各自嚴格的規則,例如分支的輸入分支、分支的輸出(合并)分支等等。下文將逐一描述。

需求分支(Feature Branch)

分支來源:develop分支

分支去向:develop分支

分支命名:任意名稱,除master,develop,以“release-”開頭,以“hotfix-”開頭的分支以外。

需求分支用于為未來的軟件版本開發新的功能需求。當進行一個需求的研發時,該需求將被整合進正式版本是未知,所以需要單獨創建分支對該需求進行研發,只要該需求尚在開發中,該需求分支就會一直存在。需求分支最終會被合并到develop分支中作為下一個待發布版本的功能之一,或者由于該需求無法實現從而被拋棄。

注:需求分支通常僅僅存在于開發者的代碼倉庫中(本地倉庫),并不上傳到遠程分支。

如何創建需求分支

創建需求分支時,該分支必須從develop分支得到:

$ git checkout -b feature_branch develop

該命令從develop分支創建一個新的分支“feature_branch”,并從當前分支切換到“feature_branch”分支,相當于:

$ git branch feature_branch develop
$ git checkout feature_branch

將已完成的需求分支合并到develop分支

已完成的需求分支需要被合并到develop分支,作為待發布版本的需求之一:

$ 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方式,也會創建一個新的commit節點。

關于fast forward

當前分支合并到另一分支時,如果沒有分歧解決,就會直接移動文件指針。這個過程叫做fast forward。

例如,開發一直在master分支進行,但忽然有一個新的想法,于是新建了一個develop的分支,并在其上進行一系列提交,完成時,回到 master分支,此時,master分支在創建develop分支之后并未產生任何新的commit。此時的合并就叫fast forward,如下圖:

一個成功的Git分支模型

git merge develop

可以看到master在合并develop分支的時候并沒有產生新的節點

回到develop分支,對代碼進行修改,提交。切換到master分支,使用git merge develop --no-ff 進行合并,此時會產生一個commit節點,如下圖:

一個成功的Git分支模型

git merge checkout --no-ff

刪除分支develop后,如下圖:

一個成功的Git分支模型

刪除develop分支后

很明顯使用--no-ff合并時,在刪除develop分之后,該分支的合并信息仍然被保留,在以后的代碼分析中可以便捷的查看到歷史信息,而fast forward方式則無法辨識代碼的合并信息。正如原文所說:

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.

發布分支(Release Branch)

分支來源:develop分支

分支去向:develop分支和master分支

分支命名:以"release-"開頭

發布分支用于輔助新版本(生產環境)發布的準備工作,例如小bug的修復,或者版本號的修改等等。使用發布分支的好處是,當從develop分支中創建發布分支以后,develop分支便可以進行新版本之后需求的研發工作,從而既不會影響到最新的研發進度,也不會影響到新版本的發布。

創建發布分支

發布分支以develop分支作為源分支。例如,目前develop分支上的所有需求將作為版本1.2發布,這時可以創建一個分支"release-1.2"。此時可以繼續在develop分支上進行新需求的研發,而1.2版本的發布工作將由“release-1.2”分支來完成:

$ git checkout -b release-1.2 develop #創建并切換到"release-1.2"分支
$ vim file #表示對版本號的修改,或者小bug的修復等
$ git commit -a -m "更新版本至1.2" #提交代碼

注: 如果在發布分支進行小型bug的修改,則需要將提交后的代碼合并到develop分支中

完成發布分支

當發布分支完成代碼的提交(如果修復過bug,則要合并到develop分支)后,需要將發布分支合并到master分支上,并進行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

完成合并操作以后,刪除該發布分支:

$ git branch -d release-1.2

修復分支(Hotfix Branch)

分支來源:master分支

分支去向:develop分支和master分支

分支命名:以"hotfix-"開頭

修復分支用于正式版本的緊急修復,在緊急修復完成以后 必須同時被合并到master分支和develop分支 ,這是修復分支和發布分支不同之處(二者的來源也不同),和發布分支類似,修復分支在修復bug,提交,被合并以后,也要進行tag操作。

創建修復分支

$ git checkout -b hotfix-1.2.1 master
$ vim file #表示修復bug
$ git commit -a -m "修復bug"
$ vim file #表示更新版本號
$ git commit -a -m "版本更新為1.2.1"

完成修復分支

$ git checkout master
$ git merge --no-ff hotfix-1.2.1
$ git tag -a 1.2.1 #tag操作

不要忘記合并修復分支到develop分支

$ git checkout develop
$ git merge --no-ff hotfix-1.2.1

刪除修復分支:

$ git branch -d hotfix-1.2.1

總結

以上就是這篇文章的主要內容,原文作者充分利用了git的諸多優勢,為我們提供了一種優雅的版本管理模型,希望能夠對大家有所幫助。整篇文章如果有任何翻譯解釋不到位的地方,還請各位指出,謝謝。最后,附上整個分支模型的示意圖,感謝閱讀。 :)

一個成功的Git分支模型
image
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!