Learn Git

分散式工作流程

同傳統的集中式版本控制系統(CVCS)不同,開發者之間的協作方式因著 Git 的分散式特性而變得更為靈活多樣。在集中式系統上,每個開發者就像是連接在集線器上的節點,彼此的工作方式大體相像。而在 Git 網路中,每個開發者同時扮演著節點和集線器的角色,這就是說,每一個開發者都可以將自己的代碼貢獻到另外一個開發者的倉庫中,或者建立自己的公共倉庫,讓其他開發者基於自己的工作開始,為自己的倉庫貢獻代碼。於是,Git 的分散式協作便可以衍生出種種不同的工作流程,我會在接下來的章節介紹幾種常見的應用方式,並分別討論各自的優缺點。你可以選擇其中的一種,或者結合起來,應用到你自己的專案中。

集中式工作流

通常,集中式工作流程使用的都是單點協作模型。一個存放代碼倉庫的中心伺服器,可以接受所有開發者提交的代碼。所有的開發者都是普通的節點,作為中心集線器的消費者,平時的工作就是和中心倉庫同步資料(見圖 5-1)。

圖 5-1. 集中式工作流

如果兩個開發者從中心倉庫克隆代碼下來,同時作了一些修訂,那麼只有第一個開發者可以順利地把資料推送到共用伺服器。第二個開發者在提交他的修訂之前,必須先下載合併伺服器上的資料,解決衝突之後才能推送資料到共用伺服器上。在 Git 中這麼用也決無問題,這就好比是在用 Subversion(或其他 CVCS)一樣,可以很好地工作。

如果你的團隊不是很大,或者大家都已經習慣了使用集中式工作流程,完全可以採用這種簡單的模式。只需要配置好一台中心伺服器,並給每個人推送資料的許可權,就可以開展工作了。但如果提交代碼時有衝突, Git 根本就不會讓用戶覆蓋他人代碼,它直接駁回第二個人的提交操作。這就等於告訴提交者,你所作的修訂無法通過快近(fast-forward)來合併,你必須先拉取最新資料下來,手工解決衝突合併後,才能繼續推送新的提交。 絕大多數人都熟悉和瞭解這種模式的工作方式,所以使用也非常廣泛。

集成管理員工作流

由於 Git 允許使用多個遠端倉庫,開發者便可以建立自己的公共倉庫,往裡面寫資料並共用給他人,而同時又可以從別人的倉庫中提取他們的更新過來。這種情形通常都會有個代表著官方發佈的專案倉庫(blessed repository),開發者們由此倉庫克隆出一個自己的公共倉庫(developer public),然後將自己的提交推送上去,請求官方倉庫的維護者拉取更新合併到主項目。維護者在自己的本地也有個克隆倉庫(integration manager),他可以將你的公共倉庫作為遠端倉庫添加進來,經過測試無誤後合併到主幹分支,然後再推送到官方倉庫。工作流程看起來就像圖 5-2 所示:

  1. 專案維護者可以推送資料到公共倉庫 blessed repository。
  2. 貢獻者克隆此倉庫,修訂或編寫新代碼。
  3. 貢獻者推送資料到自己的公共倉庫 developer public。
  4. 貢獻者給維護者發送郵件,請求拉取自己的最新修訂。
  5. 維護者在自己本地的 integration manger 倉庫中,將貢獻者的倉庫加為遠程倉庫,合併更新並做測試。
  6. 維護者將合併後的更新推送到主倉庫 blessed repository。

圖 5-2. 集成管理員工作流

在 GitHub 網站上使用得最多的就是這種工作流。人們可以複製(fork 亦即克隆)某個項目到自己的列表中,成為自己的公共倉庫。隨後將自己的更新提交到這個倉庫,所有人都可以看到你的每次更新。這麼做最主要的優點在於,你可以按照自己的節奏繼續工作,而不必等待維護者處理你提交的更新;而維護者也可以按照自己的節奏,任何時候都可以過來處理接納你的貢獻。

司令官與副官工作流

這其實是上一種工作流的變體。一般超大型的專案才會用到這樣的工作方式,像是擁有數百協作開發者的 Linux 內核專案就是如此。各個集成管理員分別負責集成專案中的特定部分,所以稱為副官(lieutenant)。而所有這些集成管理員頭上還有一位負責統籌的總集成管理員,稱為司令官(dictator)。司令官維護的倉庫用於提供所有協作者拉取最新集成的項目代碼。整個流程看起來如圖 5-3 所示:

  1. 一般的開發者在自己的特性分支上工作,並不定期地根據主幹分支(dictator 上的 master)衍合。
  2. 副官(lieutenant)將普通開發者的特性分支合併到自己的 master 分支中。
  3. 司令官(dictator)將所有副官的 master 分支併入自己的 master 分支。
  4. 司令官(dictator)將集成後的 master 分支推送到共用倉庫 blessed repository 中,以便所有其他開發者以此為基礎進行衍合。

圖 5-3. 司令官與副官工作流

這種工作流程並不常用,只有當專案極為龐雜,或者需要多級別管理時,才會體現出優勢。利用這種方式,專案總負責人(即司令官)可以把大量分散的集成工作委託給不同的小組負責人分別處理,最後再統籌起來,如此各人的職責清晰明確,也不易出錯(譯注:此乃分而治之)。

以上介紹的是常見的分散式系統可以應用的工作流程,當然不止於 Git。在實際的開發工作中,你可能會遇到各種為了滿足特定需求而有所變化的工作方式。我想現在你應該已經清楚,接下來自己需要用哪種方式開展工作了。下節我還會再舉些例子,看看各式工作流中的每個角色具體應該如何操作。