# 分布式工作流程
同傳統的集中式版本控制系統(CVCS)不同,Git 的分布式特性使得開發者間的協作變得更加靈活多樣。在集中式系統中,每個開發者就像是連接在集線器上的節點,彼此的工作方式大體相像。而在 Git 中,每個開發者同時扮演著節點和集線器的角色——也就是說,每個開發者既可以將自己的代碼貢獻到其他的倉庫中,同時也能維護自己的公開倉庫,讓其他人可以在其基礎上工作并貢獻代碼。由此,Git 的分布式協作可以為你的項目和團隊衍生出種種不同的工作流程,接下來的章節會介紹幾種利用了 Git 的這種靈活性的常見應用方式。我們將討論每種方式的優點以及可能的缺點;你可以選擇使用其中的某一種,或者將它們的特性混合搭配使用。
## 集中式工作流
集中式系統中通常使用的是單點協作模型——集中式工作流。一個中心集線器,或者說倉庫,可以接受代碼,所有人將自己的工作與之同步。若干個開發者則作為節點——也就是中心倉庫的消費者——并且與其進行同步。

Figure 5-1. 集中式工作流。
這意味著如果兩個開發者從中心倉庫克隆代碼下來,同時作了一些修改,那么只有第一個開發者可以順利地把數據推送回共享服務器。第二個開發者在推送修改之前,必須先將第一個人的工作合并進來,這樣才不會覆蓋第一個人的修改。這和 Subversion (或任何 CVCS)中的概念一樣,而且這個模式也可以很好地運用到 Git 中。
如果在公司或者團隊中,你已經習慣了使用這種集中式工作流程,完全可以繼續采用這種簡單的模式。只需要搭建好一個中心倉庫,并給開發團隊中的每個人推送數據的權限,就可以開展工作了。Git 不會讓用戶覆蓋彼此的修改。例如 John 和 Jessica 同時開始工作。John 完成了他的修改并推送到服務器。接著 Jessica 嘗試提交她自己的修改,卻遭到服務器拒絕。她被告知她的修改正通過非快進式(non-fast-forward)的方式推送,只有將數據抓取下來并且合并后方能推送。這種模式的工作流程的使用非常廣泛,因為大多數人對其很熟悉也很習慣。
當然這并不局限于小團隊。利用 Git 的分支模型,通過同時在多個分支上工作的方式,即使是上百人的開發團隊也可以很好地在單個項目上協作。
## 集成管理者工作流
Git 允許多個遠程倉庫存在,使得這樣一種工作流成為可能:每個開發者擁有自己倉庫的寫權限和其他所有人倉庫的讀權限。這種情形下通常會有個代表“官方”項目的權威的倉庫。要為這個項目做貢獻,你需要從該項目克隆出一個自己的公開倉庫,然后將自己的修改推送上去。接著你可以請求官方倉庫的維護者拉取更新合并到主項目。維護者可以將你的倉庫作為遠程倉庫添加進來,在本地測試你的變更,將其合并入他們的分支并推送回官方倉庫。這一流程的工作方式如下所示(見 [Figure?5-2](#)):
1. 項目維護者推送到主倉庫。
1. 貢獻者克隆此倉庫,做出修改。
1. 貢獻者將數據推送到自己的公開倉庫。
1. 貢獻者給維護者發送郵件,請求拉取自己的更新。
1. 維護者在自己本地的倉庫中,將貢獻者的倉庫加為遠程倉庫并合并修改。
1. 維護者將合并后的修改推送到主倉庫。

Figure 5-2. 集成管理者工作流。
這是 GitHub 和 GitLab 等集線器式(hub-based)工具最常用的工作流程。人們可以容易地將某個項目派生成為自己的公開倉庫,向這個倉庫推送自己的修改,并為每個人所見。這么做最主要的優點之一是你可以持續地工作,而主倉庫的維護者可以隨時拉取你的修改。貢獻者不必等待維護者處理完提交的更新——每一方都可以按照自己節奏工作。
## 司令官與副官工作流
這其實是多倉庫工作流程的變種。一般擁有數百位協作開發者的超大型項目才會用到這樣的工作方式,例如著名的 Linux 內核項目。被稱為副官(lieutenant)的各個集成管理者分別負責集成項目中的特定部分。所有這些副官頭上還有一位稱為司令官(dictator)的總集成管理者負責統籌。司令官維護的倉庫作為參考倉庫,為所有協作者提供他們需要拉取的項目代碼。整個流程看起來是這樣的(見 [Figure?5-3](#)):
1. 普通開發者在自己的特性分支上工作,并根據 `master` 分支進行變基。這里是司令官的`master`分支。
1. 副官將普通開發者的特性分支合并到自己的 `master` 分支中。
1. 司令官將所有副官的 `master` 分支并入自己的 `master` 分支中。
1. 司令官將集成后的 `master` 分支推送到參考倉庫中,以便所有其他開發者以此為基礎進行變基。

Figure 5-3. 司令官與副官工作流。
這種工作流程并不常用,只有當項目極為龐雜,或者需要多級別管理時,才會體現出優勢。利用這種方式,項目總負責人(即司令官)可以把大量分散的集成工作委托給不同的小組負責人分別處理,然后在不同時刻將大塊的代碼子集統籌起來,用于之后的整合。
## 工作流程總結
上面介紹了在 Git 等分布式系統中經常使用的工作流程,但是在實際的開發中,你會遇到許多可能適合你的特定工作流程的變種。現在你應該已經清楚哪種工作流程組合可能比較適合你了,我們會給出一些如何扮演不同工作流程中主要角色的更具體的例子。下一節我們將會學習為項目做貢獻的一些常用模式。
- 前言
- Scott Chacon 序
- Ben Straub 序
- 獻辭
- 貢獻者
- 引言
- 1. 起步
- 1.1 關于版本控制
- 1.2 Git 簡史
- 1.3 Git 基礎
- 1.4 命令行
- 1.5 安裝 Git
- 1.6 初次運行 Git 前的配置
- 1.7 獲取幫助
- 1.8 總結
- 2. Git 基礎
- 2.1 獲取 Git 倉庫
- 2.2 記錄每次更新到倉庫
- 2.3 查看提交歷史
- 2.4 撤消操作
- 2.5 遠程倉庫的使用
- 2.6 打標簽
- 2.7 Git 別名
- 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 Git 守護進程
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方托管的選擇
- 4.10 總結
- 5. 分布式 Git
- 5.1 分布式工作流程
- 5.2 向一個項目貢獻
- 5.3 維護項目
- 5.4 總結
- 6. GitHub
- 6.1 賬戶的創建和配置
- 6.2 對項目做出貢獻
- 6.3 維護項目
- 6.4 管理組織
- 6.5 腳本 GitHub
- 6.6 總結
- 7. Git 工具
- 7.1 選擇修訂版本
- 7.2 交互式暫存
- 7.3 儲藏與清理
- 7.4 簽署工作
- 7.5 搜索
- 7.6 重寫歷史
- 7.7 重置揭密
- 7.8 高級合并
- 7.9 Rerere
- 7.10 使用 Git 調試
- 7.11 子模塊
- 7.12 打包
- 7.13 替換
- 7.14 憑證存儲
- 7.15 總結
- 8. 自定義 Git
- 8.1 配置 Git
- 8.2 Git 屬性
- 8.3 Git 鉤子
- 8.4 使用強制策略的一個例子
- 8.5 總結
- 9. Git 與其他系統
- 9.1 作為客戶端的 Git
- 9.2 遷移到 Git
- 9.3 總結
- 10. Git 內部原理
- 10.1 底層命令和高層命令
- 10.2 Git 對象
- 10.3 Git 引用
- 10.4 包文件
- 10.5 引用規格
- 10.6 傳輸協議
- 10.7 維護與數據恢復
- 10.8 環境變量
- 10.9 總結
- A. 其它環境中的 Git
- A1.1 圖形界面
- A1.2 Visual Studio 中的 Git
- A1.3 Eclipse 中的 Git
- A1.4 Bash 中的 Git
- A1.5 Zsh 中的 Git
- A1.6 Powershell 中的 Git
- A1.7 總結
- B. 將 Git 嵌入你的應用
- A2.1 命令行 Git 方式
- A2.2 Libgit2
- A2.3 JGit
- C. Git 命令
- A3.1 設置與配置
- A3.2 獲取與創建項目
- A3.3 快照基礎
- A3.4 分支與合并
- A3.5 項目分享與更新
- A3.6 檢查與比較
- A3.7 調試
- A3.8 補丁
- A3.9 郵件
- A3.10 外部系統
- A3.11 管理
- A3.12 底層命令