溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Git分支的策略以及對發(fā)布的管理的實(shí)例分析

發(fā)布時間:2021-10-21 09:18:02 來源:億速云 閱讀:122 作者:柒染 欄目:大數(shù)據(jù)

Git分支的策略以及對發(fā)布的管理的實(shí)例分析,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

展示我一年前在自己的項(xiàng)目中成功運(yùn)用的開發(fā)模型。我一直打算把這些東西寫出來,但總是沒有抽出時間,現(xiàn)在終于寫好了。這里介紹的不是任何項(xiàng)目的細(xì)節(jié),而是有關(guān)分支的策略以及對發(fā)布的管理。

Git分支的策略以及對發(fā)布的管理的實(shí)例分析

在我的演示中,所有的操作都是通過 git 完成的。

為什么選擇 git ?

為了了斷 git 和中心源代碼控制系統(tǒng)的比較和爭論,請移步這里看看 鏈接1 鏈接2。作為一個開發(fā)者,我喜歡 git 超過其它任何現(xiàn)有的工具。Git 真正改變了開發(fā)者對于合并和分支的認(rèn)識。在傳統(tǒng)的 CVS/SVN 里,合并/分支總是有點(diǎn)令人害怕的(“注意合并沖突,它們會搞死你的”)。

但是 git 中的這些操作是如此的簡單有效,它們真正作為你每天工作流程的一部分。比如,在 CVS/SVN 的書籍里,分支和合并總是最后一個章節(jié)的討論重點(diǎn)(對于高級用戶),而在每一本 git 的書里 鏈接1 鏈接2 鏈接3,這些內(nèi)容已經(jīng)被包含在第三章(基礎(chǔ))里了。

因?yàn)樗暮唵沃苯雍椭貜?fù)性,分支和合并不再令人害怕。版本控制工具比其它任何東西都支持分支/合并。

有關(guān)工具就介紹到這里,我們現(xiàn)在進(jìn)入開發(fā)模型這個正題。我要展現(xiàn)的模型本質(zhì)上無外乎是一個流程的集合,每個團(tuán)隊(duì)成員都有必要遵守這些流程,來達(dá)到管理軟件開發(fā)流程的目的。

分散但也集中

我們的分支模型中使用良好的代碼庫的設(shè)置方式,是圍繞一個真實(shí)的中心代碼庫的。注意,這里的代碼庫僅僅被看做是一個中心代碼庫(因?yàn)?git 是 DVCS,即分散版本控制系統(tǒng),從技術(shù)層面看,是沒有所謂的中心代碼庫的)。我們習(xí)慣于把這個中心代碼庫命名為 origin,這同時也是所有 git 用戶的習(xí)慣。

Git分支的策略以及對發(fā)布的管理的實(shí)例分析

每一位開發(fā)者都向 origin 這個中心結(jié)點(diǎn) pull 和 push。但是除此之外,每一位開發(fā)者也可以向其它結(jié)點(diǎn) pull 改變形成子團(tuán)隊(duì)。比如,對于兩個以上開發(fā)者同時開發(fā)一項(xiàng)大的新特性來說,為了不必過早向 origin 推送開發(fā)進(jìn)度,這就非常有用。在上面的這個例子中,Alice 和 Bob、Alice 和 David、Clair 和 David 都是這樣的子團(tuán)隊(duì)。

從技術(shù)角度,這無非意味著 Alice 定義一個名為 Bob 的 git remote,指向 Bob 的代碼庫,反之亦然。

主分支

Git分支的策略以及對發(fā)布的管理的實(shí)例分析

該開發(fā)模型的核心基本和現(xiàn)有的模型是一樣的。中心代碼庫永遠(yuǎn)維持著兩個主要的分支:

  • master

  • develop

在 origin 上的 master 分支和每個 git 用戶的保持一致。而和 master 分支并行的另一個分支叫做 develop。

我們認(rèn)為 origin/master 是其 HEAD 源代碼總是代表了生產(chǎn)環(huán)境準(zhǔn)備就緒的狀態(tài)的主分支。

我們認(rèn)為 origin/develop 是其 HEAD 源代碼總是代表了最后一次交付的可以趕上下一次發(fā)布的狀態(tài)的主分支。有人也把它叫做“集成分支”。該源代碼還被作為了 nightly build 自動化任務(wù)的來源。

每當(dāng) develop 分支到達(dá)一個穩(wěn)定的階段,可以對外發(fā)布時,所有的改變都會被合并到 master 分支,并打一個發(fā)布版本的 tag。具體操作方法我們稍后討論。

因此,每次改動被合并到 master 的時候,這就是一個真正的新的發(fā)布產(chǎn)品。我們建議對此進(jìn)行嚴(yán)格的控制,因此理論上我們可以為每次 master 分支的提交都掛一個鉤子腳本,向生產(chǎn)環(huán)境自動化構(gòu)建并發(fā)布我們的軟件。

支持型分支

我們的開發(fā)模型里,緊接著 master 和 develop 主分支的,是多種多樣的支持型分支。它們的目的是幫助團(tuán)隊(duì)成員并行處理每次追蹤特性、準(zhǔn)備發(fā)布、快速修復(fù)線上問題等開發(fā)任務(wù)。和之前的主分支不同,這些分支的生命周期都是有限的,它們最終都會被刪除掉。

我們可能會用到的不同類型的分支有:

  • feature 分支

  • release 分支

  • hotfix 分支

每一種分支都有一個特別的目的,并且有嚴(yán)格的規(guī)則,諸如哪些分支是它們的起始分支、哪些分支必須是它們合并的目標(biāo)等。我們快速把它們過一遍。

這些“特殊”的分支在技術(shù)上是沒有任何特殊的。分支的類型取決于我們?nèi)绾芜\(yùn)用它們。它們完完全全都是普通而又平凡的 git 分支。

feature 分支

Git分支的策略以及對發(fā)布的管理的實(shí)例分析

  • 可能派發(fā)自:develop

  • 必須合并回:develop

  • 分支命名規(guī)范:除了 master 、develop 、release-* 或 hotfix-* 的任何名字

Feature 分支(有時也被稱作 topic 分支)用來開發(fā)包括即將發(fā)布或遠(yuǎn)期發(fā)布的新的特性。當(dāng)我們開始開發(fā)一個特性的時候,發(fā)布合并的目標(biāo)可能還不太確定。Feature 分支的生命周期會和新特性的開發(fā)周期保持同步,但是最終會合并回 develop (恩,下次發(fā)布的時候把這個新特性帶上)或被拋棄(真是一次杯具的嘗試啊)。

Feature 分支通常僅存在于開發(fā)者的代碼庫中,并不出現(xiàn)在 origin 里。

創(chuàng)建一個 feature 分支

當(dāng)開始一個新特性的時候,從 develop 分支派發(fā)出一個分支

$ git checkout -b myfeature develop
Switched to a new branch "myfeature"
把完成的特性合并回 develop

完成的特性可以合并回 develop

分支并趕上下一次發(fā)布:

$ git checkout develop
Switched to a new branch "develop"
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557)
$ git push origin develop

-no-ff 標(biāo)記使得合并操作總是產(chǎn)生一次新的提交,哪怕合并操作可以快速完成。這個標(biāo)記避免將 feature 分支和團(tuán)隊(duì)協(xié)作的所有提交的歷史信息混在主分支的其它提交之后。比較一下:

Git分支的策略以及對發(fā)布的管理的實(shí)例分析

在右邊的例子里,我們不可能從 git 的歷史記錄中看出來哪些提交實(shí)現(xiàn)了這一特性——你可能不得不查看每一筆提交日志?;謴?fù)一個完整的特性(比如通過一組提交)在右邊變成了一個頭疼事情,而如果使用了 --no-ff 之后,就變得簡單了。

是的,這會創(chuàng)造一些沒有必要的(空的)提交記錄,但是得到的是大量的好處。

不幸的是,我還沒有找到一個在 git merge 時默認(rèn)就把 --no-ff 標(biāo)記打上的辦法,但這很重要。

release 分支

  • 可能派發(fā)自:develop

  • 必須合并回:develop 和 master

  • 分支命名規(guī)范:release-*

Release 分支用來支持新的生產(chǎn)環(huán)境發(fā)布的準(zhǔn)備工作。允許在最后階段產(chǎn)生提交點(diǎn)(dotting i's)和交匯點(diǎn)(crossing t's)。而且允許小幅度的問題修復(fù)以及準(zhǔn)備發(fā)布時的meta數(shù)據(jù)(比如版本號、發(fā)布日期等)。在 release 分支做了上述這些工作之后,develop 分支會被“翻篇兒”,開始接收下一次發(fā)布的新特性。

我們選擇(幾近)完成所有預(yù)期的開發(fā)的時候,作為從 develop 派發(fā)出 release 分支的時機(jī)。最起碼所有準(zhǔn)備構(gòu)建發(fā)布的功能都已經(jīng)及時合并到了 develop 分支。而往后才會發(fā)布的功能則不應(yīng)該合并到 develop 分支——他們必須等到 release 分支派發(fā)出去之后再做合并。

在一個 release 分支的開始,我們就賦予其一個明確的版本號。直到該分支創(chuàng)建之前,develop 分支上的描述都是“下一次”release 的改動,但這個“下一次”release 其實(shí)也沒說清楚是 0.3 release 還是 1.0 release。而在一個 release 分支的開始時這一點(diǎn)就會確定。這將成為有關(guān)項(xiàng)目版本號晉升的一個守則。

創(chuàng)建一個 release 分支

Release 分支派發(fā)自 develop 分支。比如,我們當(dāng)前的生產(chǎn)環(huán)境發(fā)布的版本是 1.1.5,馬上有一個 release 要發(fā)布了。develop 分支已經(jīng)為“下一次”release 做好了準(zhǔn)備,并且我們已經(jīng)決定把新的版本號定為 1.2 (而不是 1.1.6 或 2.0)。所以我們派發(fā)一個 release 分支并以新的版本號為其命名:

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)

創(chuàng)建好并切換到新的分支之后,我們完成對版本號的晉升。這里的 bump-version.sh 是一個虛構(gòu)的用來改變代碼庫中某些文件以反映新版本的 shell 腳本。(當(dāng)然你也可以手動完成這些改變——重點(diǎn)是有些文件發(fā)生了改變)然后,晉升了的版本號會被提交。

這個新的分支會存在一段時間,直到它確實(shí)發(fā)布出去了為止。期間可能會有 bug 修復(fù)(這比在 develop 做更合理)。但我們嚴(yán)格禁止在此開發(fā)龐大的新特性,它們應(yīng)該合并到 develop 分支,并放入下次發(fā)布。

完成一個 release 分支

當(dāng) release 分支真正發(fā)布成功之后,還有些事情需要收尾。首先,release 分支會被合并到 master (別忘了,master 上的每一次提交都代表一個真正的新的發(fā)布);然后,為 master 上的這次提交打一個 tag,以便作為版本歷史的重要參考;最后,還要把 release 分支產(chǎn)生的改動合并回 develop,以便后續(xù)的發(fā)布同樣包含對這些 bug 的修復(fù)。

前兩部在 git 下是這樣操作的:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive
(Summary of changes)
$ git tag -a 1.2

現(xiàn)在發(fā)布工作已經(jīng)完成了,同時 tag 也打好了,用在未來做參考。

補(bǔ)充:你也可以通過 -s 或 -u <key> 標(biāo)記打 tag。

為了保留 release 分支里的改動記錄,我們需要把這些改動合并回 develop。git 操作如下:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)

這一步有可能導(dǎo)致沖突的發(fā)生(只是有理論上的可能性,因?yàn)槲覀円呀?jīng)改變了版本號),一旦發(fā)現(xiàn),解決沖突然后提交就好了。

現(xiàn)在我們真正完成了一個 release 分支,該把它刪掉了,因?yàn)樗氖姑呀?jīng)完成了:

$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).

hotfix 分支

Git分支的策略以及對發(fā)布的管理的實(shí)例分析

  • 可能派發(fā)自:master

  • 必須合并回:develop 和 master

  • 分支命名規(guī)范:hotfix-*

Hotfix 分支和 release 分支非常類似,因?yàn)樗麄兌家馕吨鴷a(chǎn)生一個新的生產(chǎn)環(huán)境的發(fā)布,盡管 hotfix 分支不是先前就計劃好的。他們在實(shí)時的生產(chǎn)環(huán)境版本出現(xiàn)意外需要快速響應(yīng)時,從 master 分支相應(yīng)的 tag 被派發(fā)。

我們這樣做的根本原因,是為了讓團(tuán)隊(duì)其中一個人來快速修復(fù)生產(chǎn)環(huán)境的問題,其他成員可以按工作計劃繼續(xù)工作下去而不受太大影響。

創(chuàng)建一個 hotfix 分支

Hotfix 分支創(chuàng)建自 master 分支。例如,假設(shè) 1.2 版本是目前的生產(chǎn)環(huán)境且出現(xiàn)了一個嚴(yán)重的 bug,但是目前的 develop 并不足夠穩(wěn)定。那么我們可以派發(fā)出一個 hotfix 分支來開始我們的修復(fù)工作:

$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)

別忘了在派發(fā)出分支之后晉升版本號!

然后,修復(fù) bug,提交改動。通過一個或多個提交都可以。

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)
完成一個 hotfix 分支

當(dāng)我們完成之后,對 bug 的修復(fù)需要合并回 master,同時也需要合并回 develop,以保證接下來的發(fā)布也都已經(jīng)解決了這個 bug。這和 release 分支的完成方式是完全一樣的。

首先,更新 master 并為本次發(fā)布打一個 tag:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive
(Summary of changes)
$ git tag -a 1.2.1

補(bǔ)充:你也可以通過 -s 或 -u <key> 標(biāo)記打 tag。

然后,把已修復(fù)的 bug 合并到 develop:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive
(Summary of changes)

這個規(guī)矩的一個額外之處是:如果此時已經(jīng)存在了一個 release 分支,那么 hotfix 的改變需要合并到這個 release 分支,而不是 develop 分支。因?yàn)榘褜?bug 的修復(fù)合并回 release 分支之后,release 分支最終還是會合并回 develop 分支的。(如果在 develop 分支中立刻需要對這個 bug 的修復(fù),且等不及 release 分支合并回來,則你還是可以直接合并回 develop 分支的,這是絕對沒問題的)

最后,刪掉這個臨時的分支:

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).

摘要
其實(shí)這個分支模型里沒有什么新奇的東西。文章開頭的那張大圖對我們的項(xiàng)目來說非常有用。它非常易于團(tuán)隊(duì)成員理解這個優(yōu)雅有效的模型,并在團(tuán)隊(duì)內(nèi)部達(dá)成共識。
這里還有一份那張大圖的 高清PDF版本,你可以把它當(dāng)做手冊放在手邊快速瀏覽。

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

git
AI