-
A1. 附錄 A: Git 在其他環境
- A1.1 圖形介面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 PowerShell 中的 Git
- A1.9 小結
-
A2. 附錄 B: 在應用程式中嵌入 Git
-
A3. 附錄 C: Git 命令
4.1 Git 伺服器 - 協議
至此,你應該已經能夠完成大部分日常使用的 Git 任務。然而,要在 Git 中進行任何協作,你需要有一個遠端 Git 倉庫。雖然你可以在技術上將更改推送到個人倉庫或從其拉取更改,但我們不建議這樣做,因為如果不小心,你很容易混淆他們的工作。此外,你希望你的協作者即使你的計算機離線也能夠訪問倉庫——擁有一個更可靠的公共倉庫通常很有用。因此,與他人協作的首選方法是設定一個你們都可以訪問的中間倉庫,並從中進行推送和拉取。
執行 Git 伺服器相當簡單。首先,你選擇伺服器要支援的協議。本章的第一節將介紹可用的協議及其優缺點。接下來的幾節將解釋使用這些協議的一些典型設定以及如何使你的伺服器執行它們。最後,如果你不介意將程式碼託管在別人的伺服器上,並且不想經歷設定和維護自己伺服器的麻煩,我們將介紹一些託管選項。
如果你對執行自己的伺服器不感興趣,可以跳到本章的最後一節,檢視設定託管賬戶的一些選項,然後轉到下一章,我們將討論在分散式版本控制環境中工作的各種細節。
遠端倉庫通常是裸倉庫——一個沒有工作目錄的 Git 倉庫。由於倉庫僅用作協作點,因此沒有理由在磁碟上檢出快照;它只是 Git 資料。簡單來說,裸倉庫就是你的專案 .git
目錄的內容,僅此而已。
協議
Git 可以使用四種不同的協議來傳輸資料:本地協議(Local)、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 訪問的倉庫慢,因為 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協議。啞協議期望裸 Git 倉庫像普通檔案一樣從 Web 伺服器提供服務。啞 HTTP 的優點是設定簡單。基本上,你所要做的就是將一個裸 Git 倉庫放在你的 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 協議智慧版本的優點。
所有型別的訪問都使用單一 URL,並且僅在需要認證時才由伺服器提示,這種簡單性使得終端使用者操作非常方便。能夠使用使用者名稱和密碼進行認證也是相對於 SSH 的一個巨大優勢,因為使用者不必在本地生成 SSH 金鑰並將公共金鑰上傳到伺服器才能與其互動。對於經驗不足的使用者,或在 SSH 不太常見的系統上的使用者,這在可用性方面是一個主要優勢。它也是一種非常快速高效的協議,類似於 SSH。
你還可以透過 HTTPS 提供倉庫的只讀訪問,這意味著你可以加密內容傳輸;或者你可以更進一步,讓客戶端使用特定的簽名 SSL 證書。
另一個優點是 HTTP 和 HTTPS 是如此常用的協議,以至於公司防火牆通常被設定為允許透過其埠的流量。
缺點
在某些伺服器上,透過 HTTPS 使用 Git 可能比 SSH 更難設定一些。除此之外,其他協議在提供 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 守護程序很常見,許多網路管理員都有使用它們的經驗,並且許多作業系統發行版都預裝了它們或有管理它們的工具。其次,透過 SSH 的訪問是安全的——所有資料傳輸都經過加密和認證。最後,像 HTTPS、Git 和本地協議一樣,SSH 效率高,在傳輸資料之前使其儘可能緊湊。
缺點
SSH 的負面影響是它不支援對 Git 倉庫的匿名訪問。如果你使用 SSH,人們必須擁有對你機器的 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 金鑰指紋時才會遇到此問題。
它也沒有認證,也就是說,任何人都可以克隆倉庫(儘管這通常正是你想要的)。它也可能是最難設定的協議。它必須執行自己的守護程序,這需要 xinetd
或 systemd
配置或類似的東西,這並不總是輕而易舉。它還需要防火牆開放 9418 埠,這不是公司防火牆總是允許的標準埠。在大型公司防火牆後面,這個不常用的埠通常會被阻塞。