簡體中文 ▾ 主題 ▾ 最新版本 ▾ gitprotocol-v2 上次更新於 2.49.0

名稱

gitprotocol-v2 - Git 有線協議,版本 2

概要

<over-the-wire-protocol>

描述

本文件提供了 Git 有線協議版本 2 的規範。協議 v2 將透過以下方式改進 v1:

  • 支援單個服務中的多個命令,而非多個服務名稱

  • 透過將功能移至協議的獨立部分,不再隱藏在 NUL 位元組後面並受 pkt-line 大小限制,從而易於擴充套件

  • 分離隱藏在 NUL 位元組後面的其他資訊(例如,代理字串作為功能,並且可以使用 ls-refs 請求符號引用)

  • 除非明確請求,否則將省略引用通告

  • ls-refs 命令可明確請求某些引用

  • 設計時考慮了 http 和無狀態 RPC。透過清晰的重新整理語義,http 遠端助手可以簡單地充當代理

在協議 v2 中,通訊是面向命令的。初次聯絡伺服器時,會通告功能列表。其中一些功能將是客戶端可以請求執行的命令。命令完成後,客戶端可以重用連線並請求執行其他命令。

資料包行分幀

所有通訊都使用資料包行分幀完成,與 v1 中相同。有關更多資訊,請參閱 gitprotocol-pack[5]gitprotocol-common[5]

在協議 v2 中,這些特殊資料包將具有以下語義:

  • 0000 重新整理資料包(flush-pkt)- 指示訊息結束

  • 0001 分隔符資料包(delim-pkt)- 分隔訊息的各個部分

  • 0002 響應結束資料包(response-end-pkt)- 指示無狀態連線的響應結束

初始客戶端請求

通常,客戶端可以透過在使用中的傳輸的相應旁路通道傳送 version=2 來請求使用協議 v2,這不可避免地會設定 GIT_PROTOCOL。更多資訊可在 gitprotocol-pack[5]gitprotocol-http[5] 以及 git.txt 中的 GIT_PROTOCOL 定義中找到。在所有情況下,伺服器的響應都是能力通告。

Git 傳輸

當使用 git:// 傳輸時,您可以透過傳送 "version=2" 作為額外引數來請求使用協議 v2。

003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0

SSH 和檔案傳輸

當使用 ssh:// 或 file:// 傳輸時,必須顯式設定 GIT_PROTOCOL 環境變數以包含 "version=2"。伺服器可能需要配置以允許此環境變數透過。

HTTP 傳輸

當使用 http:// 或 https:// 傳輸時,客戶端會發出 gitprotocol-http[5] 中描述的“智慧”info/refs 請求,並透過在 Git-Protocol 頭中提供 "version=2" 來請求使用 v2。

C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0
C: Git-Protocol: version=2

v2 伺服器將回復:

S: 200 OK
S: <Some headers>
S: ...
S:
S: 000eversion 2\n
S: <capability-advertisement>

隨後的請求將直接傳送到服務 $GIT_URL/git-upload-pack。(這對於 git-receive-pack 同樣適用)。

使用 git-upload-pack[1]--http-backend-info-refs 選項。

伺服器可能需要配置以透過 GIT_PROTOCOL 變數傳遞此頭的內容。請參閱 git-http-backend.txt 中的討論。

能力通告

伺服器根據客戶端的請求,決定使用協議版本 2 進行通訊時,會在其初始響應中傳送一個版本字串,後跟其能力通告。每個能力都是一個鍵,帶有一個可選的值。客戶端必須忽略所有未知鍵。未知值的語義留待每個鍵的定義。某些能力將描述客戶端可以請求執行的命令。

capability-advertisement = protocol-version
      capability-list
      flush-pkt
protocol-version = PKT-LINE("version 2" LF)
capability-list = *capability
capability = PKT-LINE(key[=value] LF)
key = 1*(ALPHA | DIGIT | "-_")
value = 1*(ALPHA | DIGIT | " -_.,?\/{}[]()<>!@#$%^&*+=:;")

命令請求

收到能力通告後,客戶端可以發出請求,選擇所需命令及其特定功能或引數。然後是一個可選部分,客戶端可以在其中提供任何命令特定的引數或查詢。一次只能請求一個命令。

request = empty-request | command-request
empty-request = flush-pkt
command-request = command
    capability-list
    delim-pkt
    command-args
    flush-pkt
command = PKT-LINE("command=" key LF)
command-args = *command-specific-arg
command-specific-args are packet line framed arguments defined by
each individual command.

伺服器隨後將檢查以確保客戶端的請求由有效的命令以及所通告的有效功能組成。如果請求有效,伺服器將執行該命令。伺服器在發出響應之前,必須等到收到客戶端的整個請求。響應的格式由正在執行的命令決定,但在所有情況下,重新整理資料包都表示響應的結束。

當命令完成,且客戶端已從伺服器接收到整個響應後,客戶端可以請求執行另一個命令,也可以終止連線。客戶端可以選擇傳送一個僅包含重新整理資料包的空請求,以指示不再發出任何請求。

能力

能力有兩種不同的型別:普通能力,可用於傳達資訊或改變請求的行為;以及命令,這是客戶端要執行的核心操作(抓取、推送等)。

協議版本 2 預設是無狀態的。這意味著所有命令必須只持續一輪,並且從伺服器端看是無狀態的,除非客戶端請求了一個表明伺服器應維護狀態的能力。客戶端在正確執行的前提下,不得要求伺服器端進行狀態管理。這允許伺服器端進行簡單的輪詢負載均衡,而無需擔心狀態管理。

代理

伺服器可以通告帶有值 X(形式為 agent=X)的 agent 能力,以通知客戶端伺服器正在執行版本 X。客戶端可以選擇透過在其對伺服器的請求中包含帶有值 Y(形式為 agent=Y)的 agent 能力來發送其自己的代理字串(但如果伺服器未通告 agent 能力,則不得這樣做)。XY 字串可以包含除空格以外的任何可列印 ASCII 字元(即,位元組範圍 33 ≤ x ≤ 126),通常採用“包/版本-作業系統”的形式(例如,“git/1.8.3.1-Linux”),其中 os 是作業系統名稱(例如,“Linux”)。XY 可以使用 GIT_USER_AGENT 環境變數配置,並且它具有優先順序。os 是透過 uname(2) 系統呼叫的 sysname 欄位或其等效方法檢索的。代理字串純粹用於統計和除錯目的,不得用於以程式設計方式假定特定功能的存在或缺失。

ls-refs

ls-refs 是 v2 中用於請求引用通告的命令。與當前引用通告不同,ls-refs 接受可用於限制伺服器傳送的引用的引數。

基本命令中不支援的其他功能將以空格分隔的功能列表形式作為命令的值在能力通告中通告:"<命令>=<功能-1> <功能-2>"。

ls-refs 接受以下引數:

   symrefs
In addition to the object pointed by it, show the underlying ref
pointed by it when showing a symbolic ref.
   peel
Show peeled tags.
   ref-prefix <prefix>
When specified, only references having a prefix matching one of
the provided prefixes are displayed. Multiple instances may be
given, in which case references matching any prefix will be
shown. Note that this is purely for optimization; a server MAY
show refs not matching the prefix if it chooses, and clients
should filter the result themselves.

如果通告了 unborn 功能,則可以在客戶端請求中包含以下引數。

   unborn
The server will send information about HEAD even if it is a symref
pointing to an unborn branch in the form "unborn HEAD
symref-target:<target>".

ls-refs 的輸出如下:

output = *ref
  flush-pkt
obj-id-or-unborn = (obj-id | "unborn")
ref = PKT-LINE(obj-id-or-unborn SP refname *(SP ref-attribute) LF)
ref-attribute = (symref | peeled)
symref = "symref-target:" symref-target
peeled = "peeled:" obj-id

fetch

fetch 是 v2 中用於抓取 packfile 的命令。可以將其視為 v1 fetch 的修改版本,其中去除了引用通告(因為 ls-refs 命令承擔了該角色),並調整了訊息格式以消除冗餘並允許輕鬆新增未來的擴充套件。

基本命令中不支援的其他功能將以空格分隔的功能列表形式作為命令的值在能力通告中通告:"<命令>=<功能-1> <功能-2>"。

一個 fetch 請求可以接受以下引數:

   want <oid>
Indicates to the server an object which the client wants to
retrieve.  Wants can be anything and are not limited to
advertised objects.
   have <oid>
Indicates to the server an object which the client has locally.
This allows the server to make a packfile which only contains
the objects that the client needs. Multiple 'have' lines can be
supplied.
   done
Indicates to the server that negotiation should terminate (or
not even begin if performing a clone) and that the server should
use the information supplied in the request to construct the
packfile.
   thin-pack
Request that a thin pack be sent, which is a pack with deltas
which reference base objects not contained within the pack (but
are known to exist at the receiving end). This can reduce the
network traffic significantly, but it requires the receiving end
to know how to "thicken" these packs by adding the missing bases
to the pack.
   no-progress
Request that progress information that would normally be sent on
side-band channel 2, during the packfile transfer, should not be
sent.  However, the side-band channel 3 is still used for error
responses.
   include-tag
Request that annotated tags should be sent if the objects they
point to are being sent.
   ofs-delta
Indicate that the client understands PACKv2 with delta referring
to its base by position in pack rather than by an oid.  That is,
they can read OBJ_OFS_DELTA (aka type 6) in a packfile.

如果通告了 shallow 功能,以下引數可以包含在客戶端請求中,並且可能在伺服器響應中新增 shallow-info 部分,如下所述。

   shallow <oid>
A client must notify the server of all commits for which it only
has shallow copies (meaning that it doesn't have the parents of
a commit) by supplying a 'shallow <oid>' line for each such
object so that the server is aware of the limitations of the
client's history.  This is so that the server is aware that the
client may not have all objects reachable from such commits.
   deepen <depth>
Requests that the fetch/clone should be shallow having a commit
depth of <depth> relative to the remote side.
   deepen-relative
Requests that the semantics of the "deepen" command be changed
to indicate that the depth requested is relative to the client's
current shallow boundary, instead of relative to the requested
commits.
   deepen-since <timestamp>
Requests that the shallow clone/fetch should be cut at a
specific time, instead of depth.  Internally it's equivalent to
doing "git rev-list --max-age=<timestamp>". Cannot be used with
"deepen".
   deepen-not <rev>
Requests that the shallow clone/fetch should be cut at a
specific revision specified by '<rev>', instead of a depth.
Internally it's equivalent of doing "git rev-list --not <rev>".
Cannot be used with "deepen", but can be used with
"deepen-since".

如果通告了 filter 功能,則客戶端請求中可以包含以下引數:

   filter <filter-spec>
Request that various objects from the packfile be omitted
using one of several filtering techniques. These are intended
for use with partial clone and partial fetch operations. See
`rev-list` for possible "filter-spec" values. When communicating
with other processes, senders SHOULD translate scaled integers
(e.g. "1k") into a fully-expanded form (e.g. "1024") to aid
interoperability with older receivers that may not understand
newly-invented scaling suffixes. However, receivers SHOULD
accept the following suffixes: 'k', 'm', and 'g' for 1024,
1048576, and 1073741824, respectively.

如果通告了 ref-in-want 功能,則以下引數可以包含在客戶端請求中,並且可能在伺服器響應中新增 wanted-refs 部分,如下所述。

   want-ref <ref>
Indicates to the server that the client wants to retrieve a
particular ref, where <ref> is the full name of a ref on the
server.  It is a protocol error to send want-ref for the
same ref more than once.

如果通告了 sideband-all 功能,則以下引數可以包含在客戶端請求中:

   sideband-all
Instruct the server to send the whole response multiplexed, not just
the packfile section. All non-flush and non-delim PKT-LINE in the
response (not only in the packfile section) will then start with a byte
indicating its sideband (1, 2, or 3), and the server may send "0005\2"
(a PKT-LINE of sideband 2 with no payload) as a keepalive packet.

如果通告了 packfile-uris 功能,則以下引數可以包含在客戶端請求中,並且可能在伺服器響應中新增 packfile-uris 部分,如下所述。請注意,最多隻能向伺服器傳送一條 packfile-uris 行。

   packfile-uris <comma-separated-list-of-protocols>
Indicates to the server that the client is willing to receive
URIs of any of the given protocols in place of objects in the
sent packfile. Before performing the connectivity check, the
client should download from all given URIs. Currently, the
protocols supported are "http" and "https".

如果通告了 wait-for-done 功能,則客戶端請求中可以包含以下引數。

   wait-for-done
Indicates to the server that it should never send "ready", but
should wait for the client to say "done" before sending the
packfile.

fetch 的響應分為多個部分,由分隔符資料包(0001)分隔,每個部分以其節標題開頭。大多數部分僅在傳送 packfile 時傳送。

output = acknowledgements flush-pkt |
  [acknowledgments delim-pkt] [shallow-info delim-pkt]
  [wanted-refs delim-pkt] [packfile-uris delim-pkt]
  packfile flush-pkt
acknowledgments = PKT-LINE("acknowledgments" LF)
    (nak | *ack)
    (ready)
ready = PKT-LINE("ready" LF)
nak = PKT-LINE("NAK" LF)
ack = PKT-LINE("ACK" SP obj-id LF)
shallow-info = PKT-LINE("shallow-info" LF)
 *PKT-LINE((shallow | unshallow) LF)
shallow = "shallow" SP obj-id
unshallow = "unshallow" SP obj-id
wanted-refs = PKT-LINE("wanted-refs" LF)
*PKT-LINE(wanted-ref LF)
wanted-ref = obj-id SP refname
packfile-uris = PKT-LINE("packfile-uris" LF) *packfile-uri
packfile-uri = PKT-LINE(40*(HEXDIGIT) SP *%x20-ff LF)
packfile = PKT-LINE("packfile" LF)
    *PKT-LINE(%x01-03 *%x00-ff)
   acknowledgments section
* If the client determines that it is finished with negotiations by
  sending a "done" line (thus requiring the server to send a packfile),
  the acknowledgments sections MUST be omitted from the server's
  response.
  • 總是以節標題 "acknowledgments" 開頭。

  • 如果沒有一行傳送的物件 ID 是共同的,伺服器將回復 "NAK"。

  • 伺服器將對所有傳送的共同物件 ID 的 have 行回覆 "ACK obj-id"。

  • 響應不能同時包含 "ACK" 行和 "NAK" 行。

  • 伺服器將回復一行 "ready",表示伺服器已找到可接受的公共基礎,並準備生成和傳送一個 packfile(該 packfile 將在同一響應的 packfile 部分中找到)

  • 如果伺服器找到了合適的切入點並決定傳送“ready”行,則伺服器可以決定(作為最佳化)省略其響應中本應傳送的任何“ACK”行。這是因為伺服器已經確定了它計劃傳送給客戶端的物件,並且不再需要進一步的協商。

       shallow-info section
    * If the client has requested a shallow fetch/clone, a shallow
      client requests a fetch or the server is shallow then the
      server's response may include a shallow-info section.  The
      shallow-info section will be included if (due to one of the
      above conditions) the server needs to inform the client of any
      shallow boundaries or adjustments to the clients already
      existing shallow boundaries.
  • 總是以節標題 "shallow-info" 開頭。

  • 如果請求了正深度,伺服器將計算深度不大於所需深度的提交集合。

  • 伺服器為每個其父級不會在後續的 packfile 中傳送的提交發送一個“shallow obj-id”行。

  • 伺服器為每個客戶端已指示為淺但由於抓取而不再淺的提交(由於其父級已在後續的 packfile 中傳送)傳送一個“unshallow obj-id”行。

  • 伺服器不得傳送任何客戶端未在其請求中指出是淺的“unshallow”行。

       wanted-refs section
    * This section is only included if the client has requested a
      ref using a 'want-ref' line and if a packfile section is also
      included in the response.
  • 總是以節標題 "wanted-refs" 開頭。

  • 伺服器將為每個使用 want-ref 行請求的引用傳送一個引用列表(“<oid> <refname>”)。

  • 伺服器不得傳送任何未使用 want-ref 行請求的引用。

       packfile-uris section
    * This section is only included if the client sent
      'packfile-uris' and the server has at least one such URI to
      send.
  • 總是以節標題 "packfile-uris" 開頭。

  • 對於伺服器傳送的每個 URI,它會發送包內容的雜湊值(由 git index-pack 輸出),後跟 URI。

  • 雜湊值是 40 個十六進位制字元長。當 Git 升級到新的雜湊演算法時,這可能需要更新。(它應該與 index-pack 在“pack\t”或“keep\t”之後輸出的內容匹配。)

       packfile section
    * This section is only included if the client has sent 'want'
      lines in its request and either requested that no more
      negotiation be done by sending 'done' or if the server has
      decided it has found a sufficient cut point to produce a
      packfile.
  • 總是以節標題 "packfile" 開頭。

  • packfile 的傳輸緊隨節標題之後開始。

  • packfile 的資料傳輸總是多路複用的,使用與協議版本 1 中 side-band-64k 能力相同的語義。這意味著在 packfile 資料流期間,每個資料包都由一個前導的 4 位元組 pkt-line 長度(典型的 pkt-line 格式)組成,後跟一個 1 位元組的流程式碼,再後跟實際資料。

     The stream code can be one of:
    1 - pack data
    2 - progress messages
    3 - fatal error message just before stream aborts

server-option

如果已通告,則表示可以在請求中包含任意數量的伺服器特定選項。這透過在請求的能力列表部分中將每個選項作為“server-option=<option>”能力行傳送來完成。

提供的選項不得包含 NUL 或 LF 字元。

object-format

伺服器可以通告帶有值 X(形式為 object-format=X)的 object-format 能力,以通知客戶端伺服器能夠處理使用雜湊演算法 X 的物件。如果未指定,則假定伺服器只處理 SHA-1。如果客戶端想使用除 SHA-1 以外的雜湊演算法,它應該指定其 object-format 字串。

session-id=<session-id>

伺服器可以通告一個會話 ID,該 ID 可用於在多個請求中標識此程序。客戶端也可以將其自己的會話 ID 回傳給伺服器。

會話 ID 對於給定程序應該是唯一的。它們必須適應資料包行,並且不得包含不可列印或空白字元。當前的實現使用 trace2 會話 ID(詳情請參閱 api-trace2),但這可能會改變,會話 ID 的使用者不應依賴此事實。

object-info

object-info 是檢索一個或多個物件資訊的命令。其主要目的是允許客戶端根據這些資訊做出決策,而無需完全抓取物件。目前僅支援物件大小資訊。

一個 object-info 請求接受以下引數:

size
Requests size information to be returned for each listed object id.
oid <oid>
Indicates to the server an object which the client wants to obtain
information for.

object-info 的響應是所請求物件 ID 及其相關請求資訊的列表,每個之間用一個空格分隔。

output = info flush-pkt
info = PKT-LINE(attrs) LF)
	*PKT-LINE(obj-info LF)
attrs = attr | attrs SP attrs
attr = "size"
obj-info = obj-id SP obj-size

bundle-uri

如果通告了 bundle-uri 能力,則伺服器支援“bundle-uri”命令。

該能力目前沒有通告任何值(即不是 "bundle-uri=somevalue"),未來可能會新增一個值以支援命令範圍的擴充套件。客戶端必須忽略任何未知的能力值,並繼續執行其支援的“bundle-uri”對話。

bundle-uri 命令旨在在 fetch 之前發出,以獲取捆綁檔案(參見 git-bundle[1])的 URI,從而“播種”並通知後續的 fetch 命令。

客戶端可以在任何其他有效命令之前或之後發出 bundle-uri。為了對客戶端有用,它預計將在 ls-refs 之後和 fetch 之前發出,但可以在對話中的任何時間發出。

bundle-uri 的討論

此功能的目的是透過將 git-clone[1] 期間抓取非常大的 PACK 的常見情況轉換為較小的增量抓取來最佳化伺服器資源消耗的常見情況。

它還允許伺服器結合 uploadpack.packObjectsHook(參見 git-config[1])實現更好的快取。

透過讓新的克隆或抓取成為對最新生成的 *.bundle 檔案(或檔案)的更可預測和常見的協商。伺服器甚至可以在新的推送進來時預先生成此類協商的結果,以供 uploadpack.packObjectsHook 使用。

伺服器可以利用這些捆綁包的一種方式是,伺服器會預料到新的克隆將下載一個已知捆綁包,然後使用該捆綁包(或捆綁包)中找到的引用提示來追趕儲存庫的當前狀態。

bundle-uri 協議

一個 bundle-uri 請求不帶任何引數,如上所述,目前不通告能力值。兩者都可能在未來新增。

當客戶端發出 command=bundle-uri 請求時,響應是一個鍵值對列表,以資料包行形式提供,值為 <key>=<value>。每個 <key> 都應解釋為 bundle.* 名稱空間中的配置鍵,以構建一個捆綁包列表。這些鍵按 bundle.<id>. 小節分組,其中每個與給定 <id> 對應的鍵都為該 <id> 定義的捆綁包貢獻屬性。有關這些鍵的具體細節以及 Git 客戶端如何解釋其值,請參閱 git-config[1]

客戶端必須按照上述格式解析行,不符合格式的行應該被丟棄。在這種情況下,可以警告使用者。

bundle-uri 客戶端和伺服器期望

URI 內容

通告的 URI 內容必須是以下兩種型別之一。

通告的 URI 可能包含一個 git bundle verify 會接受的 bundle 檔案。即,它們必須包含一個或多個供客戶端使用的引用提示,必須使用標準“-”字首指示先決條件(如果有),並且必須指示其“object-format”(如果適用)。

通告的 URI 也可以包含一個 git config --list 會接受的純文字檔案(帶 --file 選項)。此列表中的鍵值對位於 bundle.* 名稱空間中(參見 git-config[1])。

bundle-uri 客戶端錯誤恢復

客戶端必須最重要的是優雅地處理錯誤,無論該錯誤是由於捆綁 URI 中缺少/資料錯誤,還是因為客戶端太笨而無法理解並完全解析捆綁標頭及其先決條件關係,或其他原因。

伺服器運營商應該放心地開啟“bundle-uri”,並且不必擔心,例如,如果其 CDN 出現故障,克隆或抓取會遇到硬性故障。即使伺服器捆綁包不完整或存在某種問題,客戶端仍應以正常執行的儲存庫結束,就像它選擇不使用此協議擴充套件一樣。

所有後續關於客戶端和伺服器互動的討論都必須牢記這一點。

bundle-uri 伺服器到客戶端

返回的捆綁 URI 的順序不重要。客戶端必須解析其頭部以發現其中包含的 OID 和先決條件。客戶端必須將捆綁包本身及其頭部的內容視為最終的真相來源。

伺服器甚至可以返回與正在克隆的儲存庫沒有任何直接關係的捆綁包(無論是偶然還是故意“巧妙”配置),並期望客戶端整理出他們希望從捆綁包中獲取哪些資料(如果有)。

bundle-uri 客戶端到伺服器

客戶端應在隨後的 fetch 請求中提供捆綁標頭中找到的引用提示作為 have 行。客戶端也可以完全忽略捆綁包,如果認為這樣做出於某種原因更糟糕,例如如果捆綁包無法下載,它不喜歡它找到的提示等。

當通告的捆綁包不需要進一步協商時

如果在發出 bundle-urils-refs 後,並獲取捆綁包的頭部資訊,客戶端發現其想要的引用提示可以完全從通告的捆綁包中檢索,則客戶端可以斷開與 Git 伺服器的連線。這樣一次 clonefetch 的結果應與不使用 bundle-uri 獲得的狀態沒有區別。

早期客戶端斷開連線和錯誤恢復

客戶端在仍在下載捆綁包時(已流式傳輸並解析其標頭)可以執行早期斷開連線。在這種情況下,客戶端必須優雅地從與完成捆綁包下載和驗證相關的任何錯誤中恢復。

即,客戶端可能需要重新連線併發出 fetch 命令,並可能完全回退到不使用 bundle-uri

這種“可以”行為被如此指定(而不是“應該”),是基於以下假設:通告捆綁 URI 的伺服器更有可能提供一個相對較大的儲存庫,並且指向有良好機會正常工作的 URI。客戶端可以,例如,將捆綁包的有效載荷大小作為啟發式方法,以檢視是否值得提前斷開連線,如果需要回退到完整的“fetch”對話方塊的話。

當通告的捆綁包需要進一步協商時

客戶端應透過“fetch”命令,使用通告捆綁包中找到的 OID 提示,開始與伺服器協商 PACK,即使它仍在下載這些捆綁包。

這允許從任何互動式伺服器對話中積極地早期斷開連線。客戶端盲目地相信通告的 OID 提示是相關的,並將其作為 have 行發出,然後它透過 want 行請求任何它想要的提示(通常來自“ls-refs”通告)。伺服器將計算一個(希望很小)的 PACK,其中包含捆綁包中的提示與所請求資料之間的預期差異。

客戶端隨後需要保持活躍的唯一連線是到併發下載的靜態捆綁包,當這些捆綁包和增量 PACK 被檢索後,應進行解壓和驗證。此時發生的任何錯誤都應得到優雅恢復,請參見上文。

bundle-uri 協議功能

客戶端根據伺服器提供的 <key>=<value> 對構建捆綁包列表。這些對屬於 git-config[1] 中記錄的 bundle.* 名稱空間。在本節中,我們將討論其中一些鍵,並描述客戶端將根據這些資訊執行的操作。

特別是,bundle.version 鍵指定一個整數值。目前唯一接受的值是 1,但如果客戶端在此處看到意外值,則客戶端必須忽略捆綁包列表。

只要 bundle.version 被理解,所有其他未知鍵都可以被客戶端忽略。伺服器將保證與舊客戶端的相容性,儘管新客戶端可能能夠更好地使用額外的鍵來最小化下載。

任何向後不相容的預 URI 鍵值新增都將透過新的 bundle.version 值或 bundle-uri 能力通告本身中的值,和/或透過新的未來 bundle-uri 請求引數進行保護。

一些目前未實現但將來可能實現的示例鍵值對包括:

  • 新增 "hash=<val>" 或 "size=<bytes>" 以通告捆綁檔案的預期雜湊或大小。

  • 通告一個或多個捆綁檔案是相同的(例如,讓客戶端輪詢或以其他方式選擇 N 個可能檔案中的一個)。

  • “oid=<OID>”快捷方式和“prerequisite=<OID>”快捷方式。用於表達具有一個提示且沒有先決條件,或一個提示和一個先決條件的常見捆綁包情況。

    這將允許最佳化伺服器的常見情況,即提供一個只包含其“主”分支的“大捆綁包”,和/或其增量更新。

    收到此類響應的客戶端可以假定它們可以跳過從指定 URI 的捆綁包中檢索頭部,從而節省自身和伺服器檢查該捆綁包或捆綁包頭部所需的請求。

promisor-remote=<pr-infos>

伺服器可以向客戶端通告它正在使用或知道的一些承諾者遠端倉庫,客戶端可能希望將它們用作其承諾者遠端倉庫,而不是此儲存庫。在這種情況下,<pr-infos> 應採用以下形式:

pr-infos = pr-info | pr-infos ";" pr-info
pr-info = "name=" pr-name | "name=" pr-name "," "url=" pr-url

其中 pr-name 是一個承諾者遠端倉庫的 URL 編碼名稱,pr-url 是該承諾者遠端倉庫的 URL 編碼 URL。

在這種情況下,如果客戶端決定使用伺服器通告的一個或多個承諾者遠端倉庫,它可以回覆 "promisor-remote=<pr-names>",其中 <pr-names> 應採用以下形式:

pr-names = pr-name | pr-names ";" pr-name

其中 pr-name 是伺服器通告且客戶端接受的承諾者遠端的 URL 編碼名稱。

請注意,本文件中所有地方,pr-name 必須是有效的遠端名稱,並且如果字元 ;, 出現在 pr-namepr-url 中,則必須進行編碼。

如果伺服器不知道任何可能對客戶端有用的承諾者遠端倉庫,或者更希望客戶端不使用它正在使用或知道的任何承諾者遠端倉庫,則它根本不應該通告“promisor-remote”能力。

在這種情況下,或者如果客戶端不希望使用伺服器通告的任何承諾者遠端倉庫,客戶端不應該在其回覆中通告“promisor-remote”能力。

“promisor.advertise”和“promisor.acceptFromServer”配置選項可用於伺服器和客戶端,分別控制它們通告或接受的內容。有關這些配置選項的更多資訊,請參閱其文件。

請注意,未來如果伺服器在響應 git fetchgit clone 時,能夠使用“promisor-remote”協議功能來通告與客戶端連線更佳的遠端倉庫作為承諾者遠端倉庫,而不是當前的儲存庫,那將是很好的。這樣客戶端就可以從這些連線更佳的遠端倉庫延遲抓取物件。這將要求伺服器在其響應中省略在客戶端已接受的連線更佳的遠端倉庫上可用的物件。然而,這尚未實現。因此,目前“promisor-remote”功能僅在伺服器通告其已用於借用物件的一些承諾者遠端倉庫時才有用。

GIT

Git[1] 套件的一部分

scroll-to-top