4.1 協(xié)議

2018-02-24 15:22 更新

協(xié)議

Git 可以使用四種主要的協(xié)議來(lái)傳輸資料:本地協(xié)議(Local),HTTP 協(xié)議,SSH(Secure Shell)協(xié)議及 Git 協(xié)議。在此,我們將會(huì)討論那些協(xié)議及哪些情形應(yīng)該使用(或避免使用)他們。

本地協(xié)議

最基本的就是 本地協(xié)議(Local protocol) ,其中的遠(yuǎn)程版本庫(kù)就是硬盤(pán)內(nèi)的另一個(gè)目錄。這常見(jiàn)于團(tuán)隊(duì)每一個(gè)成員都對(duì)一個(gè)共享的文件系統(tǒng)(例如一個(gè)掛載的 NFS)擁有訪問(wèn)權(quán),或者比較少見(jiàn)的多人共用同一臺(tái)電腦的情況。后者并不理想,因?yàn)槟愕乃写a版本庫(kù)如果長(zhǎng)存于同一臺(tái)電腦,更可能發(fā)生災(zāi)難性的損失。

如果你使用共享文件系統(tǒng),就可以從本地版本庫(kù)克?。╟lone)、推送(push)以及拉取(pull)。像這樣去克隆一個(gè)版本庫(kù)或者增加一個(gè)遠(yuǎn)程到現(xiàn)有的項(xiàng)目中,使用版本庫(kù)路徑作為 URL。例如,克隆一個(gè)本地版本庫(kù),可以執(zhí)行如下的命令:

$ git clone /opt/git/project.git

或你可以執(zhí)行這個(gè)命令:

$ git clone file:///opt/git/project.git

如果在 URL 開(kāi)頭明確的指定 file://,那么 Git 的行為會(huì)略有不同。如果僅是指定路徑,Git 會(huì)嘗試使用硬鏈接(hard link)或直接復(fù)制所需要的文件。如果指定 file://,Git 會(huì)觸發(fā)平時(shí)用于網(wǎng)路傳輸資料的進(jìn)程,那通常是傳輸效率較低的方法。指定 file:// 的主要目的是取得一個(gè)沒(méi)有外部參考(extraneous references)或?qū)ο螅╫bject)的干凈版本庫(kù)副本– 通常是在從其他版本控制系統(tǒng)導(dǎo)入后或一些類(lèi)似情況(參見(jiàn) Chapter?10 for maintenance tasks)需要這么做。在此我們將使用普通路徑,因?yàn)檫@樣通常更快。

要增加一個(gè)本地版本庫(kù)到現(xiàn)有的 Git 項(xiàng)目,可以執(zhí)行如下的命令:

$ git remote add local_proj /opt/git/project.git

然后,就可以像在網(wǎng)絡(luò)上一樣從遠(yuǎn)端版本庫(kù)推送和拉取更新了。

優(yōu)點(diǎn)

基于文件系統(tǒng)的版本庫(kù)的優(yōu)點(diǎn)是簡(jiǎn)單,并且直接使用了現(xiàn)有的文件權(quán)限和網(wǎng)絡(luò)訪問(wèn)權(quán)限。如果你的團(tuán)隊(duì)已經(jīng)有共享文件系統(tǒng),建立版本庫(kù)會(huì)十分容易。只需要像設(shè)置其他共享目錄一樣,把一個(gè)裸版本庫(kù)的副本放到大家都可以訪問(wèn)的路徑,并設(shè)置好讀/寫(xiě)的權(quán)限,就可以了,我們會(huì)在 “在服務(wù)器上搭建 Git” 討論如何導(dǎo)出一個(gè)裸版本庫(kù)。

這也是快速?gòu)膭e人的工作目錄中拉取更新的方法。如果你和別人一起合作一個(gè)項(xiàng)目,他想讓你從版本庫(kù)中拉取更新時(shí),運(yùn)行類(lèi)似 git pull /home/john/project 的命令比推送到服務(wù)再取回簡(jiǎn)單多了。

缺點(diǎn)

這種方法的缺點(diǎn)是,通常共享文件系統(tǒng)比較難配置,并且比起基本的網(wǎng)絡(luò)連接訪問(wèn),這不方便從多個(gè)位置訪問(wèn)。如果你想從家里推送內(nèi)容,必須先掛載一個(gè)遠(yuǎn)程磁盤(pán),相比網(wǎng)絡(luò)連接的訪問(wèn)方式,配置不方便,速度也慢。

值得一提的是,如果你使用的是類(lèi)似于共享掛載的文件系統(tǒng)時(shí),這個(gè)方法不一定是最快的。訪問(wèn)本地版本庫(kù)的速度與你訪問(wèn)數(shù)據(jù)的速度是一樣的。在同一個(gè)服務(wù)器上,如果允許 Git 訪問(wèn)本地硬盤(pán),一般的通過(guò) NFS 訪問(wèn)版本庫(kù)要比通過(guò) SSH 訪問(wèn)慢。

最終,這個(gè)協(xié)議并不保護(hù)倉(cāng)庫(kù)避免意外的損壞。每一個(gè)用戶都有“遠(yuǎn)程”目錄的完整 shell 權(quán)限,沒(méi)有方法可以阻止他們修改或刪除 Git 內(nèi)部文件和損壞倉(cāng)庫(kù)。

HTTP 協(xié)議

Git 通過(guò) HTTP 通信有兩種模式。在 Git 1.6.6 版本之前只有一個(gè)方式可用,十分簡(jiǎn)單并且通常是只讀模式的。Git 1.6.6 版本引入了一種新的、更智能的協(xié)議,讓 Git 可以像通過(guò) SSH 那樣智能的協(xié)商和傳輸數(shù)據(jù)。之后幾年,這個(gè)新的 HTTP 協(xié)議因?yàn)槠浜?jiǎn)單、智能變的十分流行。新版本的 HTTP 協(xié)議一般被稱(chēng)為“智能” HTTP 協(xié)議,舊版本的一般被稱(chēng)為“啞” HTTP 協(xié)議。我們先了解一下新的“智能” HTTP 協(xié)議。

智能(Smart) HTTP 協(xié)議

“智能” HTTP 協(xié)議的運(yùn)行方式和 SSH 及 Git 協(xié)議類(lèi)似,只是運(yùn)行在標(biāo)準(zhǔn)的 HTTP/S 端口上并且可以使用各種 HTTP 驗(yàn)證機(jī)制,這意味著使用起來(lái)會(huì)比 SSH 協(xié)議簡(jiǎn)單的多,比如可以使用 HTTP 協(xié)議的用戶名/密碼的基礎(chǔ)授權(quán),免去設(shè)置 SSH 公鑰。

智能 HTTP 協(xié)議或許已經(jīng)是最流行的使用 Git 的方式了,它即支持像 git:// 協(xié)議一樣設(shè)置匿名服務(wù),也可以像 SSH 協(xié)議一樣提供傳輸時(shí)的授權(quán)和加密。而且只用一個(gè) URL 就可以都做到,省去了為不同的需求設(shè)置不同的 URL。如果你要推送到一個(gè)需要授權(quán)的服務(wù)器上(一般來(lái)講都需要),服務(wù)器會(huì)提示你輸入用戶名和密碼。從服務(wù)器獲取數(shù)據(jù)時(shí)也一樣。

事實(shí)上,類(lèi)似 GitHub 的服務(wù),你在網(wǎng)頁(yè)上看到的 URL (比如, https://github.com/schacon/simplegit[]),和你在克隆、推送(如果你有權(quán)限)時(shí)使用的是一樣的。

?。―umb) HTTP 協(xié)議

如果服務(wù)器沒(méi)有提供智能 HTTP 協(xié)議的服務(wù),Git 客戶端會(huì)嘗試使用更簡(jiǎn)單的“啞” HTTP 協(xié)議。啞 HTTP 協(xié)議里 web 服務(wù)器僅把裸版本庫(kù)當(dāng)作普通文件來(lái)對(duì)待,提供文件服務(wù)。啞 HTTP 協(xié)議的優(yōu)美之處在于設(shè)置起來(lái)簡(jiǎn)單?;旧?,只需要把一個(gè)裸版本庫(kù)放在 HTTP 跟目錄,設(shè)置一個(gè)叫做 post-update 的掛鉤就可以了(見(jiàn) “Git 鉤子”)。此時(shí),只要能訪問(wèn) web 服務(wù)器上你的版本庫(kù),就可以克隆你的版本庫(kù)。下面是設(shè)置從 HTTP 訪問(wèn)版本庫(kù)的方法:

$ 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)執(zhí)行合適的命令(git update-server-info),來(lái)確保通過(guò) HTTP 的獲取和克隆操作正常工作。這條命令會(huì)在你通過(guò) SSH 向版本庫(kù)推送之后被執(zhí)行;然后別人就可以通過(guò)類(lèi)似下面的命令來(lái)克?。?/p>

$ git clone https://example.com/gitproject.git

這里我們用了 Apache 里設(shè)置了常用的路徑 /var/www/htdocs,不過(guò)你可以使用任何靜態(tài) web 服務(wù)器 —— 只需要把裸版本庫(kù)放到正確的目錄下就可以。Git 的數(shù)據(jù)是以基本的靜態(tài)文件形式提供的(詳情見(jiàn) Chapter?10)。

通常的,會(huì)在可以提供讀/寫(xiě)的智能 HTTP 服務(wù)和簡(jiǎn)單的只讀的啞 HTTP 服務(wù)之間選一個(gè)。極少會(huì)將二者混合提供服務(wù)。

優(yōu)點(diǎn)

我們將只關(guān)注智能 HTTP 協(xié)議的優(yōu)點(diǎn)。

不同的訪問(wèn)方式只需要一個(gè) URL 以及服務(wù)器只在需要授權(quán)時(shí)提示輸入授權(quán)信息,這兩個(gè)簡(jiǎn)便性讓終端用戶使用 Git 變得非常簡(jiǎn)單。相比 SSH 協(xié)議,可以使用用戶名/密碼授權(quán)是一個(gè)很大的優(yōu)勢(shì),這樣用戶就不必須在使用 Git 之前先在本地生成 SSH 密鑰對(duì)再把公鑰上傳到服務(wù)器。對(duì)非資深的使用者,或者系統(tǒng)上缺少 SSH 相關(guān)程序的使用者,HTTP 協(xié)議的可用性是主要的優(yōu)勢(shì)。與 SSH 協(xié)議類(lèi)似,HTTP 協(xié)議也非??旌透咝А?/p>

你也可以在 HTTPS 協(xié)議上提供只讀版本庫(kù)的服務(wù),如此你在傳輸數(shù)據(jù)的時(shí)候就可以加密數(shù)據(jù);或者,你甚至可以讓客戶端使用指定的 SSL 證書(shū)。

另一個(gè)好處是 HTTP/S 協(xié)議被廣泛使用,一般的企業(yè)防火墻都會(huì)允許這些端口的數(shù)據(jù)通過(guò)。

缺點(diǎn)

在一些服務(wù)器上,架設(shè) HTTP/S 協(xié)議的服務(wù)端會(huì)比 SSH 協(xié)議的棘手一些。除了這一點(diǎn),用其他協(xié)議提供 Git 服務(wù)與 “智能” HTTP 協(xié)議相比就幾乎沒(méi)有優(yōu)勢(shì)了。

如果你在 HTTP 上使用需授權(quán)的推送,管理憑證會(huì)比使用 SSH 密鑰認(rèn)證麻煩一些。然而,你可以選擇使用憑證存儲(chǔ)工具,比如 OSX 的 Keychain 或者 Windows 的憑證管理器。參考 “憑證存儲(chǔ)” 如何安全地保存 HTTP 密碼。

SSH 協(xié)議

架設(shè) Git 服務(wù)器時(shí)常用 SSH 協(xié)議作為傳輸協(xié)議。因?yàn)榇蠖鄶?shù)環(huán)境下已經(jīng)支持通過(guò) SSH 訪問(wèn) —— 即時(shí)沒(méi)有也比較很容易架設(shè)。SSH 協(xié)議也是一個(gè)驗(yàn)證授權(quán)的網(wǎng)絡(luò)協(xié)議;并且,因?yàn)槠淦毡樾裕茉O(shè)和使用都很容易。

通過(guò) SSH 協(xié)議克隆版本庫(kù),你可以指定一個(gè) ssh:// 的 URL:

$ git clone ssh://user@server/project.git

或者使用一個(gè)簡(jiǎn)短的 scp 式的寫(xiě)法:

$ git clone user@server:project.git

你也可以不指定用戶,Git 會(huì)使用當(dāng)前登錄的用戶名。

優(yōu)勢(shì)

用 SSH 協(xié)議的優(yōu)勢(shì)有很多。首先,SSH 架設(shè)相對(duì)簡(jiǎn)單 —— SSH 守護(hù)進(jìn)程很常見(jiàn),多數(shù)管理員都有使用經(jīng)驗(yàn),并且多數(shù)操作系統(tǒng)都包含了它及相關(guān)的管理工具。其次,通過(guò) SSH 訪問(wèn)是安全的 —— 所有傳輸數(shù)據(jù)都要經(jīng)過(guò)授權(quán)和加密。最后,與 HTTP/S 協(xié)議、Git 協(xié)議及本地協(xié)議一樣,SSH 協(xié)議很高效,在傳輸前也會(huì)盡量壓縮數(shù)據(jù)。

缺點(diǎn)

SSH 協(xié)議的缺點(diǎn)在于你不能通過(guò)他實(shí)現(xiàn)匿名訪問(wèn)。即便只要讀取數(shù)據(jù),使用者也要有通過(guò) SSH 訪問(wèn)你的主機(jī)的權(quán)限,這使得 SSH 協(xié)議不利于開(kāi)源的項(xiàng)目。如果你只在公司網(wǎng)絡(luò)使用,SSH 協(xié)議可能是你唯一要用到的協(xié)議。如果你要同時(shí)提供匿名只讀訪問(wèn)和 SSH 協(xié)議,那么你除了為自己推送架設(shè) SSH 服務(wù)以外,還得架設(shè)一個(gè)可以讓其他人訪問(wèn)的服務(wù)。

Git 協(xié)議

接下來(lái)是 Git 協(xié)議。這是包含在 Git 里的一個(gè)特殊的守護(hù)進(jìn)程;它監(jiān)聽(tīng)在一個(gè)特定的端口(9418),類(lèi)似于 SSH 服務(wù),但是訪問(wèn)無(wú)需任何授權(quán)。要讓版本庫(kù)支持 Git 協(xié)議,需要先創(chuàng)建一個(gè) git-daemon-export-ok 文件 —— 它是 Git 協(xié)議守護(hù)進(jìn)程為這個(gè)版本庫(kù)提供服務(wù)的必要條件 —— 但是除此之外沒(méi)有任何安全措施。要么誰(shuí)都可以克隆這個(gè)版本庫(kù),要么誰(shuí)也不能。這意味這,通常不能通過(guò) Git 協(xié)議推送。由于沒(méi)有授權(quán)機(jī)制,一旦你開(kāi)放推送操作,意味著網(wǎng)絡(luò)上知道這個(gè)項(xiàng)目 URL 的人都可以向項(xiàng)目推送數(shù)據(jù)。不用說(shuō),極少會(huì)有人這么做。

優(yōu)點(diǎn)

目前,Git 協(xié)議是 Git 使用的網(wǎng)絡(luò)傳輸協(xié)議里最快的。如果你的項(xiàng)目有很大的訪問(wèn)量,或者你的項(xiàng)目很龐大并且不需要為寫(xiě)進(jìn)行用戶授權(quán),架設(shè) Git 守護(hù)進(jìn)程來(lái)提供服務(wù)是不錯(cuò)的選擇。它使用與 SSH 相同的數(shù)據(jù)傳輸機(jī)制,但是省去了加密和授權(quán)的開(kāi)銷(xiāo)。

缺點(diǎn)

Git 協(xié)議缺點(diǎn)是缺乏授權(quán)機(jī)制。把 Git 協(xié)議作為訪問(wèn)項(xiàng)目版本庫(kù)的唯一手段是不可取的。一般的做法里,會(huì)同時(shí)提供 SSH 或者 HTTPS 協(xié)議的訪問(wèn)服務(wù),只讓少數(shù)幾個(gè)開(kāi)發(fā)者有推送(寫(xiě))權(quán)限,其他人通過(guò) git:// 訪問(wèn)只有讀權(quán)限。Git 協(xié)議也許也是最難架設(shè)的。它要求有自己的守護(hù)進(jìn)程,這就要配置 xinetd 或者其他的程序,這些工作并不簡(jiǎn)單。它還要求防火墻開(kāi)放 9418 端口,但是企業(yè)防火墻一般不會(huì)開(kāi)放這個(gè)非標(biāo)準(zhǔn)端口。而大型的企業(yè)防火墻通常會(huì)封鎖這個(gè)端口。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)