Git 工做流程及分支策略

本文首發於 劉星的我的網站html

image.png

Git 是目前世界上最早進的分佈式版本控制系統。它使咱們更方便的跟蹤,管理和組織代碼。也幫助了咱們更好的與其餘開發者進行協做開發。可是沒有規矩不成方圓。協做開發必須有一個規範來約束各個貢獻者的行爲。這個規範就是 Git 工做流程(Git Workflow),也爲咱們規範各個分支管理策略等行爲。

Git 工做流程是有關如何使用 Git 以高效協做開發的規則或策略建議,下文這些常見工做流程只是做爲指導參考,這些工做流不是一成不變的,咱們應該根據本身的項目選擇或制定合適本身的工做流。git

集中式工做流

首先咱們來介紹最簡單粗暴的集中式工做流,若是你用過SVN,那麼你能夠無痛切換到 Git 集中式工做流。該工做流只用到 master 這一個主分支來維護咱們的代碼,這也是該工做流的主要工做方式。github

工做流程示例

一、首先 clone 遠程倉庫到本地apache

git clone ssh://user@host/path/to/repo.git

二、而後在本地的 master 分支作出修改完成開發後,建立一個提交bash

git status # 查看本地倉庫的修改狀態
git add # 暫存文件
git commit # 提交文件

三、而後推送到遠程倉庫服務器

git push origin master

四、 若是此時本地倉庫與遠程倉庫有了分歧,Git 將拒絕操做並報錯。這時咱們就應該先 pull 遠程倉庫的修改到本地倉庫後再解決從新推送app

git pull --rebase origin master

五、若是有衝突,Git 會在合併有衝突的提交處暫停 rebase 過程,並報出錯誤信息,咱們在解決掉衝突後可使用一下命令將更改加入暫存區後繼續只能執行 rebase:框架

git add <some-file>
git rebase --continue

若是遇到一個搞不定的衝突,這可使用一下命令來終止 rebasessh

git rebase --abort

主要遵循原則

  • 只用到 master 這一個分支,全部的修改都推送到 master 分支
  • master 分支表明了項目的正式發佈版本,因此提交歷史應該被尊重且是穩定不變的
  • pull 代碼時, 最好使用 rebase 而不是生成一個 merge commit

優勢

  • 集中式工做流主要優勢是簡單,很是適合小型團隊
  • 對於要從 SVN 遷移過來的團隊來講很友好

缺點

  • 當您的團隊規模擴大時,上面詳述的衝突解決過程可能會成爲瓶頸
  • 徹底沒有發揮 Git 的優點,在實際使用 Git 協做的項目開發中不多使用集中式工做流

若是在稍大的團隊中使用前面的集中式工做流,那麼可能會在解決衝突中浪費不少時間。在實際開發中咱們基本上都是都 功能驅動式開發,基於功能需求,建立相應的分支進行開發,完成開發合併到主分支後再被刪除掉。接下來咱們介紹的三個工做流:GitHub Flow,Git Flow 及 Gitlab Flow 都是基於不一樣的分支管理策略運做的。分佈式

GitHub Flow 工做流

GitHub Flow 是一個輕量級的基於分支的工做流程。它由 GitHub 在 2011 年建立。分支是 Git 中的核心概念,而且 GitHub 工做流程中的一切都以此爲基礎。

最重要的的一點就是:main / master分支中的任何內容始終都是可部署的。其餘分支(功能分支)建立用於新功能和錯誤修復的工做,而且在工做完成並通過檢查後,這些分支將合併回到主分支中後刪除。這些分支名應該是具備描述性的如 refactor-authentication, user-content-cache-key, make-retina-avatars

工做流程示例

一、首先 clone 遠程倉庫到本地

git clone ssh://user@host/path/to/repo.git

二、根據要實現的功能建立一個新的分支,分支名應該具備描述性,如實現鑑權功能:feature-auth

git checkout -b feature-auth

三、而後將新工做提交到該分支下,並按期將工做推送到遠程倉庫

# 建立一個commit
git status # 查看本地倉庫的修改狀態
git add # 暫存文件
git commit # 提交文件

# 將分支推送到遠程倉庫
git push --set-upstream origin feature-auth

四、當你須要幫助或者反饋,或是你以爲你已經完成該功能的工做準備合進主分支的時候建立 pull request

五、當你的這部分工做在 pull request 中,被 review 以及 approved 後,則能夠合併到主分支。

git checkout master
git pull
git pull origin feature-auth
git push

六、合併到主分支後,應當即對其進行部署

主要遵循原則

  1. master 分支中的任何內容都是可部署的
  2. 要進行新的工做,須要從主分支master 建立出一個分支,並給出描述性的名稱(如:new-oauth2-scopes
  3. 本地的修改提交到該分支,並按期將你的工做推送到服務器上的同一命名分支
  4. 當你須要反饋或幫助時,或者你認爲分支已準備好進行合併時,請打開一個Pull Request
  5. 在其餘人 Review 並 Approved 該功能後,你能夠將其合併到 master
  6. 合併並推送到後主分支master,你能夠而且應該當即進行部署

優勢

  • 相比於前文介紹的集中式流程更爲合理實用,能夠減小工做中的衝突
  • 因爲工做流程的簡單性,此 Git 分支策略對進行持續交付和持續集成很友好。
  • 當須要在生產中維護單個版本時,它是理想的選擇
  • 這個 Git 分支策略很是適合小型團隊和 Web 應用程序

缺點

  • 這種 Git 分支策略沒法同時支持多個版本的代碼的部署
  • 沒有解決部署、環境區分、 releases、Bug 修復相關的問題
  • 生產代碼容易變得不穩定

Git Flow 工做流

基於功能分支的工做流是一中至關靈活的方式。可是問題也是有時候過於靈活。對於大型團隊,經常須要給不一樣分支分配一個更具體的角色。 Git Flow 工做流是管理功能開發、預發佈和維護的經常使用模式。

Git Flow 是最先誕生而且至關流行的工做流程。它由 Vincent Driessen 於 2010 年建立。Git Flow 工做流定義了一個圍繞項目發佈的嚴格分支模型。雖然比 GitHub Flow 的功能分支工做流複雜一點,但提供了用於一個健壯的用於管理大型項目的框架。

Git Flow 工做流沒有用超出功能分支工做流的概念和命令,Git Flow 爲不一樣的分支分配一個很明確的角色,並定義分支之間如何和何時進行交互。

工做流程示例

假設你已經建立好了中央倉庫,而且已將其 clone 到本地

一、首先咱們來從主分支建立一個開發分支 develop, 並推送到服務器

git branch develop
git push -u origin develop

之後這個分支將會包含了項目的所有歷史,而 master 分支將只包含了部分歷史

二、接下來咱們開始開發新功能,基於 develop 分支建立新的功能分支

git checkout -b some-feature develop

並在本身的功能分支上進行開發、建立提交:

git status # 查看本地倉庫的修改狀態
git add # 暫存文件
git commit # 提交文件

三、當你在你的分支上完成工做,準備好進行合併時,請打開一個 Pull Request,用於合併到develop分支。若是你的團隊沒使用 Pull Request 則能夠直接合併到本地的 develop 分支而後推送到中央倉庫。

git pull origin develop
git checkout develop

git merge --no-ff some-feature
git push
# 刪除本地分支
git branch -d some-feature

而且在功能分支合併後應該當即刪除

四、當咱們的 develop 分支進行到須要發佈時,須要從develop分支建立一個新的發佈分支,命名爲release-*release/*。這一步也肯定了發佈的版本號:

git checkout -b release-0.1.0 develop

這個分支是一個預發佈的版本,只作 bug 修復、文檔生成等面向發佈的任務。新功能再也不添加到這個分支上

五、通過一系列測試確認沒有問題,準備好了對外發布後,咱們須要將發佈分支合併到 master 分支,並打下 tag

git checkout master
git merge --no-ff release-0.1
git push
git tag -a 0.1 -m "release 0.1 publish" master
git push --tags

六、同時咱們還須要將這個發佈分支合併回去 master 分支

git checkout develop
git merge --no-ff release-0.1.0
git push

最後咱們還須要刪除掉這個發佈分支 release-0.1.0

七、若是咱們的線上版本出現問題時,就須要建立一個維護分支,用於快速給產品打補丁。這個維護分支須要從master分支上建立,提交修改以解決問題,而後再直接合並回master分支:

git checkout -b hotfix-auth master

修復完成後將其合併到 master 分支

git checkout master
git merge --no-ff hotfix-auth
git push

同時打下新的 tag

git tag -a 0.1.1 -m "release 0.1.1 publish" master
git push --tags

一樣也須要將修復分支合併到 develop 分支

git checkout develop
git merge --no-ff hotfix-auth
git push

最後刪除掉這個熱修復分支

git branch -d hotfix-auth

主要遵循原則

它基於兩個長期的主要分支:

  • 主分支 master 該分支包含生產代碼。 該分支是穩定的發佈版
  • 開發分支 develop 此分支包含預生產代碼。全部的功能分支完成後須要合併到該分支

其次在開發中還有三種短時間分支

  • 功能分支(feature branch)功能分支用於爲即將發佈的版本開發新功能。從develop分支中檢出也必須合併回develop
  • 補丁分支(hotfix branch)補丁分支 用於修復線上 bug, 從 master 分支上面檢出。修復結束之後,再合併進 master 和 develop 分支
  • 預發分支(release branch)預發佈分支用於生成一個預發佈版本進行測試 預發佈分支是從 develop 分支上面分出來的,預發佈結束之後,必須合併進 Develop 和 Master 分支。它的命名,能夠採用 release-*的形式。

優勢

  • 整個項目生命週期內,分支狀態十分乾淨,各個分支各司其職
  • 分支的命名遵循系統的模式,使其更易於理解
  • masterdevelop 分支分別記錄發佈和功能開發的歷史
  • 因爲有發佈分支,其餘暫不發佈的功能的開發不受發佈的影響,能夠繼續提交
  • 維護分支能快速打補丁,不影響正在開發的功能
  • 當生產中須要多個版本時,它是理想的選擇

缺點

  • 較爲複雜
  • Git 歷史記錄變得不可讀
  • 須要維護兩個長期分支 masterdevelop
  • 不方便持續交付和持續集成

Gitlab Flow 工做流

GitLab Flow 是經過建立工做流 GitLab在 2014 年。它將功能驅動的開發和功能分支以及問題跟蹤結合在一塊兒。它是 Git Flow 與 GithubFflow 的綜合。它吸收了二者的優勢,既有適應不一樣開發環境的彈性,又有單一主分支的簡單和便利。GitLab Flow 和 GitHub Flow 之間的最大區別是 GitLab Flow 中的環境分支支持(例如stagingproduction),

GitLab Flow 的最大原則叫作"上游優先"(upsteam first),即只存在一個主分支master,它是全部其餘分支的"上游"。只有上游分支採納的代碼變化,才能應用到其餘分支。

GitLab Flow 分紅兩種情形來應付不一樣的開發流程

持續發佈

對於持續發佈的項目,它建議在master分支之外,再創建不一樣的環境分支,每一個環境都會有對應的分支。好比,開發環境的分支是master,預發環境的分支是pre-production,生產環境的分支是production

  • 開發分支 master 用於發佈到測試環境,該分支爲受保護的分支
  • 預發分支 pre-production 用於發佈到預發環境,上游分支爲 master
  • 正式分支 production 用於發佈到正式環境,上游分支爲 pre-production

若是生產環境(production)發生錯誤,則要建一個新分支修改完後合併到最上游的開發分支(master)此時就是 Upstream first),且通過測試,再繼續往 pre-production branch,要通過測試沒有問題了纔可以再往下合併到生產環境。

版本發佈

對於"版本發佈"的項目,建議的作法是每個穩定版本,都要從master分支拉出一個分支,好比2-3-stable2-4-stable等等。

再出現 bug 後,根據對應的 release branch 建立一個修復分支,修復工做萬和城呢個後,同樣要按着上游優選的原則,先合併到 master 分支,通過測試才能到纔可以合併到 release 分支,而且此時要更新小版本號。

工做流程示例

和以前同樣。首先 clone 項目到本地

一、當咱們要實現新功能或是修復 bug 時。從 master 檢出新的分支如:feature-auth

git checkout -b feature-auth

二、而後在該分支下進行工做,完成後建立提交

git status # 查看本地倉庫的修改狀態
git add # 暫存文件
git commit # 提交文件

推送代碼到遠程倉庫,

git push origin feature-auth

三、代碼推送到倉庫後,自定運行 GitLab CI

四、當咱們開發完成準備合併進 master 時,在 GitLab 上建立一個 Merge Request

五、項目管理者進行代碼審查,經過後,合併到master

六、運行第二次 GitLab CI

七、經過相應的測試後,將master分支合併到stable,若是是新版本則建立一個新的stable分支

八、爲stable打上 tag,並進行發佈

主要遵循原則

  1. 使用功能分支,不直接提交(commit)到 master 分支
  2. 測試全部的提交,而不只僅只在 master 分支上
  3. 在全部的提交上,運行全部的測試(若是你的測試時間長於 5 分鐘則讓它們並行)
  4. 在合併到 master 以前執行代碼審查,而不是過後審查
  5. 部署是自動的,並基於分支或標籤(tag)
  6. 標籤(tag)是由用戶設置的,而不是由 CI 建立
  7. 發佈(release)是基於標籤(tag)的
  8. 永遠不對已推送的提交(pushed commits)進行變基(rebase)
  9. 每一個人都從 master 分支開始工做,目標也是 master 分支
  10. 在 master 分支中修正錯誤,其次再到發佈分支
  11. 提交信息(commit message)應體現意圖

優勢

  • 它定義瞭如何進行持續集成和持續交付
  • Git 歷史記錄乾淨、易讀

缺點

  • 相比較於 GitHub Flow 更復雜
  • 當須要在生產中維護多個版本時,它可能會像 Git Flow 同樣變得複雜

總結及建議

沒有一個萬能的適合全部項目的 Git 工做流程及分支策略,不管最終選擇哪一種策略,你均可以經過進一步的修改來優化它。就像前文所說的,Git 工做流程對咱們提高團隊生產力很是重要,在制定咱們的工做流程時,應該儘可能符合咱們的項目具體業務需求及開發環境。可是也有以下幾點小建議:

  • 臨時分支不該該存在過久,每一個分支應儘可能保持精簡,用完即刪
  • 工做流應該儘可能簡單,同時方便回滾
  • 工做流程應該符合咱們的項目發佈計劃

參考連接

本文完

歡迎能夠關注個人公衆號,一塊兒玩耍。有技術乾貨也有扯淡亂談

左手代碼右手磚,拋磚引玉

相關文章
相關標籤/搜索