セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット作成
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
ガイド
- gitattributes
- コマンドラインインターフェースの慣例
- 日常のGit
- よくある質問 (FAQ)
- 用語集
- フック
- gitignore
- gitmodules
- リビジョン
- サブモジュール
- チュートリアル
- ワークフロー
- すべてのガイド...
管理
内部コマンド (Plumbing Commands)
-
2.49.0
2025-03-14
- 2.48.1 変更なし
-
2.48.0
2025-01-10
- 2.47.2 変更なし
-
2.47.1
2024-11-25
- 2.45.1 → 2.47.0 変更なし
-
2.45.0
2024-04-29
- 2.44.1 → 2.44.3 変更なし
-
2.44.0
2024-02-23
- 2.43.1 → 2.43.6 変更なし
-
2.43.0
2023-11-20
- 2.40.1 → 2.42.4 変更なし
-
2.40.0
2023-03-12
- 2.38.1 → 2.39.5 変更なし
-
2.38.0
2022-10-02
説明
このドキュメントは、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 | " -_.,?\/{}[]()<>!@#$%^&*+=:;")
コマンドリクエスト
機能広告を受信した後、クライアントは、特定の機能または引数を使用して、目的のコマンドを選択するリクエストを発行できます。その後、クライアントがコマンド固有のパラメーターまたはクエリを提供できるオプションのセクションがあります。一度に要求できるコマンドは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 are packet line framed arguments defined by each individual command.
その後、サーバーはクライアントのリクエストが有効なコマンドと広告された有効な機能で構成されていることを確認します。リクエストが有効な場合、サーバーはコマンドを実行します。サーバーは、応答を発行する前に、クライアントのすべてのリクエストを受信するまで待機する必要があります。応答の形式は実行されるコマンドによって決定されますが、すべての場合において、flush-pktは応答の終わりを示します。
コマンドが完了し、クライアントがサーバーからの応答全体を受信すると、クライアントは別のコマンドの実行を要求するか、接続を終了できます。クライアントは、これ以上リクエストを行わないことを示すために、flush-pktのみからなる空のリクエストをオプションで送信できます。
機能
機能には2つの異なるタイプがあります。情報伝達やリクエストの動作変更に使用できる通常の機能と、クライアントが実行したい主要なアクション(フェッチ、プッシュなど)であるコマンドです。
プロトコルバージョン2は、デフォルトでステートレスです。これは、すべてのコマンドは単一のラウンドで実行され、サーバー側の観点からはステートレスでなければならないことを意味します。ただし、クライアントがサーバーによって状態が維持されることを示す機能を要求した場合は除きます。クライアントは、正しく機能するためにサーバー側の状態管理を要求してはなりません。これにより、状態管理を心配することなく、サーバー側で単純なラウンドロビンロードバランシングが可能になります。
エージェント
サーバーは、`agent` 機能と値 `X`(`agent=X` の形式)を広告することで、サーバーがバージョン `X` を実行していることをクライアントに通知できます。クライアントはオプションで、自身のエージェント文字列を、値 `Y` を持つ `agent` 機能(`agent=Y` の形式)をサーバーへのリクエストに含めることで送信できます(ただし、サーバーが `agent` 機能を広告しなかった場合は送信してはなりません)。`X` と `Y` の文字列には、スペースを除く任意の印字可能なASCII文字(つまり、バイト範囲33 ≦ x ≦ 126)を含めることができ、通常は「package/version-os」(例:「git/1.8.3.1-Linux」)の形式です。ここで `os` はオペレーティングシステム名(例:「Linux」)です。`X` と `Y` は `GIT_USER_AGENT` 環境変数を使用して設定でき、こちらが優先されます。`os` は `uname(2)` システムコールまたはそれに相当するものの sysname フィールドを使用して取得されます。エージェント文字列は、統計およびデバッグ目的の情報提供のみを目的とし、特定の機能の有無をプログラム的に仮定するために使用してはなりません。
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の `fetch` の修正バージョンと見なすことができます。
基本コマンドでサポートされていない追加機能は、機能広告のコマンドの値として、スペース区切りの機能リストの形式で広告されます: "<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) で区切られた複数のセクションに分割され、各セクションはセクションヘッダーで始まります。ほとんどのセクションは、パックファイルが送信された場合にのみ送信されます。
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について、「ACK obj-id」で応答します。
-
応答には、「ACK」行と「NAK」行の両方を含めることはできません。
-
サーバーは「ready」行で応答し、許容可能な共通の基底を見つけ、パックファイルを作成して送信する準備ができたことを示します(これは同じ応答のパックファイルセクションで見つかります)。
-
サーバーが適切なカットポイントを見つけ、「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」で始まります。
-
正の深さが要求された場合、サーバーは要求された深さよりも深くならないコミットのセットを計算します。
-
サーバーは、次のパックファイルで親が送信されない各コミットに対して「shallow obj-id」行を送信します。
-
サーバーは、クライアントがシャローであると示したコミットのうち、今回のフェッチの結果として(親が次のパックファイルで送信されるため)もはやシャローではない各コミットに対して「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文字の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」で始まります。
-
パックファイルの転送は、セクションヘッダーの直後から始まります。
-
パックファイルのデータ転送は常に多重化され、プロトコルバージョン1のside-band-64k機能と同じセマンティクスを使用します。これは、パックファイルデータストリーム中の各パケットが、先行する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>」という機能行として送信することで行われます。
提供されるオプションには、NULまたはLF文字を含めてはなりません。
object-format
サーバーは `object-format` 機能に値 `X`(`object-format=X` の形式)を付加して広告することで、サーバーがハッシュアルゴリズムXを使用するオブジェクトを扱えることをクライアントに通知できます。指定されていない場合、サーバーはSHA-1のみを扱うと想定されます。クライアントがSHA-1以外のハッシュアルゴリズムを使用したい場合、そのobject-format文字列を指定する必要があります。
session-id=<session-id>
サーバーは、複数のリクエストでこのプロセスを識別するために使用できるセッションIDを広告できます。クライアントも自身のセッションIDをサーバーに広告し返すことができます。
セッションIDは、特定のプロセスに対して一意であるべきです。パケットライン内に収まり、印字不可能な文字や空白文字を含んではなりません。現在の実装ではtrace2セッションIDを使用していますが(詳細はapi-trace2を参照)、これは変更される可能性があり、セッションIDのユーザーはこの事実を当てにしてはなりません。セッション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 機能が広告されている場合、サーバーは '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` の結果を事前に生成することさえできます。
サーバーがこれらのバンドルを利用できる方法の1つは、新しいクローンが既知のバンドルをダウンロードし、そのバンドル(または複数のバンドル)で見つかった参照チップを使用してリポジトリの現在の状態に追いつくとサーバーが予測することです。
bundle-uri のプロトコル
bundle-uri
リクエストは引数をとりません。また、上記のとおり、現在、機能値を広告していません。両方とも将来追加される可能性があります。
クライアントが `command=bundle-uri` リクエストを発行すると、応答は `<key>=<value>` という値を持つパケットラインとして提供されるキーと値のペアのリストです。各 `<key>` は、`bundle.*` 名前空間からの設定キーとして解釈され、バンドルのリストを構築するために使用されます。これらのキーは `bundle.<id>.` サブセクションによってグループ化され、特定の `<id>` に対応する各キーは、その `<id>` によって定義されるバンドルに属性を提供します。これらのキーの詳細と、Gitクライアントがその値をどのように解釈するかについては、git-config[1]を参照してください。
クライアントは上記の形式に従って行を解析しなければならず、形式に適合しない行は破棄されるべきです。そのような場合、ユーザーに警告が出されることがあります。
bundle-uri クライアントとサーバーの期待
- URIの内容
-
広告されたURIの内容は、2種類のいずれかである必要があります。
広告されたURIは、`git bundle verify` が受け入れるバンドルファイルを含むことができます。つまり、クライアントが使用するための1つ以上の参照チップを含み、前提条件(もしあれば)を標準の「-」プレフィックスで示し、該当する場合は「object-format」を示す必要があります。
広告されたURIは、代わりに`git config --list`が受け入れる(`--file`オプション付きで)プレーンテキストファイルを含むこともできます。このリストのキーと値のペアは、`bundle.*`名前空間に属します(git-config[1]を参照)。
- bundle-uri クライアントのエラー回復
-
クライアントは、エラーが発生した場合(バンドルURIのデータが不足している、または破損している場合、クライアントがバンドルヘッダーとその前提条件の関係を理解して完全に解析できないなど、またはその他の理由)、何よりもまず gracefully degrade (優雅に機能低下) する必要があります。
サーバー運営者は、「bundle-uri」を安心して有効にでき、たとえばCDNがダウンした場合でも、クローンやフェッチがハードな障害に遭遇することを心配する必要がありません。たとえサーバーのバンドルが不完全であったり、何らかの形で不良であったりしても、このプロトコル拡張を使用しない場合と同様に、クライアントは最終的に機能するリポジトリを得られるはずです。
クライアントとサーバーの相互作用に関するその後のすべての議論は、この点を念頭に置く必要があります。
- bundle-uri サーバーからクライアントへ
-
返されるバンドルURIの順序は重要ではありません。クライアントは、含まれるOIDと前提条件を発見するためにヘッダーを解析する必要があります。クライアントは、バンドル自体の内容とそのヘッダーを究極の真実の源と見なすべきです。
サーバーは、クローンされているリポジトリと直接関係のないバンドルを返すことさえできます(偶然、または意図的な「賢い」構成によるもの)。そして、クライアントがバンドルから必要なデータを選択することを期待します。
- bundle-uri クライアントからサーバーへ
-
クライアントは、後続の `fetch` リクエストにおいて、バンドルヘッダーで見つかった参照チップを have 行として提供すべきです。クライアントは、何らかの理由でそれが悪いと判断された場合、例えばバンドルがダウンロードできない、見つけたチップが気に入らないなどの場合、バンドルを完全に無視することもできます。
- 広告されたバンドルがそれ以上の交渉を必要としない場合
-
bundle-uri
とls-refs
を発行し、バンドルヘッダーを取得した後、クライアントが欲する参照チップを広告されたバンドルから完全に取得できると判断した場合、クライアントはGitサーバーから切断しても構いません。そのようなクローンまたはフェッチの結果は、bundle-uriを使用しない場合と区別できないはずです。 - クライアントの早期切断とエラー回復
-
クライアントは、バンドルをダウンロード中に(ヘッダーをストリームして解析した後)早期に切断する場合があります。そのような場合、クライアントはバンドルのダウンロードと検証の完了に関連するエラーから gracefully (優雅に) 回復しなければなりません。
つまり、クライアントは再接続して fetch コマンドを発行する必要があるかもしれませんし、場合によっては bundle-uri を全く使用しないというフォールバックが必要になるかもしれません。
この「MAY」の動作は、サーバーがバンドルURIを広告している場合、比較的大きなリポジトリを提供している可能性が高く、機能している可能性が高いURIを指しているという仮定に基づいて指定されています(「SHOULD」ではなく)。クライアントは、例えば、バンドルのペイロードサイズをヒューリスティックとして見て、早期切断が価値があるかどうかを判断するかもしれません。完全な「fetch」ダイアログへのフォールバックが必要な場合でも。
- 広告されたバンドルがさらなる交渉を必要とする場合
-
クライアントは、広告されたバンドル内で見つかったOIDチップを使用して、サーバーから「fetch」コマンドを介してPACKの交渉を開始すべきです。たとえそれらのバンドルのダウンロードが進行中であってもです。
これにより、対話型サーバーダイアログからの積極的な早期切断が可能になります。クライアントは、広告されたOIDチップが関連性があると盲目的に信頼し、それらをhave行として発行します。次に、希望するチップ(通常は「ls-refs」広告から)をwant行を介して要求します。サーバーは、バンドルからのチップと要求されたデータの間の予想される差分を含む(うまくいけば小さな)PACKを計算します。
クライアントがその後アクティブに保つ必要がある接続は、同時にダウンロード中の静的バンドルのみです。それらと増分PACKが取得されたら、それらは展開され、検証されるべきです。この時点でのエラーはすべて gracefully (優雅に) 回復されるべきです。上記を参照してください。
bundle-uri プロトコル機能
クライアントは、サーバーから提供された `<key>=<value>` ペアからバンドルリストを構築します。これらのペアは、git-config[1] に記載されている `bundle.*` 名前空間の一部です。このセクションでは、これらのキーの一部と、この情報に応じてクライアントが行うアクションについて説明します。
特に、`bundle.version` キーは整数値を指定します。現時点で受け入れられる唯一の値は `1` ですが、クライアントがここで予期しない値を見つけた場合、クライアントはバンドルリストを無視しなければなりません。
bundle.version
が理解される限り、他のすべての不明なキーはクライアントによって無視される場合があります。サーバーは古いクライアントとの互換性を保証しますが、新しいクライアントは追加のキーをより効果的に使用してダウンロードを最小限に抑えることができる場合があります。
URI前のキーと値の互換性のない追加は、新しい `bundle.version` 値、または bundle-uri 機能広告自体の値、および/または新しい将来の `bundle-uri` リクエスト引数によって保護されます。
現在実装されていませんが、将来実装される可能性のあるキーと値のペアの例をいくつか示します。
-
バンドルファイルの予想されるハッシュまたはサイズを広告するために、「hash=<val>」または「size=<bytes>」を追加します。
-
1つ以上のバンドルファイルが同じであることを広告する(例:クライアントにラウンドロビンさせたり、N個の可能なファイルの中から1つを選択させたりするため)。
-
「oid=<OID>」ショートカットと「prerequisite=<OID>」ショートカット。1つのチップと前提条件なし、または1つのチップと1つの前提条件を持つバンドルの一般的なケースを表現するため。
これにより、「メイン」ブランチのみを含む「大きなバンドル」、および/またはその増分更新を提供したいサーバーの一般的なケースを最適化できます。
このような応答を受け取ったクライアントは、指示された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です。
この場合、クライアントがサーバーが広告した1つ以上のプロミサーリモートを使用することを決定した場合、クライアントは「promisor-remote=<pr-names>」で応答できます。ここで <pr-names> は次の形式になります。
pr-names = pr-name | pr-names ";" pr-name
ここで、`pr-name` はサーバーが広告し、クライアントが受け入れたプロミサーリモートのURLエンコードされた名前です。
なお、このドキュメントのどこにおいても、`pr-name` は有効なリモート名でなければならず、`pr-name` または `pr-url` に現れる `_;` と `,` 文字はエンコードされなければなりません。
サーバーが、クライアントが使用するのに適したプロミサーリモートを知らない場合、またはクライアントがサーバーが使用または知っているプロミサーリモートを使用しないことを好む場合、サーバーは「promisor-remote」機能を一切広告すべきではありません。
この場合、またはクライアントがサーバーが広告したプロミサーリモートを使用したがらない場合、クライアントは自身の応答で「promisor-remote」機能を一切広告すべきではありません。
「promisor.advertise」および「promisor.acceptFromServer」設定オプションは、サーバー側とクライアント側で、それぞれ広告するものと受け入れるものを制御するために使用できます。これらの設定オプションの詳細については、ドキュメントを参照してください。
将来的に、「promisor-remote」プロトコル機能が、`git fetch` または `git clone` への応答時にサーバーによって使用され、このリポジトリの代わりにクライアントがプロミサーリモートとして使用できる、より接続性の良いリモートを広告できるようになると良いでしょう。そうすることで、クライアントはこれらのより接続性の良いリモートからオブジェクトを遅延フェッチできます。これには、サーバーが、クライアントが受け入れた、より接続性の良いリモートで利用可能なオブジェクトを応答から省略する必要があります。しかし、これはまだ実装されていません。したがって、今のところ、この「promisor-remote」機能は、サーバーがすでにオブジェクトを借りるために使用しているプロミサーリモートを広告する場合にのみ有用です。
GIT
git[1] スイートの一部