Git
英語 ▾ トピック ▾ 最新版 ▾ gitprotocol-v2 最終更新日: 2.45.0

名称

gitprotocol-v2 - Git ワイヤプロトコル バージョン 2

概要

<over-the-wire-protocol>

説明

このドキュメントは、Git のワイヤプロトコルのバージョン 2 の仕様を示しています。プロトコル v2 は、v1 に対して以下の点を改善します。

  • 複数のサービス名ではなく、単一のサービスで複数のコマンドがサポートされます。

  • 機能がプロトコルの独自のセクションに移動されるため、NUL バイトの背後に隠されることなく、pkt-line のサイズによって制限されることもなく、簡単に拡張できます。

  • NUL バイトの背後に隠されているその他の情報(例:エージェント文字列を機能として、symrefs は *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.txtGIT_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.

サーバーは、クライアントのリクエストが有効なコマンドと、アドバタイズされた有効な機能で構成されていることを確認します。リクエストが有効な場合、サーバーはコマンドを実行します。サーバーは、レスポンスを発行する前に、クライアントの entire リクエストの受信を待機する必要があります。レスポンスの形式は実行されるコマンドによって決まりますが、いずれの場合も、flush-pkt はレスポンスの終わりを示します。

コマンドが終了し、クライアントがサーバーからの entire レスポンスを受信したら、クライアントは別のコマンドの実行を要求するか、接続を終了できます。クライアントは、それ以上リクエストが行われないことを示すために、flush-pkt のみで構成される空のリクエストを送信することもできます。

機能

機能には、情報の伝達やリクエストの動作の変更に使用できる通常の機能と、クライアントが実行したいコアアクション(フェッチ、プッシュなど)であるコマンドの 2 つのタイプがあります。

プロトコルバージョン 2 はデフォルトでステートレスです。これは、クライアントがサーバーによって状態を維持する必要があることを示す機能を要求していない限り、すべてのコマンドは単一ラウンドのみ持続し、サーバー側の観点からステートレスでなければならないことを意味します。クライアントは、正しく機能するために、サーバー側での状態管理を要求してはなりません。これにより、状態管理を心配する必要なく、サーバー側で単純なラウンドロビンロードバランシングが可能になります。

agent

サーバーは、agent=X の形式で値 X を使用して agent 機能をアドバタイズして、サーバーがバージョン X を実行していることをクライアントに通知できます。クライアントは、サーバーが agent 機能をアドバタイズしていない場合はそうしてはなりませんが、サーバーへのリクエストに agent=Y の形式で値 Y を持つ agent 機能を含めることで、独自の agent 文字列を送信することもできます。XY の文字列には、スペース以外の印刷可能な ASCII 文字(つまり、バイト範囲 32 < x < 127)を含めることができ、通常は "package/version"(例: "git/1.8.3.1")の形式です。agent 文字列は、統計とデバッグの目的のためだけの情報であり、特定の機能の存在または非存在をプログラム的に想定するために使用してはなりません。

ls-refs

ls-refs は、v2 で参照アドバタイズメントを要求するために使用されるコマンドです。現在の参照アドバタイズメントとは異なり、ls-refs は、サーバーから送信される参照を制限するために使用できる引数を受け入れます。

基本コマンドでサポートされていない追加機能は、機能のアドバタイズメントのコマンドの値として、スペースで区切られた機能のリストの形式でアドバタイズされます。「<command>=<feature-1> <feature-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 でパックファイルをフェッチするために使用されるコマンドです。これは、参照アドバタイズメントが削除され(ls-refs コマンドがその役割を果たしているため)、メッセージ形式が調整されて冗長性が排除され、将来の拡張機能を簡単に追加できるようになった、v1 フェッチの修正版と見なすことができます。

基本コマンドでサポートされていない追加機能は、機能のアドバタイズメントのコマンドの値として、スペースで区切られた機能のリストの形式でアドバタイズされます。「<command>=<feature-1> <feature-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 行は、最大 1 つです。

   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」から始まります。

  • 送信されたhave行に共通するオブジェクトIDがない場合、サーバーは「NAK」を返します。

  • 送信されたhave行に共通するオブジェクトIDすべてについて、サーバーは「ACK obj-id」を返します。

  • レスポンスには、「ACK」行と「NAK」行の両方が含まれることはできません。

  • サーバーは、許容できる共通のベースを見つけ、packfileの作成と送信の準備ができたことを示す「ready」行を返します(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」から始まります。

  • 正のdepthが要求された場合、サーバーは目的のdepthよりも深いコミットの集合を計算します。

  • サーバーは、その親が後続のpackfileで送信されないコミットごとに「shallow obj-id」行を送信します。

  • サーバーは、クライアントがshallowであると示したコミットで、fetchの結果(その親が後続のpackfileで送信されるため)shallowではなくなったコミットごとに「unshallow obj-id」行を送信します。

  • サーバーは、クライアントが要求の一部としてshallowであると示していないものに対して「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に対して、packの内容のハッシュ(git index-packの出力)とURIを送信します。

  • ハッシュは40文字の16進数です。Gitが新しいハッシュアルゴリズムにアップグレードされた場合、これを更新する必要があるかもしれません。(「pack\t」または「keep\t」の後にindex-packが出力する内容と一致する必要があります)。

       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

アドバタイズされている場合、任意の数のサーバー固有のオプションをリクエストに含めることができることを示します。これは、リクエストのcapability-listセクションで各オプションを「server-option=<option>」capability行として送信することで行われます。

提供されたオプションには、NUL文字またはLF文字を含めることはできません。

object-format

サーバーは、object-format=X の形式で値Xを使用してobject-format capabilityをアドバタイズして、サーバーがハッシュアルゴリズムXを使用してオブジェクトを処理できることをクライアントに通知できます。指定されていない場合、サーバーはSHA-1のみを処理するとみなされます。クライアントがSHA-1以外のハッシュアルゴリズムを使用したい場合は、そのobject-format文字列を指定する必要があります。

session-id=<session-id>

サーバーは、複数のリクエスト間でこのプロセスを識別するために使用できるセッションIDをアドバタイズする場合があります。クライアントも独自のセッションIDをサーバーにアドバタイズできます。

セッションIDは、特定のプロセスに対して一意である必要があります。パケットライン内に収まる必要があり、印刷できない文字や空白文字を含めることはできません。現在の実装ではtrace2セッションIDを使用していますが(詳細はapi-trace2を参照)、これは変更される可能性があり、セッションIDのユーザーはこの事実を当てにしてはなりません。

object-info

object-infoは、1つ以上のオブジェクトに関する情報を取得するためのコマンドです。その主な目的は、クライアントがオブジェクトを完全にフェッチしなくても、この情報に基づいて決定できるようにすることです。現在サポートされている情報はオブジェクトサイズのみです。

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と関連する要求された情報のリストであり、それぞれが1つのスペースで区切られています。

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 capabilityがアドバタイズされている場合、サーバーは「bundle-uri」コマンドをサポートします。

現在、このcapabilityは値なしでアドバタイズされています(つまり、「bundle-uri=somevalue」ではありません)。将来、コマンド全体の拡張をサポートするために値が追加される可能性があります。クライアントは、不明なcapability値を無視し、サポートする「bundle-uri」ダイアログを続行する必要があります。

bundle-uriコマンドは、後続のfetchコマンドを「シード」して情報を提供するために、バンドルファイル(git-bundle[1]を参照)へのURIを取得するために、fetchの前に発行することを目的としています。

クライアントは、他の有効なコマンドの前後いずれかでbundle-uriを発行できます。クライアントにとって有用にするためには、ls-refsの後、fetchの前に発行することが期待されますが、ダイアログのいつでも発行できます。

bundle-uriに関する議論

この機能の目的は、git-clone[1]中の非常に大きなPACKのフェッチという一般的なケースを、より小さい増分フェッチに変更することで、サーバーのリソース消費を最適化することです。

また、uploadpack.packObjectsHookgit-config[1]を参照)と組み合わせて、サーバーでより良いキャッシングを実現できます。

新しいクローンまたはフェッチが、最近生成された*.bundleファイルの先端に対してより予測可能で共通のネゴシエーションになるようにすることで、サーバーは新しいプッシュが入ってきたときに、そのようなネゴシエーションの結果をuploadpack.packObjectsHookに対して事前に生成することさえできます。

サーバーがこれらのバンドルを利用できる方法の1つは、サーバーが新しいクローンが既知のバンドルをダウンロードし、そのバンドル(またはバンドル)にある参照の先端を使用してリポジトリの現在の状態に追いつくことを予測することです。

bundle-uriのプロトコル

bundle-uriリクエストは引数を必要とせず、前述のように現在capability値をアドバタイズしません。どちらも将来追加される可能性があります。

クライアントがcommand=bundle-uriリクエストを発行すると、レスポンスは、値<key>=<value>を持つパケットラインとして提供されるキーバリューペアのリストになります。各<key>は、バンドルのリストを作成するためのbundle.*名前空間からの設定キーとして解釈する必要があります。これらのキーはbundle.<id>.サブセクションでグループ化され、特定の<id>に対応する各キーはその<id>で定義されたバンドルの属性に寄与します。git-config[1]で、これらのキーの具体的な詳細とGitクライアントがそれらの値をどのように解釈するかを参照してください。

クライアントは上記の形式に従って行を解析する必要があります。形式に準拠しない行は破棄する必要があります。そのような場合、ユーザーに警告することがあります。

bundle-uri クライアントとサーバーの期待

URIの内容

アドバタイズされたURIの内容は、2種類のいずれかである必要があります。

アドバタイズされたURIには、git bundle verifyが受け入れるバンドルファイルが含まれている場合があります。つまり、クライアントが使用する1つ以上の参照先端を含んでいなければならず、標準の「-」プレフィックスで前提条件(存在する場合)を示し、必要に応じて「object-format」を示す必要があります。

アドバタイズされたURIには、git config --listが受け入れるプレーンテキストファイル(--fileオプション付き)が含まれている場合もあります。このリストのキーバリューペアはbundle.*名前空間です(git-config[1]を参照)。

bundle-uri クライアントのエラー回復

クライアントは、bundle URIの欠落/データの欠陥、クライアントがバンドルヘッダーとその前提条件の関係を理解して完全に解析できないなど、エラーが発生した場合、何よりも優雅に機能を低下させる必要があります。

サーバーオペレーターは、「bundle-uri」を有効にしても、たとえばCDNがダウンした場合にクローンまたはフェッチが重大なエラーに遭遇する心配をする必要はありません。サーバーバンドルが不完全であるか、何らかの方法で不正であっても、このプロトコル拡張を使用しない場合と同じように、クライアントは依然として機能するリポジトリを取得する必要があります。

クライアントとサーバーの相互作用に関する以降のすべての議論では、この点を考慮する必要があります。

bundle-uri サーバーからクライアントへ

返されるbundle uriの順序は重要ではありません。クライアントは、ヘッダーを解析して、含まれるOIDと前提条件を検出する必要があります。クライアントは、バンドル自体とそのヘッダーの内容を最終的な真実の情報源と見なす必要があります。

サーバーは、(偶発的または意図的な「巧妙な」構成によって)クローンされているリポジトリと直接関係のないバンドルを返すことさえでき、クライアントは、必要に応じて、バンドルから取得したいデータを選別することを期待します。

bundle-uri クライアントからサーバーへ

クライアントは、後続のfetchリクエストで、バンドルヘッダーにある参照先端をhave行として提供する必要があります。クライアントは、バンドルを完全に無視することもできます(たとえば、バンドルをダウンロードできない場合、見つかった先端が気に入らない場合など)。

アドバタイズされたバンドルがそれ以上のネゴシエーションを必要としない場合

bundle-urils-refsを実行し、バンドルのヘッダーを取得した後、クライアントが、必要なref tipを広告されたバンドルから完全に取得できることを確認した場合、クライアントはGitサーバーとの接続を切断しても構いません。このようなcloneまたはfetchの結果は、bundle-uriを使用せずに到達した状態と区別できません。

早期クライアント切断とエラー回復

クライアントは、バンドルのダウンロード中(ヘッダーのストリーミングと解析が完了した後)に早期切断を実行しても構いません。そのような場合、クライアントは、バンドルのダウンロードと検証の完了に関連するエラーから正常に回復しなければなりません。

つまり、クライアントは再接続してfetchコマンドを実行する必要があり、bundle-uriを使用しないようにフォールバックする必要がある可能性があります。

この「MAY」動作は、バンドルURIを広告するサーバーは、比較的大きなリポジトリを提供し、動作状態にある可能性が高いURIを指している可能性が高いという仮定に基づいて、このように指定されています(「SHOULD」ではありません)。クライアントは、たとえば、バンドルのペイロードサイズをヒューリスティックとして使用して、早期切断が価値があるかどうかを確認し、完全な「fetch」ダイアログへのフォールバックが必要かどうかを確認できます。

広告されたバンドルがさらなるネゴシエーションを必要とする場合

クライアントは、バンドルのダウンロード中であっても、広告されたバンドルで見つかったOID tipを使用して、「fetch」コマンドでサーバーからPACKのネゴシエーションを開始する必要があります。

これにより、インタラクティブなサーバーダイアログからの積極的な早期切断が可能になります。クライアントは、広告されたOID tipが関連していることを盲目的に信頼し、それらをhave行として発行し、次に(通常は「ls-refs」広告から)必要なtipをwant行を介して要求します。次に、サーバーは、バンドルのtipと要求されたデータ間の差分(小さいことが望ましい)を含むPACKを計算します。

クライアントがアクティブに維持する必要がある接続は、同時にダウンロードしている静的バンドルへの接続だけです。それらと増分PACKが取得されたら、インフレートして検証する必要があります。この時点でのエラーは、上記のように正常に回復する必要があります。

bundle-uriプロトコル機能

クライアントは、サーバーによって提供された<key>=<value>ペアからバンドルリストを作成します。これらのペアは、git-config[1]で文書化されているbundle.*名前空間の一部です。このセクションでは、これらのキーの一部について説明し、クライアントがこの情報に応答して実行するアクションについて説明します。

特に、bundle.versionキーは整数値を指定します。現時点では、唯一受け入れられる値は1ですが、クライアントがここで予期しない値を検出した場合、クライアントはバンドルリストを無視しなければなりません。

bundle.versionが理解されている限り、他の不明なキーはクライアントによって無視されても構いません。サーバーは古いクライアントとの互換性を保証しますが、新しいクライアントは、追加のキーを使用してダウンロードを最小限に抑えることができる場合があります。

URI前のキーバリューの非後方互換性の追加は、bundle-uri機能のアドバタイズメント自体における新しいbundle.version値または値、および/または新しい将来のbundle-uri要求引数によって保護されます。

現在実装されていないが、将来実装できる可能性のあるキーバリューペアの例を次に示します。

  • バンドルファイルの予想されるハッシュまたはサイズを広告する「hash=<val>」または「size=<bytes>」を追加します。

  • 1つ以上のバンドルファイルが同じであることを広告します(クライアントがラウンドロビンを実行したり、N個の可能なファイルのいずれかを選択したりできるようにするため)。

  • 「oid=<OID>」ショートカットと「prerequisite=<OID>」ショートカット。1つのtipと前提条件がない場合、または1つのtipと1つの前提条件がある場合の一般的なケースを表すため。

    これにより、「メイン」ブランチのみ、またはその増分更新を含む1つの「大きなバンドル」を提供したいサーバーの一般的なケースを最適化できます。

    このような応答を受信したクライアントは、指定されたURIにあるバンドルからヘッダーの取得をスキップできると想定し、それによって、そのバンドルのヘッダーを検査するために必要なリクエストを自分自身とサーバーに節約できます。

Git

git[1]スイートの一部

scroll-to-top