設定和配置
獲取和建立專案
基本快照
分支與合併
共享和更新專案
檢查和比較
打補丁
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
-
2.52.0
2025-11-17
- 2.44.1 → 2.51.2 無更改
-
2.44.0
2024-02-23
- 2.43.2 → 2.43.7 無變更
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.38.1 → 2.42.4 無更改
-
2.38.0
2022-10-02
描述
Git 支援兩種基於 HTTP 的傳輸協議。一種“愚蠢”(dumb)協議,只需要伺服器端有標準的 HTTP 伺服器,以及一種“智慧”(smart)協議,需要一個 Git 感知的 CGI(或伺服器模組)。本文件描述了這兩種協議。
作為一項設計特性,智慧客戶端可以自動將“愚蠢”協議的 URL 升級為智慧 URL。這允許所有使用者擁有相同的已釋出 URL,並且對等方會自動選擇對他們可用的最高效的傳輸方式。
URL 格式
透過 HTTP 訪問的 Git 倉庫的 URL 使用 RFC 1738 中定義的標準 HTTP URL 語法,因此它們的形式為:
http://<host>:<port>/<path>?<searchpart>
在此文件中,佔位符 $GIT_URL 將代表使用者輸入的 http:// 倉庫 URL。
伺服器應處理匹配 $GIT_URL 位置的所有請求,因為 Git 使用的“智慧”和“愚蠢” HTTP 協議都透過在使用者提供的 $GIT_URL 字串的末尾附加額外的路徑元件來工作。
一個愚蠢客戶端請求一個鬆散物件的示例
$GIT_URL: http://example.com:8080/git/repo.git URL request: http://example.com:8080/git/repo.git/objects/d0/49f6c27a2244e12041955e262a404c7faba355
一個智慧請求到達通配閘道器的示例
$GIT_URL: http://example.com/daemon.cgi?svc=git&q= URL request: http://example.com/daemon.cgi?svc=git&q=/info/refs&service=git-receive-pack
一個請求到子模組的示例
$GIT_URL: http://example.com/git/repo.git/path/submodule.git URL request: http://example.com/git/repo.git/path/submodule.git/info/refs
客戶端必須去除使用者提供的 $GIT_URL 字串末尾的 /(如果存在),以防止在傳送到伺服器的任何 URL 中出現空路徑標記(//)。相容的客戶端必須將 $GIT_URL/info/refs 展開為 foo/info/refs,而不是 foo//info/refs。
認證
如果需要認證才能訪問倉庫,則使用標準的 HTTP 認證,並且可以由 HTTP 伺服器軟體進行配置和強制執行。
由於 Git 倉庫是透過標準路徑元件訪問的,伺服器管理員可以使用其 HTTP 伺服器內的目錄許可權來控制倉庫訪問。
客戶端應支援 RFC 2617 中描述的 Basic 認證。伺服器應透過依賴位於 Git 伺服器軟體前面的 HTTP 伺服器來支援 Basic 認證。
伺服器不應要求 HTTP cookie 用於認證或訪問控制目的。
客戶端和伺服器可以支援其他常見的基於 HTTP 的認證形式,例如 Digest 認證。
會話狀態
Git over HTTP 協議(與 HTTP 本身非常相似)在 HTTP 伺服器端視角來看是無狀態的。所有狀態必須由客戶端程序保留和管理。這允許在伺服器端進行簡單的輪循負載均衡,而無需擔心狀態管理。
客戶端為了正確執行,不得要求伺服器端進行狀態管理。
伺服器為了正確執行,不得要求 HTTP cookie。客戶端可以在請求處理過程中儲存和轉發 HTTP cookie,如 RFC 2616 (HTTP/1.1) 所述。伺服器應忽略客戶端傳送的任何 cookie。
通用請求處理
除非另有說明,客戶端和伺服器都應假定所有標準的 HTTP 行為。這包括(但不限於)
如果 $GIT_URL 處沒有倉庫,或者匹配 $GIT_URL 的位置指向的資源不存在,伺服器不得響應 200 OK。伺服器應響應 404 Not Found、410 Gone 或任何其他不暗示資源按請求存在的合適 HTTP 狀態碼。
如果 $GIT_URL 處有倉庫,但當前不允許訪問,伺服器必須響應 403 Forbidden HTTP 狀態碼。
伺服器應同時支援 HTTP 1.0 和 HTTP 1.1。伺服器應支援請求和響應體的分塊編碼。
客戶端應同時支援 HTTP 1.0 和 HTTP 1.1。客戶端應支援請求和響應體的分塊編碼。
伺服器可以返回 ETag 和/或 Last-Modified 標頭。
客戶端可以透過包含 If-Modified-Since 和/或 If-None-Match 請求標頭來重新驗證快取的實體。
如果請求中出現了相關標頭且實體未更改,伺服器可以返回 304 Not Modified。客戶端必須將 304 Not Modified 與 200 OK 視為相同,並重用快取的實體。
如果 Cache-Control 和/或 Expires 標頭允許快取,客戶端可以不經重新驗證就重用快取的實體。客戶端和伺服器必須遵循 RFC 2616 來處理快取控制。
發現引用
所有 HTTP 客戶端在進行 fetch 或 push 交換時,都必須先發現遠端倉庫中可用的引用。
愚蠢客戶端
僅支援“愚蠢”協議的 HTTP 客戶端必須透過請求倉庫的特殊 info/refs 檔案來發現引用。
愚蠢 HTTP 客戶端必須向 $GIT_URL/info/refs 發起 GET 請求,不帶任何搜尋/查詢引數。
C: GET $GIT_URL/info/refs HTTP/1.0
S: 200 OK
S:
S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint
S: d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master
S: 2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0
S: a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}
返回的 info/refs 實體的 Content-Type 應為 text/plain; charset=utf-8,但可以是任何內容型別。客戶端不得嘗試驗證返回的內容型別。愚蠢伺服器不得返回以 application/x-git- 開頭的返回型別。
可以返回 Cache-Control 標頭來停用對返回實體的快取。
檢查響應時,客戶端應只檢查 HTTP 狀態碼。有效的響應是 200 OK 或 304 Not Modified。
返回的內容是描述每個 ref 及其已知值的 UNIX 格式文字檔案。檔案應按 C 語言環境排序。檔案不應包含名為 HEAD 的預設 ref。
info_refs = *( ref_record ) ref_record = any_ref / peeled_ref
any_ref = obj-id HTAB refname LF
peeled_ref = obj-id HTAB refname LF
obj-id HTAB refname "^{}" LF
智慧客戶端
支援“智慧”協議(或同時支援“智慧”和“愚蠢”協議)的 HTTP 客戶端必須透過請求倉庫的帶引數的 info/refs 檔案來發現引用。
請求必須只包含一個查詢引數,service=$servicename,其中 $servicename 必須是客戶端希望聯絡以完成操作的服務名稱。請求不得包含其他查詢引數。
C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0
愚蠢伺服器回覆
S: 200 OK
S:
S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint
S: d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master
S: 2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0
S: a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}
智慧伺服器回覆
S: 200 OK
S: Content-Type: application/x-git-upload-pack-advertisement
S: Cache-Control: no-cache
S:
S: 001e# service=git-upload-pack\n
S: 0000
S: 004895dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\0multi_ack\n
S: 003fd049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n
S: 003c2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n
S: 003fa3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n
S: 0000
客戶端可以在 Git-Protocol HTTP 標頭中以冒號分隔的字串形式傳送額外引數(參見 gitprotocol-pack[5])。
使用 git-upload-pack[1] 的 --http-backend-info-refs 選項。
智慧伺服器響應
如果伺服器不識別請求的服務名稱,或者請求的服務名稱已被伺服器管理員停用,則伺服器必須響應 403 Forbidden HTTP 狀態碼。
否則,智慧伺服器必須為請求的服務名稱響應智慧伺服器響應格式。
應使用 Cache-Control 標頭來停用對返回實體的快取。
Content-Type 必須是 application/x-$servicename-advertisement。如果返回了其他內容型別,客戶端應回退到愚蠢協議。回退到愚蠢協議時,客戶端不應向 $GIT_URL/info/refs 發起額外請求,而應使用已有的響應。如果不支援愚蠢協議,客戶端不得繼續。
客戶端必須驗證狀態碼是 200 OK 還是 304 Not Modified。
客戶端必須驗證響應實體的開頭五個位元組匹配正則表示式 ^[0-9a-f]{4}#。如果此測試失敗,客戶端不得繼續。
客戶端必須將整個響應解析為一系列 pkt-line 記錄。
客戶端必須驗證第一個 pkt-line 是 # service=$servicename。伺服器必須將 $servicename 設定為請求引數值。伺服器應在此行末尾包含一個 LF。客戶端應忽略行末的 LF。
伺服器必須以魔術 0000 結束 pkt-line 標記符來終止響應。
返回的響應是一個 pkt-line 流,描述每個 ref 及其已知值。流應按 C 語言環境排序。流應包含名為 HEAD 的預設 ref 作為第一個 ref。流必須在第一個 ref 後面透過 NUL 包含功能宣告。
如果“version=1”作為額外引數傳送,“version 1”將包含在返回的響應中。
smart_reply = PKT-LINE("# service=$servicename" LF)
"0000"
*1("version 1")
ref_list
"0000"
ref_list = empty_list / non_empty_list
empty_list = PKT-LINE(zero-id SP "capabilities^{}" NUL cap-list LF)
non_empty_list = PKT-LINE(obj-id SP name NUL cap_list LF)
*ref_record
cap-list = capability *(SP capability) capability = 1*(LC_ALPHA / DIGIT / "-" / "_") LC_ALPHA = %x61-7A
ref_record = any_ref / peeled_ref
any_ref = PKT-LINE(obj-id SP name LF)
peeled_ref = PKT-LINE(obj-id SP name LF)
PKT-LINE(obj-id SP name "^{}" LF
智慧服務 git-upload-pack
此服務從 $GIT_URL 指向的倉庫讀取。
客戶端必須首先使用 $GIT_URL/info/refs?service=git-upload-pack 進行引用發現。
C: POST $GIT_URL/git-upload-pack HTTP/1.0 C: Content-Type: application/x-git-upload-pack-request C: C: 0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n C: 0032have 441b40d833fdfa93eb2908e52742248faf0ee993\n C: 0000
S: 200 OK S: Content-Type: application/x-git-upload-pack-result S: Cache-Control: no-cache S: S: ....ACK %s, continue S: ....NAK
客戶端不得重用或重新驗證快取的響應。伺服器必須包含足夠的 Cache-Control 標頭以防止響應被快取。
伺服器應支援此處定義的所有功能。
客戶端必須在請求正文中至少傳送一個“want”命令。客戶端不得引用在引用發現過程中未出現在響應中的 ID,除非伺服器聲明瞭 allow-tip-sha1-in-want 或 allow-reachable-sha1-in-want 功能。
compute_request = want_list
have_list
request_end
request_end = "0000" / "done"
want_list = PKT-LINE(want SP cap_list LF)
*(want_pkt)
want_pkt = PKT-LINE(want LF)
want = "want" SP id
cap_list = capability *(SP capability)
have_list = *PKT-LINE("have" SP id LF)
待辦:進一步記錄。
協商演算法
選擇最小 pack 的計算過程如下(C = 客戶端,S = 伺服器)
初始化步驟
C:使用引用發現獲取廣告中的引用。
C:將看到的任何物件放入集合 advertised。
C:構建一個空集合 common,用於存放稍後確定在兩端都存在的物件。
C:構建一個集合 want,包含客戶端希望獲取的 advertised 中的物件,基於引用發現期間看到的內容。
C:啟動一個佇列 c_pending,按提交時間排序(最新的先彈出)。新增所有客戶端引用。當一個提交從佇列中彈出時,其父提交應自動插入回佇列。提交必須只進入佇列一次。
一次計算步驟
C:傳送一個 $GIT_URL/git-upload-pack 請求
C: 0032want <want-#1>............................... C: 0032want <want-#2>............................... .... C: 0032have <common-#1>............................. C: 0032have <common-#2>............................. .... C: 0032have <have-#1>............................... C: 0032have <have-#2>............................... .... C: 0000
流被組織成“命令”,每個命令單獨出現在一個 pkt-line 中。在命令列中,直到第一個空格的文字是命令名,行中到第一個 LF 的其餘部分是值。命令列以 LF 作為 pkt-line 值的最後一個位元組終止。
命令必須按以下順序出現,如果它們出現在請求流中
-
“want”
-
“have”
流以 pkt-line flush ( 0000 ) 終止。
一個“want”或“have”命令必須有一個十六進位制格式的物件名稱作為其值。多個物件名稱必須透過傳送多個命令來發送。物件名稱必須使用透過 object-format 功能協商的物件格式(預設為 SHA-1)給出。
have 列表是透過從 c_pending 中彈出前 32 個提交來建立的。如果 c_pending 為空,則可以提供更少的提交。
如果客戶端已傳送 256 個“have”提交,並且尚未收到來自 s_common 的其中一個,或者客戶端已清空 c_pending,則它應包含一個“done”命令,告知伺服器它不會繼續。
C: 0009done
S:解析 git-upload-pack 請求
驗證 want 中的所有物件是否可以直接從 ref 訪問。
伺服器可以向後遍歷歷史記錄或透過 reflog 來允許稍微過時的請求。
如果沒有收到“want”物件,則傳送錯誤:待辦:定義未請求“want”的錯誤。
如果任何“want”物件不可訪問,則傳送錯誤:待辦:定義無效“want”的錯誤。
建立一個空列表 s_common。
如果傳送了“have”
按客戶端提供的順序遍歷物件。
對於每個物件,如果伺服器有可從 ref 訪問的物件,則將其新增到 s_common。如果將提交新增到 s_common,則不新增任何祖先,即使它們也出現在 have 中。
S:傳送 git-upload-pack 響應
如果伺服器找到了要打包的封閉物件集,或者請求以“done”結束,則響應 pack。待辦:記錄基於 pack 的響應。
S: PACK...
返回的流是 git-upload-pack 服務支援的 side-band-64k 協議,pack 嵌入在流 1 中。來自伺服器端的進度訊息可以出現在流 2 中。
這裡的“封閉物件集”被定義為至少存在一條從每個“want”到至少一個“common”物件的路徑。
如果伺服器需要更多資訊,它會響應一個狀態繼續響應:待辦:記錄非 pack 響應。
C:解析 upload-pack 響應:待辦:記錄解析響應。
進行另一次計算步驟。
智慧服務 git-receive-pack
此服務從 $GIT_URL 指向的倉庫讀取。
客戶端必須首先使用 $GIT_URL/info/refs?service=git-receive-pack 進行引用發現。
C: POST $GIT_URL/git-receive-pack HTTP/1.0 C: Content-Type: application/x-git-receive-pack-request C: C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\0 report-status C: 0000 C: PACK....
S: 200 OK S: Content-Type: application/x-git-receive-pack-result S: Cache-Control: no-cache S: S: ....
客戶端不得重用或重新驗證快取的響應。伺服器必須包含足夠的 Cache-Control 標頭以防止響應被快取。
伺服器應支援此處定義的所有功能。
客戶端必須在請求正文中至少傳送一個命令。在請求正體的命令部分,客戶端應將透過引用發現獲得的 ID 作為 old_id 傳送。
update_request = command_list
"PACK" <binary-data>
command_list = PKT-LINE(command NUL cap_list LF)
*(command_pkt)
command_pkt = PKT-LINE(command LF)
cap_list = *(SP capability) SP
command = create / delete / update create = zero-id SP new_id SP name delete = old_id SP zero-id SP name update = old_id SP new_id SP name
待辦:進一步記錄。