Git
章節 ▾ 第二版

4.1 伺服器上的 Git - 通訊協定

至此,您應該能夠執行大多數您將使用 Git 的日常任務。但是,為了在 Git 中進行任何協作,您需要有一個遠端 Git 儲存庫。雖然技術上您可以將變更推送到個人儲存庫並從中提取變更,但不建議這樣做,因為如果您不小心,可能會很容易混淆他們正在處理的內容。此外,您希望您的協作者即使在您的電腦離線時也能夠存取儲存庫 — 擁有一個更可靠的通用儲存庫通常很有用。因此,與他人協作的首選方法是設定一個您們都可以存取的中間儲存庫,並從該儲存庫推送和提取變更。

執行 Git 伺服器相當簡單。首先,您選擇要讓您的伺服器支援的協定。本章的第一節將介紹可用的協定以及每個協定的優缺點。下一節將解釋使用這些協定的一些典型設定,以及如何讓您的伺服器使用它們執行。最後,我們將介紹一些託管選項,如果您不介意將程式碼託管在其他人的伺服器上,並且不想經歷設定和維護自己伺服器的麻煩。

如果您對執行自己的伺服器沒有興趣,您可以跳到本章的最後一節,查看一些設定託管帳戶的選項,然後繼續下一章,我們將討論在分散式原始碼控制環境中工作的各種細節。

遠端儲存庫通常是一個裸儲存庫 — 一個沒有工作目錄的 Git 儲存庫。由於儲存庫僅用作協作點,因此沒有理由在磁碟上檢查出快照;它只是 Git 資料。簡單來說,裸儲存庫是您專案的 .git 目錄的內容,沒有其他內容。

通訊協定

Git 可以使用四種不同的協定來傳輸資料:本機、HTTP、安全殼層 (SSH) 和 Git。在這裡,我們將討論它們是什麼,以及在哪些基本情況下您會想要 (或不想要) 使用它們。

本機協定

最基本的是本機協定,其中遠端儲存庫位於同一主機上的另一個目錄中。如果您的團隊中的每個人都可以存取共用檔案系統,例如 NFS 掛載,或者在不太可能的情況下,每個人都登入同一台電腦,則通常會使用此協定。後者並非理想選擇,因為所有程式碼儲存庫實例都將位於同一台電腦上,使得災難性遺失的可能性更高。

如果您有一個共用的已掛載檔案系統,則可以複製、推送和從基於本機檔案的儲存庫提取。若要複製這樣的儲存庫,或將其作為遠端新增至現有專案,請使用儲存庫的路徑作為 URL。例如,若要複製本機儲存庫,您可以執行類似以下的命令

$ git clone /srv/git/project.git

或者您可以這樣做

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

如果您在 URL 的開頭明確指定 file://,Git 的運作方式會稍微不同。如果您僅指定路徑,Git 會嘗試使用硬連結或直接複製它需要的檔案。如果您指定 file://,Git 會啟動它通常用來透過網路傳輸資料的程序,這通常效率較低。指定 file:// 字首的主要原因是,如果您想要儲存庫的乾淨副本,其中省略了多餘的參照或物件,通常是在從其他 VCS 匯入或類似的情況之後(請參閱Git 內部機制以了解維護任務)。我們將在此處使用正常路徑,因為這樣做幾乎總是更快。

若要將本機儲存庫新增至現有的 Git 專案,您可以執行類似以下的命令

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

然後,您可以透過新的遠端名稱 local_proj 推送和提取該遠端,就像您透過網路執行一樣。

優點

基於檔案的儲存庫的優點是它們很簡單,並且使用現有的檔案權限和網路存取。如果您已經有一個整個團隊都可以存取的共用檔案系統,則設定儲存庫非常容易。您將裸儲存庫副本放在每個人都有共用存取權限的地方,並設定讀/寫權限,就像對待任何其他共用目錄一樣。我們將在在伺服器上取得 Git中討論如何匯出用於此目的的裸儲存庫副本。

這也是快速從其他人的工作儲存庫獲取工作的絕佳選擇。如果您和一位同事正在同一個專案上工作,並且他們希望您檢查一些東西,執行類似 git pull /home/john/project 的命令通常比他們推送至遠端伺服器,然後您從該伺服器擷取要容易得多。

缺點

此方法的缺點是,與基本的網路存取相比,共用存取通常更難以設定並從多個位置存取。如果您想在家的筆記型電腦上推送,則必須掛載遠端磁碟,這與基於網路的存取相比可能很困難且速度慢。

重要的是要提到,如果您正在使用某種共用掛載,這不一定是速度最快的選項。僅當您可以快速存取資料時,本機儲存庫才快速。在 NFS 上的儲存庫通常比在同一伺服器上透過 SSH 的儲存庫慢,允許 Git 在每個系統上的本機磁碟上執行。

最後,此協定不會保護儲存庫免受意外損壞。每個使用者都對「遠端」目錄具有完整的 Shell 存取權,並且沒有任何東西阻止他們變更或移除內部 Git 檔案並損壞儲存庫。

HTTP 協定

Git 可以使用兩種不同的模式透過 HTTP 通訊。在 Git 1.6.6 之前,只有一種方法可以做到這一點,這種方法非常簡單且通常是唯讀的。在 1.6.6 版中,引入了一種新的、更智慧的協定,該協定涉及 Git 能夠以類似於它透過 SSH 進行資料傳輸的方式來智慧地協商資料傳輸。在過去幾年中,這種新的 HTTP 協定變得非常受歡迎,因為它對使用者來說更簡單,並且在如何通訊方面更智慧。較新的版本通常稱為智慧 HTTP 協定,而較舊的方法稱為愚笨 HTTP。我們將首先介紹較新的智慧 HTTP 協定。

智慧 HTTP

智慧 HTTP 的運作方式與 SSH 或 Git 協定非常相似,但在標準 HTTPS 連接埠上執行,並且可以使用各種 HTTP 驗證機制,這意味著它通常比 SSH 之類的東西對使用者更容易,因為您可以使用使用者名稱/密碼驗證之類的內容,而不必設定 SSH 金鑰。

它可能已成為現在使用 Git 最受歡迎的方式,因為它可以設定為像 git:// 協定一樣匿名服務,也可以像 SSH 協定一樣透過驗證和加密進行推送。現在,您可以使用單一 URL 來處理這兩件事,而不必為這些事情設定不同的 URL。如果您嘗試推送並且儲存庫需要驗證(通常應該這樣),則伺服器可以提示輸入使用者名稱和密碼。讀取存取也是如此。

實際上,對於像 GitHub 這樣的服務,您用來在線上檢視儲存庫的 URL(例如,https://github.com/schacon/simplegit)與您可以用來複製以及(如果您有權限)推送的 URL 相同。

愚笨 HTTP

如果伺服器沒有回應 Git HTTP 智慧服務,Git 用戶端將嘗試返回到更簡單的愚笨 HTTP 協定。愚笨協定期望從 Web 伺服器像普通檔案一樣服務裸 Git 儲存庫。愚笨 HTTP 的優點是設定簡單。基本上,您所要做的就是將裸 Git 儲存庫放在您的 HTTP 文件根目錄下並設定特定的 post-update Hook,這樣就完成了(請參閱Git Hook)。屆時,任何可以存取您放置儲存庫的 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 Hook 會執行適當的命令(git update-server-info),以使 HTTP 擷取和複製正常工作。當您(可能透過 SSH)推送至此儲存庫時,會執行此命令;然後,其他人可以透過類似以下的方式複製

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

在這個特定的例子中,我們正在使用 Apache 設定中常見的 /var/www/htdocs 路徑,但您可以使用任何靜態 Web 伺服器,只需將裸儲存庫放在其路徑中即可。Git 資料會作為基本的靜態檔案提供(請參閱Git 內部機制章節,以了解它如何確切地提供服務)。

通常,您會選擇執行讀/寫智慧 HTTP 伺服器,或僅以愚笨方式讓檔案以唯讀方式存取。很少同時執行這兩項服務。

優點

我們將重點介紹智慧版本 HTTP 協定的優點。

為所有類型的存取提供單一 URL,並且僅在需要驗證時才提示伺服器的簡便性,使得最終使用者非常容易。能夠使用使用者名稱和密碼進行驗證也是比 SSH 更大的優勢,因為使用者不必在本機產生 SSH 金鑰,並在能夠與其互動之前將其公開金鑰上傳到伺服器。對於不太複雜的使用者或 SSH 不太常見的系統上的使用者來說,這在可用性方面是一個主要優勢。它也是一個非常快速且有效率的協定,與 SSH 協定類似。

您也可以透過 HTTPS 以唯讀方式提供儲存庫,這表示您可以加密內容傳輸;或者,您可以進一步讓用戶端使用特定的已簽署 SSL 憑證。

另一個好處是 HTTP 和 HTTPS 是如此常用的協定,以至於公司防火牆通常會設定為允許流量透過其連接埠。

缺點

與某些伺服器上的 SSH 相比,透過 HTTPS 設定 Git 可能會稍微棘手。除此之外,其他協定在提供 Git 內容方面幾乎沒有比智慧 HTTP 更大的優勢。

如果您使用 HTTP 進行驗證推送,則提供您的憑證有時比使用 SSH 金鑰更複雜。但是,您可以使用多種憑證快取工具,包括 macOS 上的鑰匙圈存取和 Windows 上的認證管理員,來使此過程變得非常輕鬆。請閱讀憑證儲存,以了解如何在您的系統上設定安全的 HTTP 密碼快取。

SSH 協定

自行託管時,Git 的常見傳輸協定是透過 SSH。這是因為大多數地方已經設定了對伺服器的 SSH 存取,而且如果沒有,也很容易做到。SSH 也是經過驗證的網路協定,而且由於它無處不在,因此通常很容易設定和使用。

若要透過 SSH 複製 Git 儲存庫,您可以指定類似以下的 ssh:// URL

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

或者,您可以使用 SSH 協定的較短的類似 scp 的語法

$ git clone [user@]server:project.git

在上述兩種情況下,如果您沒有指定選用的使用者名稱,Git 會假設您目前登入的使用者。

優點

使用 SSH 的優點很多。首先,SSH 相對容易設定,SSH 精靈很常見,許多網路管理員都有使用它們的經驗,並且許多 OS 發行版都設定了它們或具有管理它們的工具。其次,透過 SSH 的存取是安全的,所有資料傳輸都是加密和驗證的。最後,與 HTTPS、Git 和本機協定一樣,SSH 也很有效率,可以在傳輸之前盡可能地壓縮資料。

缺點

SSH 的負面方面是它不支援對您的 Git 儲存庫進行匿名存取。如果您使用 SSH,即使是以唯讀方式,人們必須具有您機器的 SSH 存取權,這不利於人們可能只想複製您的儲存庫以進行檢查的開放原始碼專案。如果您僅在公司網路內使用它,則 SSH 可能是您需要處理的唯一協定。如果您想允許對您的專案進行匿名唯讀存取,並且還想使用 SSH,則必須設定 SSH 以供您推送,但設定其他東西供其他人擷取。

Git 協定

最後,我們有 Git 協定。這是一個與 Git 一起封裝的特殊精靈;它會在專用的連接埠 (9418) 上偵聽,該連接埠提供的服務類似於 SSH 協定,但絕對沒有驗證或加密。為了透過 Git 協定服務儲存庫,您必須建立 git-daemon-export-ok 檔案,該精靈不會在沒有該檔案的情況下服務儲存庫,但除此之外,沒有任何安全性。Git 儲存庫要么可供所有人複製,要么不可用。這表示通常無法透過此協定進行推送。您可以啟用推送存取,但由於缺乏驗證,網路上任何找到您專案 URL 的人都可以推送至該專案。可以說這種情況很少見。

優點

Git 協定通常是可用的最快速網路傳輸協定。如果您為公開專案提供大量流量,或者服務一個不需要使用者身份驗證即可讀取的非常大型的專案,那麼您很可能會希望設定一個 Git 精靈來服務您的專案。它使用與 SSH 協定相同的資料傳輸機制,但沒有加密和身份驗證的額外負擔。

缺點

由於缺乏 TLS 或其他加密方式,透過 git:// 進行克隆可能會導致任意程式碼執行漏洞,因此除非您清楚自己在做什麼,否則應避免使用。

  • 如果您執行 git clone git://example.com/project.git,控制您的路由器等攻擊者可以修改您剛克隆的儲存庫,將惡意程式碼插入其中。如果您隨後編譯/執行您剛克隆的程式碼,您將執行惡意程式碼。基於相同的原因,應該避免執行 git clone http://example.com/project.git

  • 執行 git clone https://example.com/project.git 不會遇到相同的問題(除非攻擊者可以為 example.com 提供 TLS 憑證)。 執行 git clone git@example.com:project.git 只有在您接受錯誤的 SSH 金鑰指紋時才會遇到此問題。

它也沒有身份驗證,也就是說,任何人都可以克隆儲存庫(儘管這通常正是您想要的)。它也可能是最難設定的協定。它必須運行自己的精靈,這需要 xinetdsystemd 配置之類的設定,這並不總是那麼容易。它還需要防火牆允許存取 9418 埠,這不是公司防火牆總是允許的標準埠。在大型公司防火牆後面,這個不明顯的埠通常會被封鎖。

scroll-to-top