Git
英文 ▾ 主題 ▾ 最新版本 ▾ gitprotocol-capabilities 最後更新於 2.44.0

名稱

gitprotocol-capabilities - 協定 v0 和 v1 功能

概要

<over-the-wire-protocol>

描述

注意
本文描述封包協定版本 0 和 1 的功能。關於版本 2,請參考 gitprotocol-v2[5] 文件。

伺服器應支援本文中定義的所有功能。

在 receive-pack 和 upload-pack 的初始伺服器回應的第一行中,第一個參考之後會接著一個 NUL 位元組,然後是一個以空格分隔的伺服器功能列表。這些功能允許伺服器宣告它可以和不能支援的內容給客戶端。

客戶端會接著發送一個以空格分隔的功能列表,這些功能是它想要生效的。客戶端不得要求伺服器未聲明支援的功能。

如果發送了伺服器不了解的功能,伺服器必須診斷並中止。伺服器不得忽略客戶端請求且伺服器已宣告的功能。作為這些規則的結果,伺服器不得宣告其不了解的功能。

atomicreport-statusreport-status-v2delete-refsquietpush-cert 功能會被 receive-pack (推送到伺服器) 程序發送和識別。

ofs-deltaside-band-64k 功能會被 upload-pack 和 receive-pack 協定發送和識別。agentsession-id 功能可以選擇性地在兩種協定中發送。

所有其他功能僅由 upload-pack (從伺服器提取) 程序識別。

multi_ack

multi_ack 功能允許伺服器在找到一個可用作客戶端「想要」和客戶端「擁有」的集合之間的共同基礎的提交時,立即回傳「ACK obj-id continue」。

透過盡早發送此訊息,伺服器可能會阻止客戶端進一步向下追蹤客戶端儲存庫歷史記錄的特定分支。客戶端可能仍然需要追蹤其他分支,並為這些分支發送 have 行,直到伺服器在 DAG 中有完整的橫切面,或者客戶端說「done」。

在沒有 multi_ack 的情況下,客戶端會以 --date-order 發送 have 行,直到伺服器找到共同的基礎。這表示客戶端將會發送伺服器已知為共通的 have 行,因為它們在時間上與伺服器尚未找到共同基礎的其他分支重疊。

例如,假設客戶端擁有的提交是以大寫表示,而伺服器擁有的提交是以小寫表示,如下圖所示:

      +---- u ---------------------- x
     /              +----- y
    /              /
   a -- b -- c -- d -- E -- F
      \
+--- Q -- R -- S

如果客戶端想要 x,y 並從說 have F,S 開始,伺服器不知道 F,S 是什麼。最終,客戶端會說「have d」,伺服器會發送「ACK d continue」,讓客戶端知道停止向下追蹤該行 (因此不要發送 c-b-a),但尚未完成,它需要 x 的基礎。客戶端會繼續執行 S-R-Q,直到到達 a,此時伺服器有清楚的基礎,所有事情都會結束。

如果沒有 multi_ack,客戶端仍然會發送 c-b-a 鏈,並與 S-R-Q 交錯。

multi_ack_detailed

這是 multi_ack 的延伸,允許客戶端更好地理解伺服器的記憶體狀態。請參閱 gitprotocol-pack[5] 的「封包檔案協商」章節以取得更多資訊。

no-done

此功能只能與智慧型 HTTP 協定一起使用。如果同時存在 multi_ack_detailed 和 no-done,則傳送者可以在其第一個「ACK obj-id ready」訊息之後立即發送封包。

在智慧型 HTTP 協定中,如果沒有 no-done,伺服器會話將會結束,且客戶端必須再次傳送「done」才能讓伺服器傳送封包。no-done 移除了最後一輪,因此略微降低了延遲。

thin-pack

thin 封包是指 delta 參考封包中未包含的基本物件 (但接收端已知存在) 的封包。這可以顯著減少網路流量,但它要求接收端知道如何透過將遺失的基礎新增到封包中來「加厚」這些封包。

當 upload-pack 伺服器可以產生和傳送 thin 封包時,它會宣告 thin-pack。當客戶端了解如何「加厚」thin 封包時,它會要求 thin-pack 功能,通知伺服器它可以接收此類封包。如果客戶端無法將 thin 封包轉換為獨立的封包,則不得要求 thin-pack 功能。

另一方面,預設情況下,receive-pack 會被認為能夠處理 thin 封包,但可以透過宣告 no-thin 功能來要求客戶端不要使用該功能。如果伺服器宣告 no-thin 功能,客戶端不得傳送 thin 封包。

此不對稱性的原因有歷史因素。receive-pack 程式是在 thin 封包發明之後才出現的,因此在歷史上,receive-pack 的參考實作始終了解 thin 封包。稍後新增的 no-thin 允許 receive-pack 以向後相容的方式停用該功能。

side-band, side-band-64k

此功能表示伺服器可以傳送,且客戶端可以理解,多工處理進度報告和錯誤資訊與封包檔案本身交錯。

這兩個選項互斥。現代客戶端始終偏好 side-band-64k

任一模式都表示封包檔案資料將會以資料包的形式串流傳輸,每個資料包的大小在 side_band 的情況下最多為 1000 個位元組,或在 side_band_64k 的情況下最多為 65520 個位元組。每個資料包都由一個前導的 4 位元組 pkt-line 長度組成,該長度表示資料包中有多少資料,然後是一個 1 位元組的串流代碼,最後才是實際的資料。

串流代碼可以是下列其中一個:

1 - pack data
2 - progress messages
3 - fatal error message just before stream aborts

「side-band-64k」功能出現的原因是為了讓可以處理更大資料包的新客戶端要求幾乎完全塞滿的資料包,同時保持對舊客戶端的向後相容性。

此外,透過 side-band 及其最多 1000 個位元組的訊息,實際上是 999 個位元組的酬載和 1 個位元組的串流代碼。透過 side-band-64k,情況相同,您最多可以有 65519 個位元組的資料和 1 個位元組的串流代碼。

客戶端必須僅傳送「side-band」和「side-band-64k」其中之一。如果客戶端同時要求兩者,伺服器必須將其診斷為錯誤。

ofs-delta

伺服器可以傳送,且客戶端可以理解,以封包中的位置而非 obj-id 來參考其基礎的 PACKv2。也就是說,它們可以在封包檔案中傳送/讀取 OBJ_OFS_DELTA (也稱為類型 6)。

agent

伺服器可以選擇性地傳送 agent=X 形式的功能,通知客戶端伺服器正在執行版本 X。客戶端可以選擇性地透過回覆 agent=Y 功能來返回其自身的代理程式字串 (但如果伺服器未提及代理程式功能,則不得執行此操作)。XY 字串可能包含任何可列印的 ASCII 字元,但不包括空格 (也就是位元組範圍 32 < x < 127),且通常採用「套件/版本」的形式 (例如,「git/1.8.3.1」)。代理程式字串僅供統計和偵錯用途,不得用於以程式設計方式假設存在或不存在特定功能。

object-format

此功能會將雜湊演算法作為引數,表示伺服器支援給定的雜湊演算法。它可以多次傳送;如果是,則給定的第一個演算法會用於參考宣告。

當客戶端提供時,這表示它打算使用給定的雜湊演算法進行通訊。提供的演算法必須是伺服器支援的演算法。

如果未提供此功能,則假設唯一支援的演算法是 SHA-1。

symref

此參數化的功能用於通知接收者哪個符號參考指向哪個參考;例如,「symref=HEAD:refs/heads/master」告訴接收者 HEAD 指向 master。可以重複使用此功能來表示多個符號參考。

如果 HEAD 符號參考是正在傳送的參考之一,則伺服器應包含此功能。

客戶端可以使用此功能中的參數,在複製儲存庫時選擇正確的初始分支。

shallow

此功能會將「deepen」、「shallow」和「unshallow」命令新增到 fetch-pack/upload-pack 協定,讓客戶端可以要求淺層複製。

deepen-since

此功能為 fetch-pack/upload-pack 協定新增了 "deepen-since" 命令,以便客戶端可以請求以特定時間點而非深度為基準的淺層複製。在內部,這等同於在伺服器端執行 "rev-list --max-age=<timestamp>"。"deepen-since" 無法與 "deepen" 一起使用。

deepen-not

此功能為 fetch-pack/upload-pack 協定新增了 "deepen-not" 命令,以便客戶端可以請求以特定修訂版本而非深度為基準的淺層複製。在內部,這等同於在伺服器端執行 "rev-list --not <rev>"。"deepen-not" 無法與 "deepen" 一起使用,但可以與 "deepen-since" 一起使用。

deepen-relative

如果客戶端請求此功能,則 "deepen" 命令的語義會變更。"depth" 引數是從目前的淺層邊界開始的深度,而不是從遠端參考的深度。

no-progress

客戶端以 "git clone -q" 或類似方式啟動,不希望使用邊帶 2。基本上,客戶端只是說「我不想在邊帶上接收串流 2,所以不要傳送給我,如果你傳了,我會直接丟棄」。但是,邊帶通道 3 仍然用於錯誤回應。

include-tag

include-tag 功能是關於在傳送物件時,也一併傳送指向這些物件的附註標籤。如果我們將一個物件打包傳送給客戶端,而且有一個標籤物件正好指向該物件,我們也會一併打包該標籤物件。一般來說,這讓客戶端在單一網路連線中擷取分支時,可以取得所有新的附註標籤。

當伺服器宣告此功能時,客戶端可以總是傳送 include-tag,將其硬編碼到請求中。客戶端是否請求 include-tag 的決定,僅與客戶端對標籤資料的需求有關,無論伺服器是否已宣告在 refs/tags/* 命名空間中的物件。

如果標籤的參照物件已打包且客戶端已請求 include-tags,伺服器必須打包這些標籤。

客戶端必須為伺服器忽略 include-tag 且實際上沒有在打包中傳送標籤的情況做好準備。在這種情況下,客戶端應該發出後續的擷取請求,以取得 include-tag 本來會提供給客戶端的標籤。

伺服器如果支援 include-tag,無論是否有可用的標籤,都應該傳送 include-tag。

report-status

receive-pack 程序可以接收 report-status 功能,這會告知它,客戶端想要知道封包檔案上傳和參考更新後發生了什麼事。如果推送的客戶端請求此功能,伺服器在解壓縮和更新參考之後,將會回應封包檔案是否成功解壓縮,以及每個參考是否已成功更新。如果任何一項不成功,它將會傳回錯誤訊息。有關範例訊息,請參閱 gitprotocol-pack[5]

report-status-v2

功能 report-status-v2 擴展了功能 report-status,加入了新的「選項」指示詞,以便支援由 "proc-receive" hook 重寫的參考。"proc-receive" hook 可以處理一個虛擬參考的命令,該命令可能會建立或更新具有不同名稱、新 oid 和舊 oid 的參考。而功能 report-status 無法報告這種情況。詳細資訊請參閱 gitprotocol-pack[5]

delete-refs

如果伺服器傳回 delete-refs 功能,則表示它可以接受零 ID 值作為參考更新的目標值。它不是由客戶端傳回,只是通知客戶端它可以傳送零 ID 值來刪除參考。

quiet

如果 receive-pack 伺服器宣告 quiet 功能,則表示它能夠靜默處理接收到的封包時可能顯示的人工可讀進度輸出。如果本機進度報告也被抑制(例如,透過 push -q,或者如果 stderr 沒有輸出到 tty),send-pack 客戶端應該使用 quiet 功能來抑制伺服器端的進度報告。

atomic

如果伺服器傳送 atomic 功能,則表示它可以接受原子推送。如果推送的客戶端請求此功能,伺服器將在一個原子交易中更新參考。所有參考都會更新,否則都不會更新。

push-options

如果伺服器傳送 push-options 功能,則表示它可以在傳送更新命令後,但在串流傳輸封包檔案之前,接受推送選項。如果推送的客戶端請求此功能,伺服器會將選項傳遞給處理此推送請求的 pre- 和 post- receive hook。

allow-tip-sha1-in-want

如果 upload-pack 伺服器宣告此功能,fetch-pack 可以傳送 "want" 行,其中包含伺服器上存在但未由 upload-pack 宣告的物件名稱。由於歷史原因,此功能的名稱包含 "sha1"。物件名稱始終使用透過 object-format 功能協商的物件格式給定。

allow-reachable-sha1-in-want

如果 upload-pack 伺服器宣告此功能,fetch-pack 可以傳送 "want" 行,其中包含伺服器上存在但未由 upload-pack 宣告的物件名稱。由於歷史原因,此功能的名稱包含 "sha1"。物件名稱始終使用透過 object-format 功能協商的物件格式給定。

push-cert=<nonce>

宣告此功能的 receive-pack 伺服器願意接受簽署的推送憑證,並要求將 <nonce> 包含在推送憑證中。除非 receive-pack 伺服器宣告此功能,否則 send-pack 客戶端不得傳送 push-cert 封包。

filter

如果 upload-pack 伺服器宣告 filter 功能,fetch-pack 可以傳送 "filter" 命令,以請求部分複製或部分擷取,並要求伺服器從封包檔案中省略各種物件。

session-id=<session-id>

伺服器可以宣告一個工作階段 ID,該 ID 可用於在多個請求中識別此程序。客戶端也可以將自己的工作階段 ID 回傳給伺服器。

工作階段 ID 對於給定的程序應該是唯一的。它們必須符合封包行,並且不得包含不可列印或空白字元。目前的實作使用 trace2 工作階段 ID(詳細資訊請參閱 api-trace2),但這可能會變更,且工作階段 ID 的使用者不應依賴此事實。

GIT

git[1] 套件的一部分

scroll-to-top