同傳統的集中式版本控制系統(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。在實際的開發工作中,你可能會遇到各種為了滿足特定需求而有所變化的工作方式。我想現在你應該已經清楚,接下來自己需要用哪種方式開展工作了。下節我還會再舉些例子,看看各式工作流中的每個角色具體應該如何操作。
- 1. 起步
- 1.1 關于版本控制
- 1.2 Git 簡史
- 1.3 Git 基礎
- 1.4 安裝 Git
- 1.5 初次運行 Git 前的配置
- 1.6 獲取幫助
- 1.7 小結
- 2. Git基礎
- 2.1 取得項目的 Git 倉庫
- 2.2 記錄每次更新到倉庫
- 2.3 查看提交歷史
- 2.4 撤消操作
- 2.5 遠程倉庫的使用
- 2.6 打標簽
- 2.7 技巧和竅門
- 2.8 小結
- 3. Git分支
- 3.1 何謂分支
- 3.2 分支的新建與合并
- 3.3 分支的管理
- 3.4 利用分支進行開發的工作流程
- 3.5 遠程分支
- 3.6 分支的衍合
- 3.7 小結
- 4. 服務器上的Git
- 4.1 協議
- 4.2 在服務器上部署 Git
- 4.3 生成 SSH 公鑰
- 4.4 架設服務器
- 4.5 公共訪問
- 4.6 GitWeb
- 4.7 Gitosis
- 4.8 Gitolite
- 4.9 Git 守護進程
- 4.10 Git 托管服務
- 4.11 小結
- 5. 分布式Git
- 5.1 分布式工作流程
- 5.2 為項目作貢獻
- 5.3 項目的管理
- 5.4 小結
- 6. Git工具
- 6.1 修訂版本(Revision)選擇
- 6.2 交互式暫存
- 6.3 儲藏(Stashing)
- 6.4 重寫歷史
- 6.5 使用 Git 調試
- 6.6 子模塊
- 6.7 子樹合并
- 6.8 總結
- 7. 自定義Git
- 7.1 配置 Git
- 7.2 Git屬性
- 7.3 Git掛鉤
- 7.4 Git 強制策略實例
- 7.5 總結
- 8. Git與其他系統
- 8.1 Git 與 Subversion
- 8.2 遷移到 Git
- 8.3 總結
- 9. Git 內部原理
- 9.2 Git 對象
- 9.3 Git References
- 9.4 Packfiles
- 9.5 The Refspec
- 9.6 傳輸協議
- 9.7 維護及數據恢復
- 9.8 總結
- 9.1 底層命令 (Plumbing) 和高層命令 (Porcelain)