SYNOPSIS
<over-the-wire-protocol>
DESCRIPTION
このドキュメントは、Gitの通信(wire)プロトコルのバージョン2の仕様を示しています。プロトコルv2は、以下の方法でv1を改善します:
-
複数のサービス名の代わりに、単一のサービスで複数のコマンドがサポートされます
-
機能(capability)がプロトコルの独自のセクションに移動され、NULバイトの後ろに隠されたり、pkt行のサイズによって制限されたりすることがないため、簡単に拡張できます。
-
NULバイトの後ろに隠されている他の情報を分離します(たとえば、機能(capability)としてのエージェント文字列とsymrefsは
ls-refs
を使用して要求できます) -
明示的に要求されない限り、 reference advertisement は省略されます
-
一部のrefを明示的に要求する ls-refs コマンド
-
http と stateless-rpc を念頭に置いて設計されています。明確なフラッシュセマンティクス(flush semantics)を使用すると、httpリモートヘルパーは単にプロキシとして機能できます
プロトコルv2では、通信はコマンド指向です。サーバーに最初に接続するときに、機能のリストが広告されます。これらの機能の一部は、クライアントが実行を要求できるコマンドになります。コマンドが完了すると、クライアントは接続を再利用して、他のコマンドの実行を要求できます。
Packet-Line Framing
すべての通信は、v1と同様に、パケットラインフレーミングを使用して行われます。 詳細については、 gitprotocol-pack(5) と gitprotocol-common(5) を参照してください。
プロトコルv2では、これらの特別なパケットの意味は以下のとおりです:
-
0000
フラッシュパケット (flush-pkt) - メッセージの終わりを示します -
0001
区切りパケット (delim-pkt) - メッセージのセクションを区切ります -
0002
応答終了パケット (response-end-pkt) - ステートレス接続の応答の終了を示します
Initial Client Request
一般に、クライアントは、使用されているトランスポートのそれぞれのサイドチャネルを介して version=2
を送信することにより、プロトコルv2を話すように要求できます。これにより、必然的に GIT_PROTOCOL
が定されます。詳細については gitprotocol-pack(5) や gitprotocol-http(5) と、 git.txt
の GIT_PROTOCOL
定義を参照してください。すべての場合において、サーバーからの応答は機能広告(capability advertisement)です。
Git Transport
git:// 輸送を使用する場合、追加のパラメーターとして "version=2" を送信することにより、プロトコルv2の使用を要求できます:
003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0
SSH and File Transport
ssh:// 輸送 または file:// 輸送 のどちらかを使用する場合、GIT_PROTOCOL環境変数を明示的に設定して「version=2」を含める必要があります。この環境変数が渡されるようにサーバーを構成する必要がある場合があります。
HTTP Transport
http:// 輸送または https:// 輸送を使用する場合、 クライアントは gitprotocol-http(5) で説明されているように「smart」な 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でも同じように機能します)。
--http-backend-info-refs
オプションを使用して git-upload-pack(1) を実行します。
サーバーは、 GIT_PROTOCOL
変数を介してこのヘッダーの内容を渡すように構成する必要がある場合があります。 git-http-backend.txt
の説明を参照してください。
Capability Advertisement(機能の広告)
(クライアントからの要求に基づいて)プロトコルバージョン2を使用して通信することを決定したサーバーは、初期応答でバージョン文字列を送信し、続いてその機能(capabilities)を広告(advertisement)することによってクライアントに通知します。各機能は、オプションの値を持つキーです。クライアントは、不明なキーをすべて無視する必要があります。未知の値の意味は、各キーの定義に任されています。一部の機能では、クライアントによる実行を要求できるコマンドについて説明します。
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 | " -_.,?\/{}[]()<>!@#$%^&*+=:;")
Command Request
機能広告を受信した後、クライアントは、特定の機能または引数を使用して、必要なコマンドを選択する要求を発行できます。その次に、クライアントがコマンド固有のパラメータまたはクエリを提供できるオプションのセクションがあります。 一度に要求できるコマンドは1つだけです。
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は、個々のコマンドによって定義される
パケットラインフレームの引数です。
次に、サーバーは、クライアントの要求が、広告された有効な機能だけでなく、有効なコマンドで構成されていることを確認します。リクエストが有効な場合、サーバーはコマンドを実行します。 サーバーは、応答を発行する前に、クライアントの要求全体を受信するまで待機する必要があります。応答の形式は実行中のコマンドによって決まりますが、すべての場合で、flush-pktは応答の終了を示します。
コマンドが終了し、クライアントがサーバーからの応答全体を受信すると、クライアントは別のコマンドの実行を要求するか、接続を終了することができます。 クライアントは、オプションで、flush-pktのみで構成される空の要求を送信して、これ以上要求が行われないことを示すことができます。
Capabilities(機能)
機能には異なる2つのタイプがあります。情報を伝達したり要求の動作を変更したりするために使用できる通常の機能と、クライアントが実行したいコアアクション(フェッチ、プッシュなど)であるコマンドです。
プロトコルバージョン2は、デフォルトではステートレスです。 つまり、クライアントがサーバーで状態を維持する必要があることを指示する機能を要求しない限り、すべてのコマンドは1ラウンドだけ持続し、サーバー側の観点からステートレスである必要があります。クライアントは、正しく機能するためにサーバー側に状態管理を要求してはいけません(MUST NOT)。これにより、サーバー側では状態管理について心配することなく、単純なラウンドロビン負荷分散が可能になります。
agent
サーバーは、値 X
(agent=X
形式)を使用して agent
機能を広告ズし、サーバーがバージョン X
を実行していることをクライアントに通知できます。クライアントは、サーバーへの要求に値 Y
(agent=Y
形式)を持つ agent
機能を含めることにより、オプションで独自のエージェント文字列を送信できます(ただし、サーバーがagent機能を広告しなかった場合は、クライアントから送信してはいけません(MUST NOT))。X
および Y
文字列には、スペースを除く任意の印刷可能なASCII文字(つまり、バイト範囲32 < x <127)を含めることができ、通常は「パッケージ/バージョン」(例: 「git/1.8.3.1」形式です)。エージェント文字列は、統計およびデバッグの目的で純粋に情報を提供するものであり、特定の機能の有無をプログラムで想定するために使用してはいけません(MUST NOT)。
ls-refs
ls-refs
は、v2で参照広告を要求するために使用されるコマンドです。現在の参照広告とは異なり、ls-refsは、サーバーから送信される参照を制限するために使用できる引数を取ります。
基本コマンドでサポートされていない追加の機能は、機能広告のコマンドの値として、スペースで区切られた機能のリストの形式で広告されます: "<command>=<feature 1> <feature 2>"
ls-refsは以下の引数を取ります:
- symrefs
-
それが指すオブジェクトに加えて、シンボリックrefを表示するときに、それが指す基になるrefを表示します。
- peel
-
剥いたタグ(peeled tags)を表示します。
- ref-prefix <prefix>
-
指定すると、 指定された接頭辞のいずれかに一致する接頭辞を持つ参照のみが表示されます。 複数のインスタンスを指定できます。 その場合、プレフィックスに一致する参照が表示されます。 注意: これは純粋に最適化のためであることに注意してください。 サーバーは、 選択した場合、 プレフィックスに一致しない参照を表示する場合があり、 クライアントは結果を自分でフィルターする必要があります。
「unborn」機能が広告される場合、以下の引数をクライアントの要求に含めることができます。
- unborn
-
サーバーは、
unborn HEAD symref-target:<target>
の形式で、unbornブランチを指すsymrefであっても、HEADに関する情報を送信します。
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でパックファイルをフェッチするために使用されるコマンドです。 これは、v1 fetch の修正バージョンと見なすことができ、(ls-refs
コマンドがその役割を果たしているため、)ref-advertisementが削除され、メッセージ形式が調整されて冗長性が排除され、将来の拡張機能を簡単に追加できるようになっています。
基本コマンドでサポートされていない追加の機能は、機能広告のコマンドの値として、スペースで区切られた機能のリストの形式で広告されます: "<command>=<feature 1> <feature 2>"
fetch
リクエストは、以下の引数を取ることができます:
- want <oid>
-
クライアントが取得したいオブジェクトをサーバーに提示します。欲しいものは何でもかまいません。広告されているオブジェクトに限定されません。
- have <oid>
-
クライアントがローカルに持っているオブジェクトをサーバーに提示します。 これにより、サーバーは、クライアントが必要とするオブジェクトのみを含むパックファイルを作成できます。 複数の「have」行を指定できます。
- done
-
ネゴシエーションを終了する必要があること(またはクローンを実行する場合は開始しないこと)、およびサーバーが要求で提供された情報を使用してパックファイルを作成する必要があることをサーバーに提示します。
- thin-pack
-
シンパック(thin pack)の送信を要求します。これは、パック内に含まれていない(ただし、受信側に存在することがわかっている)ベースオブジェクトを参照するデルタを含むパックです。これにより、ネットワークトラフィックを大幅に削減できますが、受信側は、シンパックに不足しているベースを追加して、これらのパックを「厚く」(thicken)する方法を知っている必要があります。
- no-progress
-
パックファイル転送中にサイドバンドチャネル2で通常送信される進行状況情報を送信しないように要求します。 ただし、サイドバンドチャネル3は引き続きエラー応答に使用されます。
- include-tag
-
注釈付きタグ(annotated tags)が指すオブジェクトが送信されている場合は、注釈付きタグ(annotated tags)を送信するように要求します。
- ofs-delta
-
クライアントが PACKv2を理解していることを提示します。デルタは、OIDではなくパック内の位置によってベースを参照しています。 つまり、パックファイル内の OBJ_OFS_DELTA (別名タイプ 6)を読み取ることができます。
「shallow」機能が広告される場合、以下で説明するように、以下の引数をクライアント要求に含めることができ、サーバーの応答に「shallow-info」セクションを追加する可能性があります。
- shallow <oid>
-
クライアントは、サーバーがクライアントの履歴の制限を認識できるように、そのようなオブジェクトごとに「shallow <oid>」行を指定することにより、shallowコピーしかない(つまり、そのコミットの親がないことを意味する、)すべてのコミットをサーバーに通知する必要があります。 これは、クライアントがそのようなコミットから到達可能なすべてのオブジェクトを持っていない可能性があることをサーバーが認識できるようにするためです。
- deepen <depth>
-
フェッチ/クローンを浅くし(shallow)、リモート側に対してコミットの深さが<depth>であることを要求します。
- deepen-relative
-
「deepen」コマンドのセマンティクスを変更して、要求された深さが、要求されたコミットではなく、クライアントの現在のshallow境界に関連していることを示すように要求します。
- deepen-since <timestamp>
-
shallow クローン/フェッチ を深さではなく特定の日付時刻でカットするように要求します。 内部的には、「git rev-list --max-age=<timestamp>」を実行するのと同じです。 「deepen」との併用はできません。
- deepen-not <rev>
-
shallow クローン/フェッチを、深さではなく、 <rev> で指定された特定のリビジョンでカットするように要求します。 内部的には、「git rev-list --not <rev>」を実行するのと同じです。 「deepen」では使用できませんが、「deepen-since」では使用できます。
filter
機能が広告される場合、以下の引数をクライアントの要求に含めることができます:
- filter <filter-spec>
-
いくつかのフィルタリング手法のいずれかを使用して、パックファイルのさまざまなオブジェクトを省略するように要求します。これらは、部分クローン(partial clone)および部分フェッチ(partial fetch)操作での使用を目的としています。 可能な「filter-spec」値については、
rev-list
を参照してください。他のプロセスと通信する場合、送信者はスケーリングされた整数(「1k」など)を完全に拡張された形式(「1024」など)に変換して、新発想のスケーリングサフィックスを理解できない古い受信者との相互運用性を支援する必要があります。しかしながら、受信者は次のサフィックスを受け入れる必要があります:「k」、「m」、「g」で、それぞれ、1024、1048576、1073741824 を現します。
「ref-in-want」機能が広告される場合、以下で説明するように、以下の引数をクライアントの要求に含めることができ、サーバーの応答に「wanted-refs」セクションを追加する可能性があります。
- want-ref <ref>
-
クライアントが特定のrefを取得することをサーバーに提示します。ここで、 <ref> はサーバー上のrefのフルネームです。
sideband-all
機能が広告される場合、以下の引数をクライアントの要求に含めることができます:
- sideband-all
-
packfileセクションだけでなく、応答全体を多重化して送信するようにサーバーに指示します。(packfileセクションだけでなく、)応答内のすべての非フラッシュ(non-flush)および non-delim PKT-LINEは、そのサイドバンド(1または2または3)を示すバイトで始まります。サーバーは、キープアライブパケットとして「0005\2」(ペイロードのないサイドバンド2のPKT-LINE)を送信する場合があります。
「packfile-uris」機能が広告される場合、以下で説明するように、以下の引数をクライアントの要求に含めることができ、サーバーの応答に「packfile-uris」セクションを追加する可能性があります。
- packfile-uris <comma-separated list of protocols>
-
クライアントが、送信されたパックファイル内のオブジェクトの代わりに、指定されたプロトコルのいずれかのURIを受信する用意があることをサーバーに提示します。 接続チェックを実行する前に、クライアントは指定されたすべてのURIからダウンロードする必要があります。 現在、サポートされているプロトコルは「http」と「https」です。
wait-for-done
機能が広告される場合、以下の引数をクライアントの要求に含めることができます。
- wait-for-done
-
サーバは決して "ready" を送らず、クライアントが "done" と言うまで待ってからパックファイルを送信するように指示します。
fetch
の応答は、区切り文字パケット(0001)で区切られたいくつかのセクションに分割され、各セクションはセクションヘッダーで始まります。ほとんどのセクションは、パックファイルが送信されたときにのみ送信されます。
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
-
-
クライアントが「done」行を送信してネゴシエーションが終了したと判断した場合(したがって、サーバーにパックファイルを送信する必要があります)、サーバーの応答からacknowledgmentsセクションを省略しなければなりません(MUST)。
-
常にセクションヘッダー「acknowledgements」で始まります
-
have行として送信されたオブジェクトIDがどれも共通していない場合、サーバーは「NAK」で応答します。
-
サーバーは、共通のhave行として送信されたすべてのオブジェクトIDに対して「ACK obj-id」で応答します。
-
応答に「ACK」行と「NAK」行の両方を含めることはできません。
-
サーバーは、サーバーが許容可能な共通ベースを検出し、packfile(同じ応答のpackfileセクションにあります)を作成して、送信する準備ができていることを示す「ready」行で応答します。
-
サーバーが適切な切断点(cut point)を見つけて「ready」行を送信することを決定した場合、サーバーは(最適化として)応答中に送信した「ACK」行を省略することを決定できます。これは、サーバーがクライアントに送信する予定のオブジェクトをすでに決定しており、それ以上のネゴシエーションが必要ないためです。
-
- shallow-info section
-
-
クライアントが shallow フェッチ/クローン を要求した場合、shallowクライアントがフェッチを要求するか、サーバーがshallowの場合、サーバーの応答に shallow-info セクションが含まれる場合があります。(上記の条件のいずれかにより、サーバーがクライアントにshallow 境界(shallow boundaries)を通知する必要がある場合、または既存の浅い境界をクライアントと調整する必要がある場合は、 shallow-info セクションが含まれます。
-
常にセクションヘッダー「shallow-info」で始まります
-
正数の深さが要求された場合、サーバーは指定の深さよりも深くないコミットのセットを計算します。
-
サーバーは、続くパックファイルで親が送信されないコミットごとに「shallow obj-id」行を送信します。
-
サーバーは、クライアントがshallowを指示したコミットごとに「unshallow obj-id」行を送信しますが、(その親が次のパックファイルで送信されるため、)フェッチの結果としてはshallowにはなりません。
-
サーバーは、クライアントが要求の一部としてshallowを指示していないものに対して、「unshallow」行を送信しては「いけません」。
-
- wanted-refs section
-
-
このセクションは、クライアントが「want-ref」行を使用してrefを要求し、packfileセクションも応答に含まれている場合にのみ含まれます。
-
常にセクションヘッダー「wanted-refs」で始まります。
-
サーバーは、「want-ref」行を使用して要求された参照ごとに、参照リスト("<oid> <refname>")を送信します。
-
サーバーは、「want-ref」行を使用して要求されなかった参照を送信しては「いけません」。
-
- packfile-uris section
-
-
このセクションは、クライアントが「packfile-uris」を送信し、サーバーに送信するそのようなURIが少なくとも1つある場合にのみ含まれます。
-
常にセクションヘッダー「packfile-uris」で始まります。
-
サーバーが送信するURIごとに、パックの内容のハッシュ(git index-packによって出力される)と、それに続くURIを送信します。
-
ハッシュの長さは40文字です。 Gitが新しいハッシュアルゴリズムにアップグレードするとき、これを更新する必要があるかもしれません。 (「pack\t」または「keep\t」の後に出力されるインデックスパックと一致する必要があります)。
-
- packfile section
-
-
このセクションは、クライアントがリクエストで「want」行を送信し、「done」を送信してこれ以上ネゴシエーションを行わないように要求した場合、または、サーバーがパックファイルを生成するのに十分なカットポイントを見つけたと判断した場合、のいずれかにのみ含まれます。
-
常にセクションヘッダー「packfile」で始まります
-
パックファイルの送信は、セクションヘッダーの直後に開始されます
-
パックファイルのデータ転送は、プロトコルバージョン1の「side-band-64k」機能と同じセマンティクスを使用して、常に多重化されます。つまり、packfileデータストリーム中の各パケットは、先頭の4バイトの pkt-line長(通常はpkt-line形式)、1バイトのストリームコード、実際のデータで構成されます。
ストリーム・コードは以下のいずれかです:
-
パックデータ
-
進行状況メッセージ
-
ストリームが中止(abort)される直前の致命的なエラーメッセージ
-
-
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は、特定のプロセスに固有である必要があります。それらはパケット行内に収まる必要があり、印刷不可能な文字や空白文字を含めることはできません。 現在の実装ではtrace2セッションID(詳細は api-trace2 参照)を使用していますが、これは変更される可能性があるため、セッションIDのユーザーはこの事実に依存しないでください。
object-info
object-info
は、1つまたは複数のオブジェクトに関する情報を取得するためのコマンドです。 その主な目的は、クライアントがオブジェクトを完全にフェッチすることなく、この情報に基づいて決定を下せるようにすることです。 現在サポートされている情報はオブジェクトサイズのみです。
object-info
リクエストは以下の引数を取ります:
- size
-
リストされたオブジェクトIDごとに返されるサイズ情報を要求します。
- oid <oid>
-
クライアントが情報を取得したいオブジェクトをサーバーに指示します。
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
機能が広告されている場合、サーバーは bundle-uri
コマンドをサポートします。
現在、この機能は値なし(つまり、 bundle-uri=ほげほげ 形式ではありません)で広告されていますが、コマンド全体の拡張機能をサポートするために、将来値が追加される可能性があります。クライアントは不明な機能値を無視し、サポートする bundle-uri
対話を続行しなければなりません。
bundle-uri
コマンドは、種(seed)にするためのバンドル・ファイルの URI を取得し、 後続の fetch
コマンドに通知するために、 fetch
の前に発行されることを目的としています。
クライアントは、他の有効なコマンドの前後に bundle-uri
を発行できます。クライアントにとって役立つように、 ls-refs
の後でかつ fetch
の前に発行されることが期待されますが、対話内のいつでも発行できます。
DISCUSSION of bundle-uri
この機能の目的は、 git-clone(1) 処理中に非常に大きなパックを取得する一般的なケースを、 より小さな増分フェッチに変更することで、 一般的なケースでのサーバー・リソースの消費を最適化することです。
また、 サーバーは uploadpack.packObjectsHook
と組み合わせてより優れたキャッシュを実現できます (git-config(1) 参照)。
新しいクローンやフェッチを、 最近生成された *.bundle ファイルの先端(tips)に対して、より予測可能で一般的なネゴシエーションを行うようにする。 サーバーは、新しいプッシュが来ると uploadpack.packObjectsHook
のために、そのようなネゴシエーションの結果を事前に生成するかもしれません。
サーバーがこれらのバンドルを利用する方法の一つは、新しいクローンが既知のバンドルをダウンロードし、その後にそのバンドルにある ref 先端(tips) を使ってリポジトリの現在の状態に追いつくことをサーバーが予測することである。
PROTOCOL for bundle-uri
bundle-uri
要求は引数無しで、上記の通り、現時点では機能値(capability value)を広告しません。いずれも将来追加される可能性はあります。
クライアントが command=bundle-uri
要求を発行すると、その応答は値 <key>=<value>
を持つパケット行として提供される、キーと値のペアのリストです。 各 <key>
は、バンドルのリストを作成するための bundle.*
名前空間の設定キーとして解釈される必要があります。これらのキーは bundle.<id>.
サブセクションによってグループ化されており、指定された <id>
に対応する各キーは、その <id>
によって定義されたバンドルに属性を提供します。これらのキーの具体的な詳細と、Git クライアントがそれらの値をどのように解釈するかについては、git-config(1) を参照してください。
クライアントは上記の形式に従って行をパースしなければいけません(MUST)、形式に従わない行は破棄されるべきです(SHOULD)。そののような場合、ユーザーに警告が表示されることがあります。
bundle-uri CLIENT AND SERVER EXPECTATIONS(bundle-uriクライアントとサーバが期待する事)
- URI CONTENTS
-
広告された URI の内容は、以下の 2 つのタイプのいずれかでなければなりません。
広告された URI には、
git bundle verify
が受け入れる事ができるバンドル・ファイルが含まれている場合があります。つまり、それらには、クライアントが使用するための 1 つ以上の参照先端(reference tips)が含まれていなければなりません(MUST)。標準の-
プレフィックスを使用して(いずれかの)前提条件を示さなければなりません(MUST)。また、該当する場合はobject-format
(オブジェクト形式)を示さなければなりません。広告された URI には、
git config --list
が受け入れられるプレーンテキスト・ファイルが含まれる場合もあります(--file
オプションを使用)。このリストのキーと値のペアは、bundle.*
名前空間内にあります (git-config(1) 参照)。 - bundle-uri CLIENT ERROR RECOVERY
-
そのエラーが、 バンドルURIの欠落やデータの誤りによるものであれ、クライアントがバンドルヘッダとその前提関係を理解せず解析しきれないほど間抜けであるためであれ、あるいは他の何かによるものであれ、クライアントは何よりもまず、エラーに対してすなおに縮退しなければなりません(MUST)。
サーバー管理者は、「bundle-uri」機能をオンにすることで、例えばCDNがダウンした場合でも、クローンやフェッチが重大な失敗することを心配する必要がなくなります。サーバーのバンドルが不完全であったり、何らかの形で不良であったりしても、クライアントは、このプロトコル拡張を使用しないことを選択した場合と同じように、機能するリポジトリを手にすることができます。
クライアントとサーバーの相互作用に関する以降のすべての議論は、これを念頭に置く必要があります。
- bundle-uri SERVER TO CLIENT
-
返されるバンドル URI の順序は重要ではありません。クライアントは、ヘッダーを解析して、含まれる OID と前提条件を検出する必要があります。クライアントは、バンドル自体のコンテンツとそのヘッダーを最も信頼できる情報源と見なす必要があります。
サーバーは(事故または意図的な「賢い」構成によって)、クローン作成されるリポジトリと直接関係のないバンドルを返してもよく、クライアントがそのバンドルからどのようなデータを取得したいかえり分けることを期待します。
- bundle-uri CLIENT TO SERVER
-
クライアントは、バンドル・ヘッダーで見つかった参照先端(reference tips)を、後続の「fetch」要求の「have」行として提供する必要があります。 クライアントは、何らかの理由、バンドルがダウンロードできない場合、見つけた先端(tips)が気に入らない場合など、 バンドル処理するほうがより悪いとみなされる場合、バンドルを完全に無視してもよいです。
- WHEN ADVERTISED BUNDLE(S) REQUIRE NO FURTHER NEGOTIATION(宣伝されたバンドルにそれ以上ネゴが必要ない場合)
-
bundle-uri
とls-refs
を発行し、バンドルのヘッダーを取得後、クライアントが必要なすべての ref 先端(tips)を広告されたバンドルから取得できることがわかった場合、クライアントはGit サーバーから切断してもよいです。このような「clone」または「fetch」の結果は、 bundle-uri を使用せずに得られた状態と区別できないものであるべきです。 - EARLY CLIENT DISCONNECTIONS AND ERROR RECOVERY(クライアントの早期切断とエラーリカバリ)
-
クライアントは、バンドルのダウンロード中(ヘッダーの転送・パース後)、早期切断を実行してもよい。 このような場合、クライアントは、バンドルのダウンロード終了と検証に関連するエラーから適切に回復しなければなりません。
つまり、クライアントは再接続して「fetch」コマンドを発行する必要がある場合があり、場合によっては「bundle-uri」をまったく使用しないようにフォールバックする可能性があります。
この、 (「しなければならない」(SHOULD)ではなく、)「してもよい」(MAY)という振る舞いは、バンドルURIを広告するサーバーが比較的大きなリポジトリを提供している可能性が高く、かつ、正常である可能性が高いURIを指しているという仮定に基づいています。 クライアントは、例えば、ヒューリスティックとしてバンドルのペイロ ード・サイズを確認して、早期に切断する価値があるかどうか、完全な「fetch」対話にフォールバックする必要があるかどうかを確認「してもよい」です。
- WHEN ADVERTISED BUNDLE(S) REQUIRE FURTHER NEGOTIATION(宣伝されているバンドルにさらなるネゴが必要な場合)
-
クライアントは、たとえバンドルをダウンロード途中であっても、広告されたバンドルで見つかった OID 先端(tips)を使用して、「fetch」コマンドを介してサーバーから PACK のネゴシエーションを開始する必要があります。
これにより、対話的なサーバーとの対話からの積極的な早期切断が可能になります。 クライアントは、広告された OID 先端(tips)が自分に関連していることを盲目的に信頼し、それらを「have」行として発行し、その後(通常は「ls-refs」広告から、)「want」行を介して必要な先端(tips)を要求します。次にサーバーは、バンドルからの先端(tips)と要求されたデータの間の期待される差分を使用して、(できれば小さい) PACK を計算します。
クライアントがアクティブに保っておく必要がある唯一の接続は、並列にダウンロードしている静的バンドルへの接続であり、そして、それらと増分 PACK が取得されるときに、解凍して検証する必要があります。 この時点でエラーが発生した場合は、正常に回復する必要があります(上記参照)。
bundle-uri PROTOCOL FEATURES
クライアントは、 サーバーから提供された <key>=<value>
ペア達からバンドル・リストを構築します。 これらのペア達は、 git-config(1) に記載されている bundle.*
名前空間の一部です。 このセクションでは、 これらのキーのいくつかについて説明し、 この情報に応じてクライアントが実行するアクションについて説明します。
特に、 bundle.version
キーは整数値を指定します。 現時点で受け入れられる唯一の値は 1
ですが、クライアントがここで予期しない値を見た場合、クライアントはバンドルリストを無視しなければなりません(MUST)。
bundle.version
が了解されている限り、他のすべての未知のキーはクライアントによって無視されても構いません(MAY)。サーバーは古いクライアントとの互換性を保証しますが、より新しいクライアントは追加のキーを使用してダウンロードを最小限に抑えることができる場合があります。
pre-URI Key-Value の後方互換性のない追加は 新しい bundle.version
値、または bundle-uri
機能広告自体、 および/または 将来の新しい bundle-uri
リクエスト引数によって保護されます。
現在は実装されていないが、将来実装される可能性があるキーと値のペアの例としては、以下のものが挙げられます:
-
hash=<val>
またはsize=<bytes>
を追加して、バンドル・ファイルの予想されるハッシュまたはサイズを広告します。 -
1 つ以上のバンドル・ファイルが同一であることを広告します(たとえば、クライアントにラウンドロビンさせたり、 N 個の可能なファイルから 1 つを選択させるため)。
-
oid=<OID>
ショートカットとprerequisite=<OID>
ショートカット。 1 つの先端(tip)かつ前提条件(prerequisites)無しのバンドル、 または 1 つの先端と 1 つの前提条件を備えたバンドルの一般的なケースを表現します。これにより、「メイン」ブランチ および/または その増分更新のみを含む 1 つの「大きなバンドル」を提供したいサーバーの一般的なケースを最適化できます。
そのような応答を受信したクライアントは、指定された URI にあるバンドルからヘッダーを取得することをスキップできると想定しても構いません(MAY)。これにより、そのバンドルのヘッダーを検査するために必要なリクエストを自分自身とサーバーが節約することができます。
GIT
Part of the git(1) suite