『現學現忘』Git基礎 — 5、Git的協作模式

繁華似錦Fighting發表於2022-04-13

1、分散式工作流程

與傳統的集中式版本控制系統(CVCS)相反,Git 的分散式特性,使開發者間的協作變得更加靈活多樣。

在集中式版本控制系統中,每個開發者就像是連線在集線器上的節點,彼此的工作方式大體相像。 而在 Git 中,每個開發者同時扮演著節點和集線器的角色。也就是說, 每個開發者既可以將自己的程式碼貢獻到其他的倉庫中,同時也能維護自己的公開倉庫, 讓其他人可以在其基礎上工作並貢獻程式碼。

由此,Git 的分散式協作可以為你的專案和團隊,衍生出種種不同的工作流程, 接下來會介紹幾種常見Git工作流程。

你可以選擇使用其中的某一種,或者將它們的特性混合搭配使用。

2、集中式工作流

Git為了便於客戶機之間的協同工作,Git版本控制系統一般會設定一箇中央版本庫伺服器,目的是讓所有客戶機都從該主機更新版本,提交最新版本,該工作模式下的客戶機地位都平等。

集中式工作流像SVN一樣,以中央倉庫作為專案所有修改的單點實體,所有修改都提交到 Master分支上。這種方式與 SVN 的主要區別就是開發人員有本地庫,但是Git 很多特性並沒有用到。

如下圖:

image

上圖說明:

  • 一個遠端倉庫。
  • 一個主分支master
  • 團隊每個成員都有一個本地倉庫,在本地倉庫中進行程式碼的編輯、暫存和提交工作。

集中式工作流總結:

  • 適用人群:小型開發小團隊,習慣使用SVN工具的小團隊。
  • 工作方式:
    • 團隊組長建立遠端倉庫,建立一個master分支,組員可讀可寫。
    • 每個開發人員都git clone遠端倉庫到本地倉庫,在master分支上開發。
    • 每次開發都要git pull更新遠端倉庫的master分支版本到本地。
    • 每次開發完成就git commit到本地倉庫, 接著git push到遠端倉庫。
  • 缺點:
    • 忘了git push,一直會提交到本地倉庫,沒有推送到遠端倉庫。
    • 忘了git pull,導致本地倉庫與中央倉庫不一致,發生檔案衝突。
    • 大量操作git pull,導致增加Git分支合併次數,增加了Git變基次數,降低了Git的效能。

3、分支工作流

功能分支工作流在集中式工作流的基礎上,為各個新功能分配一個專門的分支來開發,即在master主分支外在建立一個分支,程式設計師開發的新功能全部push到此分支上,等到功能成熟的時候,再把此分支合併到主分支master上。

如下圖:

image

分支工作流總結:

  • 適用人群:小型開發團隊,熟悉Git分支的團隊。
  • 工作方式:
    • 團隊組長建立遠端倉庫,建立一個master分支,組員可讀不可寫。
    • 每個開發人員都git clone遠端倉庫到本地倉庫。
    • 每個開發人員建立自己的feature分支,在feature分支上開發。(記住,feature分支是基於master分支)
    • 每個開發人員每次開發完成就git commit到本地倉庫中自己的feature分支, 接著git push到遠端倉庫。
    • 通過pull request提醒團隊組長,瀏覽組員提交feature分支。
    • 組長把feature分支拉下來,然後合併到自己本地倉庫的master分支上測試。
    • 組長測試feature分支通過之後,由組長負責把feature分支合併到遠端倉庫的master分支上。
    • 組長在遠端倉庫把合併過的feature分支刪除。
    • 組員在本地倉庫把合併過的feature分支刪除。
    • 組員將本地倉庫分支切換為master分支,然後git pull將本地倉庫的master分支更新到遠端倉庫的master分支版本。
  • 缺點:
    • 增加團隊組長的工作量。
    • 增加團隊組員提交步驟。

說明:Pull Request作用是可以讓其他組員或組長可以檢視你的程式碼,並可以提出程式碼修改意見或者討論。

4、GitFlow 工作流(最流行)

Gitflow工作流沒有用超出上面功能分支工作流的概念和命令,而是為不同的分支,分配一個很明確的角色,並定義分支之間如何互動,和什麼時候進行互動。

  • 除了有master主分支(用於儲存正式釋出的歷史版本)外,還有一個作為功能整合分支的develop分支。
    當初始化完成後,某個程式設計師想要開發一個功能,並不是直接從master分支上拉出新分支,而是使用develop分支作為父分支來拉出新分支。
    當新功能完成後,再合併回父分支,新功能的提交併不與master分支直接互動
  • 一旦develop分支上有了做一次釋出(或者說快到了既定的釋出日)的足夠功能,就從develop分支上checkout一個釋出分支。
    新建的釋出分支用於開始釋出迴圈,所以從這個時間點開始之後新的功能,不能再加到這個分支上,該分支只應該做Bug修復、文件生成和其它面向釋出任務。
    一旦對外發布的工作都完成了,釋出分支合併到master分支,並分配一個版本號打好Tag
    另外,這些從新建釋出分支以來的做的修改,要合併回develop分支上。
  • 維護分支或說是熱修復(hotfix)分支用於,快速給產品釋出版本(production releases)打補丁,這是唯一可以直接從master分支fork出來的分支。
    修復完成,修改應該馬上合併回master分支和develop分支(當前的釋出分支),master分支應該用新的版本號打好Tag
    為Bug修復使用專門分支,讓團隊可以快速處理掉問題,而不用打斷其它工作或是等待下一個釋出迴圈。
    你可以把維護分支想成是一個直接在master分支上處理的臨時釋出。

總結就是Gitflow 工作流通過為功能開發釋出準備維護設立了獨立的分支,讓釋出迭代過程更流暢,充分的利用了分支的特點。嚴格的分支模型也為大型專案提供了一些非常必要的結構。

下圖是完整的Gitflow 工作流開發方式圖,但實際開發工作環境可能會精簡:

image

Gitflow工作流總結:

  • 適用人群:任何開發團隊,熟悉Git分支的團隊。
  • 工作方式:
    • 專案維護者建立專案維護者的遠端倉庫,建立master分支與develop分支,貢獻者可讀不可寫。
    • 每個貢獻者git clone遠端倉庫中的develop分支到本地倉庫。(記住,develop分支相當於master的分支,包括功能開發,修改,測試。master分支相當於最終分支)
    • 每個貢獻者在本地倉庫建立自己的feature分支,在feature分支上開發。
    • feature分支又可以建立多個feature分支,繼續開發專案。
    • 每個貢獻者每次開發完成就git commit到本地倉庫中自己的feature分支, 接著git push到遠端倉庫。
    • 通過pull request提醒專案維護者,瀏覽貢獻者提交feature分支。
    • 專案維護者把feature分支拉下來,然後合併到自己本地倉庫的develop分支上測試。
    • 組長測試feature分支通過之後,由組長負責把feature分支合併到遠端倉庫的develop分支上。
    • 專案維護者會release分支上git tag打上版本號。
    • 專案維護者可以從develop分支建立release分支,接著把release分支合併到master分支上,同時master分支同步到develop分支。
    • 專案維護者在遠端倉庫把合併過的feature分支刪除。
    • 每個貢獻者在本地倉庫把合併過的feature分支刪除。
    • 每個貢獻者將本地倉庫分支切換為develop分支,然後git pull將本地倉庫的master分支更新到遠端倉庫的develop分支版本。

說明:Gitflow工作流是Vincent Driessen工程師提出的多分支工作流。

5、Forking 工作流(偶爾使用)

分叉(Forking)工作流也可以叫做分散式工作流,是在 GitFlow工作流的基礎上的衍生,充分利用了Git在分支和克隆上的優勢,再加上pull request 的功能,以達到程式碼稽核的目的。既可以管理大團隊的開發者(developer)的提交,也可以接受不信任貢獻者(contributor)的提交。

這種工作流使得每個開發者都有一個服務端倉庫(此倉庫只有自己可以push推送,但是所有人都可以pull拉取修改),每個程式設計師都push程式碼到自己的服務端倉庫,但不能push到正式倉庫,只有專案維護者才能push到正式倉庫,這樣專案維護者可以接受任何開發者的提交,但無需給他正式程式碼庫的寫許可權。

這種工作流適合開源社群的開源專案,大家統一對專案做貢獻,但是有一個人或一個團隊作為開發者來管理專案,所有的貢獻者的程式碼由開發者稽核,其功能完善之後再由開發者push到正式倉庫中。

總結:

  • 分叉(Forking)工作流更適合安全可靠地管理大團隊的開發者,而且能接受不信任貢獻者的提交。
  • 在實際工作中,如果偶爾有需要團隊外的成員幫我們解決問題時,可能會用到。
  • 這種工作流程並不常用,只有當專案極為龐雜,或者需要多級別管理時,才會體現出優勢。 利用這種方式,專案總負責人(即主管)可以把大量分散的整合工作,委託給不同的小組負責人分別處理,然後在不同時刻將大塊的程式碼子集統籌起來,用於之後的整合。

圖示如下:

image

提示:

  • 每個成員都可以從中央版本庫中拉取程式碼。
  • 每級成員都只能向上一級提交程式碼。
  • 上一級合併程式碼之後繼續向上級提交程式碼。
  • 最後只有獨裁者才能向中央版本庫提交程式碼。

分叉工作流(分散式倉庫工作流)總結:

  • 適用人群:大型開發團隊,熟悉Git分支的團隊。
  • 工作方式:
    • 主專案維護者建立遠端倉庫,建立一個master分支,從專案維護者可讀不可寫。
    • 從專案維護者通過fork主專案維護者的遠端倉庫的副本,到自己的遠端倉庫,包括master分支。(記住,從專案維護者的遠端倉庫獨立於主專案維護者的遠端倉庫)
    • 從專案維護者git clone主專案維護者的遠端倉庫的副本到本地倉庫。
    • 從專案維護者建立自己的feature分支,在feature分支上開發。
    • 從專案維護者每次開發完成就git commit到本地倉庫中自己的feature分支, 接著git push到遠端倉庫。
    • 通過pull request命令,從專案維護者合併自己feature分支,到從專案維護者的遠端倉庫的master分支上。
    • 從專案維護者在遠端倉庫把合併過的feature分支刪除。
    • 從專案維護者在本地倉庫把合併過的feature分支刪除。
    • 從專案維護者在遠端倉庫通過pull request向主專案維護者的遠端倉庫的推送。
    • 主專案維護者通過pull request獲取從專案維護者的遠端倉庫的推送。
    • 主專案維護者進行從專案維護者的遠端倉庫程式碼審查,測試。
    • 主專案維護者確認無誤後,可以直接合併到主專案維護者的遠端倉庫。

6、總結

上面介紹了在Git分散式系統中經常使用的工作流程,但是在實際的開發中,你會遇到許多可能適合你的特定工作流程的變種,你可以按照實際的情況,靈活的進行組合和擴充。

參考:

相關文章