Note
このドキュメントでは、パックプロトコルのバージョン 0 および 1 の機能について説明します。 バージョン 2 については、 protocol-v2 ドキュメントを参照してください。

サーバーは、このドキュメントで定義されているすべての機能をサポートするべきです。

receive-pack および upload-pack の最初のサーバー応答の最初の行で、最初の参照の後に NUL バイトが続き、次にスペースで区切られたサーバー機能のリストが続きます。 これらにより、サーバーはクライアントに対してサポートできるものとサポートできないものを宣言できます。

次に、クライアントは、有効にしたい機能のスペース区切りのリストを送信します。 クライアントは、サーバーがサポートしているとは言っていない機能を要求してはいけません。

サーバーは送信された機能について診断し、理解できない機能が送信された場合、中止(abort)しなければなりません。サーバーは、クライアントが要求し、かつ、サーバーが宣伝(advertise)した機能の実行を無視してはなりません。 これらのルールの結果として、サーバーは理解できない機能を宣伝してはなりません。

atomic 機能と report-status 機能と report-status-v2 機能と delete-refs 機能と quiet 機能と push-cert 機能が送信され、 receive-pack 処理(サーバーへのプッシュ処理)によって認識されます。

ofs-deltaside-band-64k 機能は、 upload-pack プロトコルと receive-pack プロトコルの両方によって送信および認識されます。 agent 機能と session-id 機能は、オプションで両方のプロトコルで送信できます。

他のすべての機能は、upload-pack (サーバーからのフェッチ) 処理によってのみ認識されます。

multi_ack

「multi_ack」機能により、サーバーは、クライアントの要求セットと所持しているセットの間で、共通のベースとして使用できるコミットを見つけるとすぐに「ACK obj-id continue」を返すことができます。

これを早期に送信することで、サーバーは、クライアントがクライアントのリポジトリ履歴の特定のブランチをさらにたどり下っていくのを防ぐことができます。 クライアントは、サーバーが DAG を完全に通過するまで、またはクライアントが「完了」と言うまで、他のブランチをたどってそれらのラインを送信する必要がある場合があります。

multi_ack がない場合、サーバーが共通のベースを見つけるまで、クライアントは --date-order で 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 のベースが必要です。 クライアントは、a に到達するまで S-R-Q を続行し、到達した時点でサーバーは明確なベースを持ち、すべてが終了します。

multi_ackがなければ、クライアントは S-R-Q を差し挟んで、いずれにせよ c-b-a チェーンを送信していたでしょう。

multi_ack_detailed

これは、クライアントがサーバーのメモリ内状態をよりよく理解できるようにする multi_ack の拡張です。 詳細については、 pack-protocol.txt の「Packfile Negotiation」セクションを参照してください。

no-done

この機能は、スマート HTTP プロトコルでのみ使用するべきです。 multi_ack_detailed と no-done の両方が存在する場合、送信者は、最初の「ACK obj-id ready」メッセージに続いて、パックをすぐに自由に送信できます。

スマート HTTP プロトコルで no-done がないと、サーバーセッションが終了し、サーバーがパックを送信する前に、クライアントは "done" を送信するために別のトリップ(trip)を行う必要があります。 no-done は最後のラウンド(round)を削除するため、待ち時間がわずかに短縮されます。

thin-pack

シンパックは、パック内に含まれていないベースオブジェクトを参照するデルタを持つパックです (ただし、受信側に存在することがわかっています)。 これにより、ネットワークトラフィックを大幅に削減できますが、受信側は、不足しているベースをパックに追加してこれらのパックを「厚く」する方法を知っている必要があります。

upload-pack サーバーは、シンパックを生成して送信できる場合に「thin-pack」を宣伝(advertise)します。 クライアントは、それを「厚く」する方法を理解したときに「thin-pack」機能を要求し、そのようなパックを受信できることをサーバーに通知します。 シンパックを自己完結型パックに変換できない場合、クライアントは「thin-pack」機能を要求してはなりません。

一方、 receive-pack はデフォルトでシンパックを処理できると想定されていますが、「no-thin」機能をアドバタイズすることで、クライアントに機能を使用しないように要求できます。 サーバーが「no-thin」機能を宣伝する場合、クライアントはシンパックを送信してはなりません。

この非対称性の理由は歴史的なものです。 receive-pack プログラムはシンパックが発明されるまで存在しなかったため、歴史的には receive-pack のリファレンス実装は常にシンパックを理解していました。 後で「no-thin」を追加すると、後方互換性のある方法で receive-pack が機能を無効にすることができました。

side-band, side-band-64k

この機能は、サーバーが送信できることを意味し、クライアントは、パックファイル自体に差し挟まれた多重化された進行状況レポートとエラー情報を理解します。

これら 2 つのオプションは相互に排他的です。 最新のクライアントは、常に「side-band-64k」を好みます。

いずれのモードも、パックファイルデータが「side_band」の場合は最大 1000 バイト、「side_band_64k」の場合は 65520 バイトのパケットに分割されてストリーミングされることを示します。 各パケットは、パケット内のデータ量を示す先頭の 4 バイトの pkt-line 長と、その後に続く 1 バイトのストリームコード、および実際のデータで構成されます。

ストリームコードは以下のいずれか一つです:

1 - パックデータ
2 - 進行メッセージ
3 - ストリームが中止(abort)される直前の致命的なエラーメッセージ

「side-band-64k」機能は、古いクライアントとの下位互換性を維持しながら、実際にはほぼいっぱいに詰め込まれたパケットを要求するために、はるかに大きなパケットを処理できる新しいクライアントの方法として生まれました。

さらに、 side-band とその最大 1000 バイトのメッセージを使用すると、実際には 999 バイトのペイロードと 1 バイトのストリームコードになります。 side-band-64k を使用すると、同じ取引で、最大 65519 バイトのデータと 1 バイトのストリームコードで使用できます。

クライアントは、 "side-band" と "side-band-64k" の最大値のどちらか 1 つだけ送信しなければなりません。 クライアントが両方を要求した場合、サーバーはそれをエラーとして診断しなければなりません。

ofs-delta

サーバーは送信でき、クライアントは、obj-id ではなくパック内の位置によってベースを参照するデルタを使用して PACKv2 を理解します。 つまり、パックファイルで OBJ_OFS_DELTA (別名:タイプ 6) を 送信/読み取り することができます。

agent

サーバーは、サーバーがバージョン「X」を実行していることをクライアントに通知するために、オプションで「agent=X」の形式の機能を送信できます。 クライアントはオプションで、agent=Y 機能で応答することにより、独自のエージェント文字列を返すことができます (ただし、サーバーがエージェント機能について言及していない場合は、そうしてはなりません)。 X および Y 文字列には、スペースを除く任意の印刷可能な ASCII 文字 (つまり、バイト範囲 32 < x < 127) を含めることができ、通常は「パッケージ/バージョン」(「git/1.8.3.1」など) の形式になります。 エージェント文字列は、統計とデバッグの目的で純粋に情報を提供するものであり、特定の機能の有無をプログラムで想定するために使用してはなりません。

object-format

ハッシュアルゴリズムを引数として取るこの機能は、サーバーが特定のハッシュ アルゴリズムをサポートしていることを示します。 複数回送信される場合があります。 その場合、最初に指定されたものは、ref 広告(ref advertisement)で使用されたものです。

クライアントによって提供された場合、これは、クライアントが指定のハッシュアルゴリズムを使用して通信することを意図していることを示します。 提供されるアルゴリズムは、サーバーがサポートするものでなければなりません。

この機能が提供されていない場合、サポートされているアルゴリズムは SHA-1 だけであると見なされます。

symref

このパラメーター化された機能は、どのシンボリック ref がどの ref を指しているかを受信者に通知するために使用されます。 たとえば、 symref=HEAD:refs/heads/master は、HEAD が master を指していることをレシーバーに伝えます。 この機能を繰り返して、複数の symref を表すことができます。

HEAD symref が送信される参照の 1 つである場合、サーバーはこの機能を HEAD symref に含めるべきです。

クライアントは、この機能のパラメーターを使用して、リポジトリのクローンを作成するときに適切な初期ブランチを選択するでしょう。

shallow

この機能は、「deepen」と「shallow」と「unshallow」コマンドを fetch-pack/upload-pack プロトコルに追加して、クライアントが浅いクローン(shallow clones)を要求できるようにします。

deepen-since

この機能により、「deepen-since」コマンドが fetch-pack/upload-pack プロトコルに追加されるため、クライアントは深さではなく、特定の日時でカットされる浅いクローンを要求できます。 内部的には、サーバー側で rev-list --max-age=<timestamp> を実行するのと同じです。 「deepen-since」は「deepen」と併用できません。

deepen-not

この機能により、「deepen-not」コマンドが fetch-pack/upload-pack プロトコルに追加されるため、クライアントは深さではなく特定のリビジョンでカットされた浅いクローンを要求できます。 内部的には、サーバー側で rev-list --not <rev> を実行するのと同じです。 「deepen-not」は「deepen」では使用できませんが、「deepen-since」では使用できます。

deepen-relative

この機能がクライアントによって要求された場合、「deepen」コマンドのセマンティクスが変更されます。 「深さ」引数は、リモートrefからの深さではなく、現在の浅い境界からの深さです。

no-progress

クライアントは「git clone -q」などで開始され、その サイドバンド 2 は必要ありません。基本的に、クライアントは「私はサイドバンドでストリーム 2 を受信したくないので、送信しないでください。 もし送信されたら、とにかく破棄します。(I will drop it on the floor anyway)」 ただし、サイドバンド チャネル 3 はエラー応答に引き続き使用されます。

include-tag

「include-tag」機能は、それらが指すオブジェクトを送信する場合に、注釈付きタグを送信することに関するものです。 オブジェクトをクライアントにパックし、タグ オブジェクトがそのオブジェクトを正確に指す場合、タグオブジェクトもパックします。 一般に、これにより、クライアントは単一のネットワーク接続でブランチをフェッチするときに、すべての新しい注釈付きタグを取得できます。

クライアントは、サーバーがこの機能を宣伝するときに、常に include-tag を要求にハードコーディングして送信しても構いません。 クライアントが include-tag を要求するかどうかの決定は、サーバーが refs/tags/* 名前空間でオブジェクトを宣伝したかどうかに関係なく、タグデータに対するクライアントの要求にのみ関係があります。

サーバーは、リファラント(referrant)がパックされていて、クライアントが include-tags を要求している場合、タグをパックする必要があります。

クライアントは、サーバーが include-tag を無視し、パック内のタグを実際に送信していない場合に備えなければなりません。 そのような場合、クライアントは後続のフェッチを発行して、そうでなければ include-tag がクライアントに与えるタグを取得する必要があります。

サーバーは、使用可能なタグがあるかどうかに関係なく、サポートしている場合、 include-tag を送信すべきです。

report-status

receive-pack プロセスは、「report-status」機能を受け取ることができます。これは、クライアントがパックファイルのアップロードと参照の更新後に何が起こったかのレポートを必要としていることを伝えます。 プッシュするクライアントがこの機能を要求すると、参照をアンパックして更新した後、サーバーはパックファイルが正常にアンパックされたかどうか、および各参照が正常に更新されたかどうかを応答します。 それらのいずれかが成功しなかった場合、エラーメッセージが返されます。 メッセージの例については、pack-protocol.txt を参照してください。

report-status-v2

機能「report-status-v2」は、「proc-receive」フックによって書き換えられた参照をサポートするために、新しい「option」ディレクティブを追加して機能「report-status」を拡張します。 「proc-receive」フックは、異なる名前、new-oid、および old-oid で参照を作成または更新する可能性がある疑似参照のコマンドを処理できます。 機能「report-status」ではそのような場合にレポートできません。 詳細については、 pack-protocol.txt を参照してください。

delete-refs

サーバーが「delete-refs」機能を返送する場合、それは参照更新のターゲット値としてゼロ ID 値を受け入れることができることを意味します。 クライアントから送り返されるのではなく、参照を削除するためにゼロ ID 値を送信できることをクライアントに通知するだけです。

quiet

receive-pack サーバーが「quiet」機能を宣伝する場合、受信したパックを処理するときに表示される可能性のある、人間が読める進行状況出力を黙らせる事ができます。 send-pack クライアントは、ローカルの進捗レポートも抑制されている場合 (たとえば、「push -q」を介して、または stderr が tty に出力されない場合)、サーバー側の進捗レポートを抑制する「quiet」機能で応答する必要があります。

atomic

サーバーが「atomic」機能を送信すると、アトミック プッシュを受け入れることができます。 プッシュするクライアントがこの機能を要求すると、サーバーはたった 1 つのアトミック取引(atomic transaction)でrefを更新します。 すべてのrefが更新されるか、まったく更新されません。

push-options

サーバーが「push-options」機能を送信すると、updateコマンドが送信された後、パックファイルがストリーミングされる前に、プッシュ オプションを受け入れることができます。 プッシュするクライアントがこの機能を要求すると、サーバーは、このプッシュ要求を処理する pre-receive フックと post-receive フックにオプションを渡します。

allow-tip-sha1-in-want

upload-pack サーバーがこの機能を宣伝する場合、fetch-pack は、サーバーに存在するが、upload-pack によって宣伝されていないオブジェクト名を含む「want」行を送信する場合があります。 歴史的な理由から、この機能の名前には「sha1」が含まれています。 オブジェクト名は常に、「object-format」機能によってネゴシエートされたオブジェクトフォーマットを使用して指定されます。

allow-reachable-sha1-in-want

upload-pack サーバーがこの機能を宣伝する場合、fetch-pack は、サーバーに存在するが、upload-pack によって宣伝されていないオブジェクト名を含む「want」行を送信する場合があります。 歴史的な理由から、この機能の名前には「sha1」が含まれています。 オブジェクト名は常に、「object-format」機能によってネゴシエートされたオブジェクトフォーマットを使用して指定されます。

push-cert=<nonce>

この機能を宣伝する receive-pack サーバーは、署名されたプッシュ証明書を喜んで受け入れ、<nonce> をプッシュ証明書に含めるように要求します。 send-pack クライアントは、receive-pack サーバーがこの機能を宣伝しない限り、push-cert パケットを送信してはいけません (MUST NOT)。

filter

upload-pack サーバーが「filter」機能を宣伝する場合、fetch-pack は「filter」コマンドを送信して部分クローン(partial clone)または部分フェッチ(partial fetch)を要求し、サーバーがパックファイルからさまざまなオブジェクトを省略するように要求する場合があります。

session-id=<session id>

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

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