Git 可以使用四種主要的協(xié)議來(lái)傳輸數(shù)據(jù):本地傳輸,SSH 協(xié)議,Git 協(xié)議和 HTTP 協(xié)議。下面分別介紹一下哪些情形應(yīng)該使用(或避免使用)這些協(xié)議。
值得注意的是,除了 HTTP 協(xié)議外,其他所有協(xié)議都要求在服務(wù)器端安裝并運(yùn)行 Git。
最基本的就是本地協(xié)議(Local protocol),所謂的遠(yuǎn)程倉(cāng)庫(kù)在該協(xié)議中的表示,就是硬盤上的另一個(gè)目錄。這常見(jiàn)于團(tuán)隊(duì)每一個(gè)成員都對(duì)一個(gè)共享的文件系統(tǒng)(例如 NFS)擁有訪問(wèn)權(quán),或者比較少見(jiàn)的多人共用同一臺(tái)電腦的情況。后面一種情況并不安全,因?yàn)樗写a倉(cāng)庫(kù)實(shí)例都儲(chǔ)存在同一臺(tái)電腦里,增加了災(zāi)難性數(shù)據(jù)損失的可能性。
如果你使用一個(gè)共享的文件系統(tǒng),就可以在一個(gè)本地文件系統(tǒng)中克隆倉(cāng)庫(kù),推送和獲取??寺〉臅r(shí)候只需要將遠(yuǎn)程倉(cāng)庫(kù)的路徑作為 URL 使用,比如下面這樣:
$ git clone /opt/git/project.git
或者這樣:
$ git clone file:///opt/git/project.git
如果在 URL 開頭明確使用 file://
,那么 Git 會(huì)以一種略微不同的方式運(yùn)行。如果你只給出路徑,Git 會(huì)嘗試使用硬鏈接或直接復(fù)制它所需要的文件。如果使用了 file://
,Git 會(huì)調(diào)用它平時(shí)通過(guò)網(wǎng)絡(luò)來(lái)傳輸數(shù)據(jù)的工序,而這種方式的效率相對(duì)較低。使用 file://
前綴的主要原因是當(dāng)你需要一個(gè)不包含無(wú)關(guān)引用或?qū)ο蟮母蓛魝}(cāng)庫(kù)副本的時(shí)候 — 一般指從其他版本控制系統(tǒng)導(dǎo)入的,或類似情形(參見(jiàn)第 9 章的維護(hù)任務(wù))。我們這里僅僅使用普通路徑,這樣更快。
要添加一個(gè)本地倉(cāng)庫(kù)作為現(xiàn)有 Git 項(xiàng)目的遠(yuǎn)程倉(cāng)庫(kù),可以這樣做:
$ git remote add local_proj /opt/git/project.git
然后就可以像在網(wǎng)絡(luò)上一樣向這個(gè)遠(yuǎn)程倉(cāng)庫(kù)推送和獲取數(shù)據(jù)了。
基于文件倉(cāng)庫(kù)的優(yōu)點(diǎn)在于它的簡(jiǎn)單,同時(shí)保留了現(xiàn)存文件的權(quán)限和網(wǎng)絡(luò)訪問(wèn)權(quán)限。如果你的團(tuán)隊(duì)已經(jīng)有一個(gè)全體共享的文件系統(tǒng),建立倉(cāng)庫(kù)就十分容易了。你只需把一份裸倉(cāng)庫(kù)的副本放在大家都能訪問(wèn)的地方,然后像對(duì)其他共享目錄一樣設(shè)置讀寫權(quán)限就可以了。我們將在下一節(jié)“在服務(wù)器上部署 Git ”中討論如何導(dǎo)出一個(gè)裸倉(cāng)庫(kù)的副本。
這也是從別人工作目錄中獲取工作成果的快捷方法。假如你和你的同事在一個(gè)項(xiàng)目中合作,他們想讓你檢出一些東西的時(shí)候,運(yùn)行類似 git pull /home/john/project
通常會(huì)比他們推送到服務(wù)器,而你再?gòu)姆?wù)器獲取簡(jiǎn)單得多。
這種方法的缺點(diǎn)是,與基本的網(wǎng)絡(luò)連接訪問(wèn)相比,難以控制從不同位置來(lái)的訪問(wèn)權(quán)限。如果你想從家里的筆記本電腦上推送,就要先掛載遠(yuǎn)程硬盤,這和基于網(wǎng)絡(luò)連接的訪問(wèn)相比更加困難和緩慢。
另一個(gè)很重要的問(wèn)題是該方法不一定就是最快的,尤其是對(duì)于共享掛載的文件系統(tǒng)。本地倉(cāng)庫(kù)只有在你對(duì)數(shù)據(jù)訪問(wèn)速度快的時(shí)候才快。在同一個(gè)服務(wù)器上,如果二者同時(shí)允許 Git 訪問(wèn)本地硬盤,通過(guò) NFS 訪問(wèn)倉(cāng)庫(kù)通常會(huì)比 SSH 慢。
Git 使用的傳輸協(xié)議中最常見(jiàn)的可能就是 SSH 了。這是因?yàn)榇蠖鄶?shù)環(huán)境已經(jīng)支持通過(guò) SSH 對(duì)服務(wù)器的訪問(wèn) — 即便還沒(méi)有,架設(shè)起來(lái)也很容易。SSH 也是唯一一個(gè)同時(shí)支持讀寫操作的網(wǎng)絡(luò)協(xié)議。另外兩個(gè)網(wǎng)絡(luò)協(xié)議(HTTP 和 Git)通常都是只讀的,所以雖然二者對(duì)大多數(shù)人都可用,但執(zhí)行寫操作時(shí)還是需要 SSH。SSH 同時(shí)也是一個(gè)驗(yàn)證授權(quán)的網(wǎng)絡(luò)協(xié)議;而因?yàn)槠淦毡樾?,一般架設(shè)和使用都很容易。
通過(guò) SSH 克隆一個(gè) Git 倉(cāng)庫(kù),你可以像下面這樣給出 ssh:// 的 URL:
$ git clone ssh://user@server/project.git
或者不指明某個(gè)協(xié)議 — 這時(shí) Git 會(huì)默認(rèn)使用 SSH :
$ git clone user@server:project.git
如果不指明用戶,Git 會(huì)默認(rèn)使用當(dāng)前登錄的用戶名連接服務(wù)器。
使用 SSH 的好處有很多。首先,如果你想擁有對(duì)網(wǎng)絡(luò)倉(cāng)庫(kù)的寫權(quán)限,基本上不可能不使用 SSH。其次,SSH 架設(shè)相對(duì)比較簡(jiǎn)單 — SSH 守護(hù)進(jìn)程很常見(jiàn),很多網(wǎng)絡(luò)管理員都有一些使用經(jīng)驗(yàn),而且很多操作系統(tǒng)都自帶了它或者相關(guān)的管理工具。再次,通過(guò) SSH 進(jìn)行訪問(wèn)是安全的 — 所有數(shù)據(jù)傳輸都是加密和授權(quán)的。最后,和 Git 及本地協(xié)議一樣,SSH 也很高效,會(huì)在傳輸之前盡可能壓縮數(shù)據(jù)。
SSH 的限制在于你不能通過(guò)它實(shí)現(xiàn)倉(cāng)庫(kù)的匿名訪問(wèn)。即使僅為讀取數(shù)據(jù),人們也必須在能通過(guò) SSH 訪問(wèn)主機(jī)的前提下才能訪問(wèn)倉(cāng)庫(kù),這使得 SSH 不利于開源的項(xiàng)目。如果你僅僅在公司網(wǎng)絡(luò)里使用,SSH 可能是你唯一需要使用的協(xié)議。如果想允許對(duì)項(xiàng)目的匿名只讀訪問(wèn),那么除了為自己推送而架設(shè) SSH 協(xié)議之外,還需要支持其他協(xié)議以便他人訪問(wèn)讀取。
接下來(lái)是 Git 協(xié)議。這是一個(gè)包含在 Git 軟件包中的特殊守護(hù)進(jìn)程; 它會(huì)監(jiān)聽一個(gè)提供類似于 SSH 服務(wù)的特定端口(9418),而無(wú)需任何授權(quán)。打算支持 Git 協(xié)議的倉(cāng)庫(kù),需要先創(chuàng)建 git-daemon-export-ok
文件 — 它是協(xié)議進(jìn)程提供倉(cāng)庫(kù)服務(wù)的必要條件 — 但除此之外該服務(wù)沒(méi)有什么安全措施。要么所有人都能克隆 Git 倉(cāng)庫(kù),要么誰(shuí)也不能。這也意味著該協(xié)議通常不能用來(lái)進(jìn)行推送。你可以允許推送操作;然而由于沒(méi)有授權(quán)機(jī)制,一旦允許該操作,網(wǎng)絡(luò)上任何一個(gè)知道項(xiàng)目 URL 的人將都有推送權(quán)限。不用說(shuō),這是十分罕見(jiàn)的情況。
Git 協(xié)議是現(xiàn)存最快的傳輸協(xié)議。如果你在提供一個(gè)有很大訪問(wèn)量的公共項(xiàng)目,或者一個(gè)不需要對(duì)讀操作進(jìn)行授權(quán)的龐大項(xiàng)目,架設(shè)一個(gè) Git 守護(hù)進(jìn)程來(lái)供應(yīng)倉(cāng)庫(kù)是個(gè)不錯(cuò)的選擇。它使用與 SSH 協(xié)議相同的數(shù)據(jù)傳輸機(jī)制,但省去了加密和授權(quán)的開銷。
Git 協(xié)議消極的一面是缺少授權(quán)機(jī)制。用 Git 協(xié)議作為訪問(wèn)項(xiàng)目的唯一方法通常是不可取的。一般的做法是,同時(shí)提供 SSH 接口,讓幾個(gè)開發(fā)者擁有推送(寫)權(quán)限,其他人通過(guò) git://
擁有只讀權(quán)限。 Git 協(xié)議可能也是最難架設(shè)的協(xié)議。它要求有單獨(dú)的守護(hù)進(jìn)程,需要定制 — 我們將在本章的 “Gitosis” 一節(jié)詳細(xì)介紹它的架設(shè) — 需要設(shè)定 xinetd
或類似的程序,而這些工作就沒(méi)那么輕松了。該協(xié)議還要求防火墻開放 9418 端口,而企業(yè)級(jí)防火墻一般不允許對(duì)這個(gè)非標(biāo)準(zhǔn)端口的訪問(wèn)。大型企業(yè)級(jí)防火墻通常會(huì)封鎖這個(gè)少見(jiàn)的端口。
最后還有 HTTP 協(xié)議。HTTP 或 HTTPS 協(xié)議的優(yōu)美之處在于架設(shè)的簡(jiǎn)便性。基本上,只需要把 Git 的裸倉(cāng)庫(kù)文件放在 HTTP 的根目錄下,配置一個(gè)特定的 post-update
掛鉤(hook)就可以搞定(Git 掛鉤的細(xì)節(jié)見(jiàn)第 7 章)。此后,每個(gè)能訪問(wèn) Git 倉(cāng)庫(kù)所在服務(wù)器上 web 服務(wù)的人都可以進(jìn)行克隆操作。下面的操作可以允許通過(guò) HTTP 對(duì)倉(cāng)庫(kù)進(jìn)行讀?。?/p>
$ 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
掛鉤會(huì)默認(rèn)運(yùn)行合適的命令(git update-server-info
)來(lái)確保通過(guò) HTTP 的獲取和克隆正常工作。這條命令在你用 SSH 向倉(cāng)庫(kù)推送內(nèi)容時(shí)運(yùn)行;之后,其他人就可以用下面的命令來(lái)克隆倉(cāng)庫(kù):
$ git clone http://example.com/gitproject.git
在本例中,我們使用了 Apache 設(shè)定中常用的 /var/www/htdocs
路徑,不過(guò)你可以使用任何靜態(tài) web 服務(wù) — 把裸倉(cāng)庫(kù)放在它的目錄里就行。 Git 的數(shù)據(jù)是以最基本的靜態(tài)文件的形式提供的(關(guān)于如何提供文件的詳情見(jiàn)第 9 章)。
通過(guò) HTTP 進(jìn)行推送操作也是可能的,不過(guò)這種做法不太常見(jiàn),并且牽扯到復(fù)雜的 WebDAV 設(shè)定。由于很少用到,本書將略過(guò)對(duì)該內(nèi)容的討論。如果對(duì) HTTP 推送協(xié)議感興趣,不妨打開這個(gè)地址看一下操作方法:http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt
。通過(guò) HTTP 推送的好處之一是你可以使用任何 WebDAV 服務(wù)器,不需要為 Git 設(shè)定特殊環(huán)境;所以如果主機(jī)提供商支持通過(guò) WebDAV 更新網(wǎng)站內(nèi)容,你也可以使用這項(xiàng)功能。
使用 HTTP 協(xié)議的好處是易于架設(shè)。幾條必要的命令就可以讓全世界讀取到倉(cāng)庫(kù)的內(nèi)容?;ㄙM(fèi)不過(guò)幾分鐘。HTTP 協(xié)議不會(huì)占用過(guò)多服務(wù)器資源。因?yàn)樗话阒挥玫届o態(tài)的 HTTP 服務(wù)提供所有數(shù)據(jù),普通的 Apache 服務(wù)器平均每秒能支撐數(shù)千個(gè)文件的并發(fā)訪問(wèn) — 哪怕讓一個(gè)小型服務(wù)器超載都很難。
你也可以通過(guò) HTTPS 提供只讀的倉(cāng)庫(kù),這意味著你可以加密傳輸內(nèi)容;你甚至可以要求客戶端使用特定簽名的 SSL 證書。一般情況下,如果到了這一步,使用 SSH 公共密鑰可能是更簡(jiǎn)單的方案;不過(guò)也存在一些特殊情況,這時(shí)通過(guò) HTTPS 使用帶簽名的 SSL 證書或者其他基于 HTTP 的只讀連接授權(quán)方式是更好的解決方案。
HTTP 還有個(gè)額外的好處:HTTP 是一個(gè)如此常見(jiàn)的協(xié)議,以至于企業(yè)級(jí)防火墻通常都允許其端口的通信。
HTTP 協(xié)議的消極面在于,相對(duì)來(lái)說(shuō)客戶端效率更低。克隆或者下載倉(cāng)庫(kù)內(nèi)容可能會(huì)花費(fèi)更多時(shí)間,而且 HTTP 傳輸?shù)捏w積和網(wǎng)絡(luò)開銷比其他任何一個(gè)協(xié)議都大。因?yàn)樗鼪](méi)有按需供應(yīng)的能力 — 傳輸過(guò)程中沒(méi)有服務(wù)端的動(dòng)態(tài)計(jì)算 — 因而 HTTP 協(xié)議經(jīng)常會(huì)被稱為傻瓜(dumb)協(xié)議。更多 HTTP 協(xié)議和其他協(xié)議效率上的差異見(jiàn)第 9 章。
更多建議: