[toc]
到目前為止,你應該已經有辦法使用 Git 來完成日常工作。 然而,為了使用 Git 協作功能,你還需要有遠程的 Git 倉庫。 盡管在技術上你可以從個人倉庫進行推送(push)和拉取(pull)來修改內容,但不鼓勵使用這種方法,因為一不留心就很容易弄混其他人的進度。 此外,你希望你的合作者們即使在你的電腦未聯機時亦能存取倉庫 — 擁有一個更可靠的公用倉庫十分有用。 因此,與他人合作的最佳方法即是建立一個你與合作者們都有權利訪問,且可從那里推送和拉取資料的共用倉庫。
架設一臺 Git 服務器并不難。 首先,選擇你希望服務器使用的通訊協議。 在本章第一節將介紹可用的協議以及各自優缺點。 下面一節將解釋使用那些協議的典型設置及如何在你的服務器上運行。 最后,如果你不介意托管你的代碼在其他人的服務器,且不想經歷設置與維護自己服務器的麻煩,可以試試我們介紹的幾個倉庫托管服務。
如果你對架設自己的服務器沒興趣,可以跳到本章最后一節去看看如何申請一個代碼托管服務的帳戶然后繼續下一章,我們會在那里討論分散式源碼控制環境的林林總總。
一個遠程倉庫通常只是一個裸倉庫(bare repository)— 即一個沒有當前工作目錄的倉庫。 因為該倉庫僅僅作為合作媒介,不需要從磁碟檢查快照;存放的只有 Git 的資料。 簡單的說,裸倉庫就是你工程目錄內的 .git 子目錄內容,不包含其他資料。
## 協議
Git 可以使用四種主要的協議來傳輸資料:本地協議(Local),HTTP 協議,SSH(Secure Shell)協議及 Git 協議。 在此,我們將會討論那些協議及哪些情形應該使用(或避免使用)他們。
## 本地協議
最基本的就是 本地協議(Local protocol) ,其中的遠程版本庫就是硬盤內的另一個目錄。 這常見于團隊每一個成員都對一個共享的文件系統(例如一個掛載的 NFS)擁有訪問權,或者比較少見的多人共用同一臺電腦的情況。 后者并不理想,因為你的所有代碼版本庫如果長存于同一臺電腦,更可能發生災難性的損失。
如果你使用共享文件系統,就可以從本地版本庫克隆(clone)、推送(push)以及拉取(pull)。 像這樣去克隆一個版本庫或者增加一個遠程到現有的項目中,使用版本庫路徑作為 URL。 例如,克隆一個本地版本庫,可以執行如下的命令:
~~~
$ git clone /opt/git/project.git
~~~
或你可以執行這個命令:
~~~
$ git clone file:///opt/git/project.git
~~~
如果在 URL 開頭明確的指定` file://`,那么 Git 的行為會略有不同。 如果僅是指定路徑,Git 會嘗試使用硬鏈接(hard link)或直接復制所需要的文件。 如果指定 `file://`,Git 會觸發平時用于網路傳輸資料的進程,那通常是傳輸效率較低的方法。 指定 file:// 的主要目的是取得一個沒有外部參考(extraneous references)或對象(object)的干凈版本庫副本– 通常是在從其他版本控制系統導入后或一些類似情況(參見 Git 內部原理 for maintenance tasks)需要這么做。 在此我們將使用普通路徑,因為這樣通常更快。
要增加一個本地版本庫到現有的 Git 項目,可以執行如下的命令:
~~~
$ git remote add local_proj /opt/git/project.git
~~~
然后,就可以像在網絡上一樣從遠端版本庫推送和拉取更新了。
### 優點
基于文件系統的版本庫的優點是簡單,并且直接使用了現有的文件權限和網絡訪問權限。 如果你的團隊已經有共享文件系統,建立版本庫會十分容易。 只需要像設置其他共享目錄一樣,把一個裸版本庫的副本放到大家都可以訪問的路徑,并設置好讀/寫的權限,就可以了, 我們會在 在服務器上搭建 Git 討論如何導出一個裸版本庫。
這也是快速從別人的工作目錄中拉取更新的方法。 如果你和別人一起合作一個項目,他想讓你從版本庫中拉取更新時,運行類似 git pull /home/john/project 的命令比推送到服務再取回簡單多了。
### 缺點
這種方法的缺點是,通常共享文件系統比較難配置,并且比起基本的網絡連接訪問,這不方便從多個位置訪問。 如果你想從家里推送內容,必須先掛載一個遠程磁盤,相比網絡連接的訪問方式,配置不方便,速度也慢。
值得一提的是,如果你使用的是類似于共享掛載的文件系統時,這個方法不一定是最快的。 訪問本地版本庫的速度與你訪問數據的速度是一樣的。 在同一個服務器上,如果允許 Git 訪問本地硬盤,一般的通過 NFS 訪問版本庫要比通過 SSH 訪問慢。
最終,這個協議并不保護倉庫避免意外的損壞。 每一個用戶都有“遠程”目錄的完整 shell 權限,沒有方法可以阻止他們修改或刪除 Git 內部文件和損壞倉庫。
## HTTP 協議
Git 通過 HTTP 通信有兩種模式。 在 Git 1.6.6 版本之前只有一個方式可用,十分簡單并且通常是只讀模式的。 Git 1.6.6 版本引入了一種新的、更智能的協議,讓 Git 可以像通過 SSH 那樣智能的協商和傳輸數據。 之后幾年,這個新的 HTTP 協議因為其簡單、智能變的十分流行。 新版本的 HTTP 協議一般被稱為“智能” HTTP 協議,舊版本的一般被稱為“啞” HTTP 協議。 我們先了解一下新的“智能” HTTP 協議。
### 智能(Smart) HTTP 協議
“智能” HTTP 協議的運行方式和 SSH 及 Git 協議類似,只是運行在標準的 HTTP/S 端口上并且可以使用各種 HTTP 驗證機制,這意味著使用起來會比 SSH 協議簡單的多,比如可以使用 HTTP 協議的用戶名/密碼的基礎授權,免去設置 SSH 公鑰。
智能 HTTP 協議或許已經是最流行的使用 Git 的方式了,它即支持像 git:// 協議一樣設置匿名服務,也可以像 SSH 協議一樣提供傳輸時的授權和加密。 而且只用一個 URL 就可以都做到,省去了為不同的需求設置不同的 URL。 如果你要推送到一個需要授權的服務器上(一般來講都需要),服務器會提示你輸入用戶名和密碼。 從服務器獲取數據時也一樣。
事實上,類似 GitHub 的服務,你在網頁上看到的 URL (比如, `https://github.com/schacon/simplegit[]`),和你在克隆、推送(如果你有權限)時使用的是一樣的。
### 啞(Dumb) HTTP 協議
如果服務器沒有提供智能 HTTP 協議的服務,Git 客戶端會嘗試使用更簡單的“啞” HTTP 協議。 啞 HTTP 協議里 web 服務器僅把裸版本庫當作普通文件來對待,提供文件服務。 啞 HTTP 協議的優美之處在于設置起來簡單。 基本上,只需要把一個裸版本庫放在 HTTP 根目錄,設置一個叫做 post-update 的掛鉤就可以了(見 Git 鉤子)。 此時,只要能訪問 web 服務器上你的版本庫,就可以克隆你的版本庫。 下面是設置從 HTTP 訪問版本庫的方法:
~~~
$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update
~~~
這樣就可以了。 Git 自帶的 post-update 掛鉤會默認執行合適的命令(git update-server-info),來確保通過 HTTP 的獲取和克隆操作正常工作。 這條命令會在你通過 SSH 向版本庫推送之后被執行;然后別人就可以通過類似下面的命令來克隆:
~~~
$ git clone https://example.com/gitproject.git
~~~
這里我們用了 Apache 里設置了常用的路徑 `/var/www/htdocs`,不過你可以使用任何靜態 web 服務器 —— 只需要把裸版本庫放到正確的目錄下就可以。 Git 的數據是以基本的靜態文件形式提供的(詳情見 Git 內部原理)。
通常的,會在可以提供讀/寫的智能 HTTP 服務和簡單的只讀的啞 HTTP 服務之間選一個。 極少會將二者混合提供服務。
### 優點
我們將只關注智能 HTTP 協議的優點。
不同的訪問方式只需要一個 URL 以及服務器只在需要授權時提示輸入授權信息,這兩個簡便性讓終端用戶使用 Git 變得非常簡單。 相比 SSH 協議,可以使用用戶名/密碼授權是一個很大的優勢,這樣用戶就不必須在使用 Git 之前先在本地生成 SSH 密鑰對再把公鑰上傳到服務器。 對非資深的使用者,或者系統上缺少 SSH 相關程序的使用者,HTTP 協議的可用性是主要的優勢。 與 SSH 協議類似,HTTP 協議也非常快和高效。
你也可以在 HTTPS 協議上提供只讀版本庫的服務,如此你在傳輸數據的時候就可以加密數據;或者,你甚至可以讓客戶端使用指定的 SSL 證書。
另一個好處是 HTTP/S 協議被廣泛使用,一般的企業防火墻都會允許這些端口的數據通過。
### 缺點
在一些服務器上,架設 HTTP/S 協議的服務端會比 SSH 協議的棘手一些。 除了這一點,用其他協議提供 Git 服務與 “智能” HTTP 協議相比就幾乎沒有優勢了。
如果你在 HTTP 上使用需授權的推送,管理憑證會比使用 SSH 密鑰認證麻煩一些。 然而,你可以選擇使用憑證存儲工具,比如 OSX 的 Keychain 或者 Windows 的憑證管理器。 參考 憑證存儲 如何安全地保存 HTTP 密碼。
## SSH 協議
架設 Git 服務器時常用 SSH 協議作為傳輸協議。 因為大多數環境下已經支持通過 SSH 訪問 —— 即時沒有也比較很容易架設。 SSH 協議也是一個驗證授權的網絡協議;并且,因為其普遍性,架設和使用都很容易。
通過 SSH 協議克隆版本庫,你可以指定一個 ssh:// 的 URL:
~~~
$ git clone ssh://user@server/project.git
~~~
或者使用一個簡短的 scp 式的寫法:
~~~
$ git clone user@server:project.git
~~~
你也可以不指定用戶,Git 會使用當前登錄的用戶名。
### 優勢
用 SSH 協議的優勢有很多。 首先,SSH 架設相對簡單 —— SSH 守護進程很常見,多數管理員都有使用經驗,并且多數操作系統都包含了它及相關的管理工具。 其次,通過 SSH 訪問是安全的 —— 所有傳輸數據都要經過授權和加密。 最后,與 HTTP/S 協議、Git 協議及本地協議一樣,SSH 協議很高效,在傳輸前也會盡量壓縮數據。
### 缺點
SSH 協議的缺點在于你不能通過他實現匿名訪問。 即便只要讀取數據,使用者也要有通過 SSH 訪問你的主機的權限,這使得 SSH 協議不利于開源的項目。 如果你只在公司網絡使用,SSH 協議可能是你唯一要用到的協議。 如果你要同時提供匿名只讀訪問和 SSH 協議,那么你除了為自己推送架設 SSH 服務以外,還得架設一個可以讓其他人訪問的服務。
## Git 協議
接下來是 Git 協議。 這是包含在 Git 里的一個特殊的守護進程;它監聽在一個特定的端口(9418),類似于 SSH 服務,但是訪問無需任何授權。 要讓版本庫支持 Git 協議,需要先創建一個 git-daemon-export-ok 文件 —— 它是 Git 協議守護進程為這個版本庫提供服務的必要條件 —— 但是除此之外沒有任何安全措施。 要么誰都可以克隆這個版本庫,要么誰也不能。 這意味著,通常不能通過 Git 協議推送。 由于沒有授權機制,一旦你開放推送操作,意味著網絡上知道這個項目 URL 的人都可以向項目推送數據。 不用說,極少會有人這么做。
### 優點
目前,Git 協議是 Git 使用的網絡傳輸協議里最快的。 如果你的項目有很大的訪問量,或者你的項目很龐大并且不需要為寫進行用戶授權,架設 Git 守護進程來提供服務是不錯的選擇。 它使用與 SSH 相同的數據傳輸機制,但是省去了加密和授權的開銷。
### 缺點
Git 協議缺點是缺乏授權機制。 把 Git 協議作為訪問項目版本庫的唯一手段是不可取的。 一般的做法里,會同時提供 SSH 或者 HTTPS 協議的訪問服務,只讓少數幾個開發者有推送(寫)權限,其他人通過 git:// 訪問只有讀權限。 Git 協議也許也是最難架設的。 它要求有自己的守護進程,這就要配置 xinetd 或者其他的程序,這些工作并不簡單。 它還要求防火墻開放 9418 端口,但是企業防火墻一般不會開放這個非標準端口。 而大型的企業防火墻通常會封鎖這個端口。
- 第一章 起步
- 1.1 關于版本控制
- 1.2 Git 簡史
- 1.3 Git 基礎
- 1.4 命令行
- 1.5 安裝 Git
- 1.6 初次運行 Git 前的配置
- 1.7 獲取幫助
- 1.8 總結
- 第二章 Git基礎
- 2.1 獲取 Git 倉庫
- 2.2 記錄每次更新到倉庫
- 2.3 查看提交歷史
- 2.4 撤消操作
- 2.5 遠程倉庫的使用
- 2.6 打標簽
- 2.7 Git 別名
- 2.8 總結
- 第三章 Git分支
- 3.1 分支簡介
- 3.2 分支的新建與合并
- 3.3 分支管理
- 3.4 分支開發工作流
- 3.5 遠程分支
- 3.6 變基
- 3.7 總結
- 第四章 服務器上Git
- 4.1 協議
- 4.2 在服務器上搭建 Git
- 4.3 生成 SSH 公鑰
- 4.4 配置服務器
- 4.5 Git 守護進程 TODO
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方托管的選擇
- 4.10 總結
- 第五章 分布式Git
- 5.1 分布式工作流程
- 第六章 GitHub
- 第七章 Git工具
- 第八章 自定義Git
- 第九章 Git于其他系統
- 第十章 Git內部原理
- 附錄A 其他環境中的Git
- A1.1 圖形界面 TODO
- A1.2 Visual Studio 中的 Git TODO
- A1.3 Eclipse 中的 Git
- 附錄B 將Git嵌入你的應用
- 附錄C Git命令
- 附錄D 常用命令
- D.1 配置和設置
- D.2 幫助
- D.3 創建和獲取倉庫
- D.4 文件狀態
- D.5 查看日志