日本語 ▾ トピック ▾ 最新バージョン ▾ gitprotocol-http 最終更新: 2.44.0

名前

gitprotocol-http - Git HTTPベースのプロトコル

概要

<over-the-wire-protocol>

説明

Gitは2つのHTTPベースの転送プロトコルをサポートしています。接続のサーバー側で標準のHTTPサーバーのみを必要とする「ダム (dumb)」プロトコルと、Git対応のCGI(またはサーバーモジュール)を必要とする「スマート (smart)」プロトコルです。このドキュメントでは、両方のプロトコルについて説明します。

設計上の機能として、スマートクライアントは「ダム」プロトコルURLをスマートURLに自動的にアップグレードできます。これにより、すべてのユーザーが同じ公開URLを持つことができ、ピアは利用可能な最も効率的なトランスポートを自動的に選択します。

URL形式

HTTPでアクセスされるGitリポジトリのURLは、RFC 1738で文書化されている標準的なHTTP URL構文を使用するため、次の形式になります。

http://<host>:<port>/<path>?<searchpart>

このドキュメントでは、プレースホルダー $GIT_URL はエンドユーザーが入力する http:// リポジトリURLを表します。

サーバーは $GIT_URL に一致する場所へのすべてのリクエストを処理 SHOULD (すべき) です。Gitが使用する「スマート」および「ダム」HTTPプロトコルは両方とも、ユーザーが指定した $GIT_URL 文字列の末尾に追加のパスコンポーネントを付加して動作するためです。

ダムクライアントがルーズオブジェクトを要求する例

$GIT_URL:     http://example.com:8080/git/repo.git
URL request:  http://example.com:8080/git/repo.git/objects/d0/49f6c27a2244e12041955e262a404c7faba355

キャッチオールゲートウェイへのスマートなリクエストの例

$GIT_URL:     http://example.com/daemon.cgi?svc=git&q=
URL request:  http://example.com/daemon.cgi?svc=git&q=/info/refs&service=git-receive-pack

サブモジュールへのリクエストの例

$GIT_URL:     http://example.com/git/repo.git/path/submodule.git
URL request:  http://example.com/git/repo.git/path/submodule.git/info/refs

クライアントは、ユーザーが指定した $GIT_URL 文字列から、末尾の / が存在する場合は削除 MUST (しなければならない) です。これにより、サーバーに送信されるURLに空のパストークン (//) が現れるのを防ぎます。互換性のあるクライアントは $GIT_URL/info/refsfoo/info/refs として展開 MUST (しなければならない) であり、foo//info/refs としては展開すべきではありません。

認証

リポジトリへのアクセスに認証が必要な場合は、標準のHTTP認証が使用され、HTTPサーバーソフトウェアによって設定および強制 MAY (してもよい) です。

Gitリポジトリは標準のパスコンポーネントによってアクセスされるため、サーバー管理者はHTTPサーバー内でディレクトリベースのアクセス許可を使用してリポジトリへのアクセスを制御 MAY (してもよい) です。

クライアントはRFC 2617に記述されている基本認証をサポート SHOULD (すべき) です。サーバーはGitサーバーソフトウェアの前に配置されたHTTPサーバーに依存して基本認証をサポート SHOULD (すべき) です。

サーバーは認証またはアクセス制御の目的でHTTPクッキーを要求すべきではありません (SHOULD NOT)。

クライアントとサーバーは、ダイジェスト認証などの他の一般的なHTTPベースの認証形式をサポート MAY (してもよい) です。

SSL

クライアントとサーバーはSSLをサポート SHOULD (すべき) です。特に基本HTTP認証に依存する場合、パスワードを保護するために重要です。

セッション状態

HTTP上のGitプロトコル(HTTP自体と同様に)は、HTTPサーバー側の観点からはステートレスです。すべての状態はクライアントプロセスによって保持および管理される MUST (しなければならない) です。これにより、状態管理を心配することなく、サーバー側での単純なラウンドロビンロードバランシングが可能になります。

クライアントは、正しく機能するためにサーバー側での状態管理を要求すべきではありません (MUST NOT)。

サーバーは、正しく機能するためにHTTPクッキーを要求すべきではありません (MUST NOT)。クライアントは、RFC 2616 (HTTP/1.1) に記述されているように、リクエスト処理中にHTTPクッキーを保存および転送 MAY (してもよい) です。サーバーは、クライアントによって送信されたすべてのクッキーを無視 SHOULD (すべき) です。

一般的なリクエスト処理

特に記載がない限り、クライアントとサーバーの両方で、すべての標準的なHTTP動作が仮定される SHOULD (べき) です。これには、(ただし、必ずしもこれらに限定されない)

$GIT_URL にリポジトリがない場合、または $GIT_URL に一致する場所が指すリソースが存在しない場合、サーバーは 200 OK レスポンスで応答すべきではありません (MUST NOT)。サーバーは 404 Not Found410 Gone、またはリソースが要求通りに存在することを暗示しないその他の適切なHTTPステータスコードで応答 SHOULD (すべき) です。

$GIT_URL にリポジトリがあるが、現在アクセスが許可されていない場合、サーバーは 403 Forbidden HTTPステータスコードで応答 MUST (しなければならない) です。

サーバーはHTTP 1.0とHTTP 1.1の両方をサポート SHOULD (すべき) です。サーバーはリクエストとレスポンスの両方のボディに対してチャンクエンコーディングをサポート SHOULD (すべき) です。

クライアントはHTTP 1.0とHTTP 1.1の両方をサポート SHOULD (すべき) です。クライアントはリクエストとレスポンスの両方のボディに対してチャンクエンコーディングをサポート SHOULD (すべき) です。

サーバーはETagおよび/またはLast-Modifiedヘッダーを返してもよい (MAY)。

クライアントはIf-Modified-Sinceおよび/またはIf-None-Matchリクエストヘッダーを含めることで、キャッシュされたエンティティを再検証してもよい (MAY)。

関連するヘッダーがリクエストに存在し、エンティティが変更されていない場合、サーバーは 304 Not Modified を返してもよい (MAY)。クライアントはキャッシュされたエンティティを再利用することで、304 Not Modified200 OK と同一に扱う MUST (しなければならない) です。

Cache-Controlおよび/またはExpiresヘッダーがキャッシュを許可する場合、クライアントは再検証なしにキャッシュされたエンティティを再利用してもよい (MAY)。クライアントとサーバーはキャッシュ制御のためにRFC 2616に従う MUST (しなければならない) です。

参照の発見

すべてのHTTPクライアントは、フェッチまたはプッシュのいずれかの交換をリモートリポジトリで利用可能な参照を発見することによって開始 MUST (しなければならない) です。

ダムクライアント

「ダム」プロトコルのみをサポートするHTTPクライアントは、リポジトリの特別なinfo/refsファイルへのリクエストを行うことによって参照を発見 MUST (しなければならない) です。

ダムHTTPクライアントは、検索/クエリパラメータなしで、$GIT_URL/info/refsGET リクエストを行う MUST (しなければならない) です。

C: GET $GIT_URL/info/refs HTTP/1.0
S: 200 OK
S:
S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31	refs/heads/maint
S: d049f6c27a2244e12041955e262a404c7faba355	refs/heads/master
S: 2cb58b79488a98d2721cea644875a8dd0026b115	refs/tags/v1.0
S: a3c2e2402b99163d1d59756e5f207ae21cccba4c	refs/tags/v1.0^{}

返されるinfo/refsエンティティのContent-Typeは text/plain; charset=utf-8 である SHOULD (べき) ですが、任意のコンテンツタイプであってもよい (MAY)。クライアントは返されたContent-Typeを検証しようとすべきではありません (MUST NOT)。ダムサーバーは application/x-git- で始まる返却タイプを返すべきではありません (MUST NOT)。

Cache-Controlヘッダーは、返されたエンティティのキャッシュを無効にするために返されてもよい (MAY)。

応答を検証する際、クライアントはHTTPステータスコードのみを検証すべきです (SHOULD)。有効な応答は 200 OK または 304 Not Modified です。

返されるコンテンツは、各参照とその既知の値を記述するUNIX形式のテキストファイルです。ファイルはCロケールの順序に従って名前でソートされる SHOULD (べき) です。ファイルには HEAD というデフォルトの参照を含めるべきではありません (SHOULD NOT)。

info_refs   =  *( ref_record )
ref_record  =  any_ref / peeled_ref
any_ref     =  obj-id HTAB refname LF
peeled_ref  =  obj-id HTAB refname LF
 obj-id HTAB refname "^{}" LF

スマートクライアント

「スマート」プロトコル(または「スマート」と「ダム」の両方のプロトコル)をサポートするHTTPクライアントは、リポジトリのinfo/refsファイルに対するパラメータ化されたリクエストを行うことによって参照を発見 MUST (しなければならない) です。

リクエストには、service=$servicename というクエリパラメータが正確に1つ含まれる MUST (しなければならない) です。ここで $servicename は、クライアントが操作を完了するために接触したいサービス名である MUST (しなければならない) です。リクエストには追加のクエリパラメータを含めるべきではありません (MUST NOT)。

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

ダムサーバー応答

S: 200 OK
S:
S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31	refs/heads/maint
S: d049f6c27a2244e12041955e262a404c7faba355	refs/heads/master
S: 2cb58b79488a98d2721cea644875a8dd0026b115	refs/tags/v1.0
S: a3c2e2402b99163d1d59756e5f207ae21cccba4c	refs/tags/v1.0^{}

スマートサーバー応答

S: 200 OK
S: Content-Type: application/x-git-upload-pack-advertisement
S: Cache-Control: no-cache
S:
S: 001e# service=git-upload-pack\n
S: 0000
S: 004895dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\0multi_ack\n
S: 003fd049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n
S: 003c2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n
S: 003fa3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n
S: 0000

クライアントは、Git-Protocol HTTPヘッダーにコロン区切りの文字列として追加パラメータ(gitprotocol-pack[5]参照)を送信してもよい (MAY)。

git-upload-pack[1]--http-backend-info-refs オプションを使用します。

ダムサーバー応答

ダムサーバーはダムサーバー応答形式で応答 MUST (しなければならない) です。

ダムサーバー応答の詳細については、ダムクライアントに関する前のセクションを参照してください。

スマートサーバー応答

サーバーが要求されたサービス名を認識しない場合、または要求されたサービス名がサーバー管理者によって無効にされている場合、サーバーは 403 Forbidden HTTPステータスコードで応答 MUST (しなければならない) です。

そうでない場合、スマートサーバーは要求されたサービス名に対してスマートサーバー応答形式で応答 MUST (しなければならない) です。

返されたエンティティのキャッシュを無効にするために、Cache-Controlヘッダーを使用 SHOULD (すべき) です。

Content-Typeは application/x-$servicename-advertisement である MUST (しなければならない) です。別のコンテンツタイプが返された場合、クライアントはダムプロトコルにフォールバック SHOULD (すべき) です。ダムプロトコルにフォールバックする際、クライアントは $GIT_URL/info/refs に追加のリクエストを行うべきではありません (SHOULD NOT)。代わりに、既に手元にある応答を使用 SHOULD (すべき) です。ダムプロトコルをサポートしない場合、クライアントは続行すべきではありません (MUST NOT)。

クライアントは、ステータスコードが 200 OK または 304 Not Modified のいずれかであることを検証 MUST (しなければならない) です。

クライアントは、応答エンティティの最初の5バイトが正規表現 ^[0-9a-f]{4}# と一致することを検証 MUST (しなければならない) です。このテストに失敗した場合、クライアントは続行すべきではありません (MUST NOT)。

クライアントは、応答全体をpkt-lineレコードのシーケンスとして解析 MUST (しなければならない) です。

クライアントは、最初のpkt-lineが # service=$servicename であることを検証 MUST (しなければならない) です。サーバーは $servicename をリクエストパラメータの値に設定 MUST (しなければならない) です。サーバーはこの行の終わりにLFを含める SHOULD (べき) です。クライアントはこの行の終わりのLFを無視 MUST (しなければならない) です。

サーバーは、マジックな 0000 終端pkt-lineマーカーで応答を終了 MUST (しなければならない) です。

返される応答は、各参照とその既知の値を記述するpkt-lineストリームです。ストリームはCロケールの順序に従って名前でソートされる SHOULD (べき) です。ストリームは、デフォルトの参照である HEAD を最初の参照として含める SHOULD (べき) です。ストリームは、最初の参照のNULの後に機能宣言を含める MUST (しなければならない) です。

返された応答には、「version=1」が追加パラメータとして送信された場合、「バージョン1」が含まれます。

smart_reply     =  PKT-LINE("# service=$servicename" LF)
     "0000"
     *1("version 1")
     ref_list
     "0000"
ref_list        =  empty_list / non_empty_list
empty_list      =  PKT-LINE(zero-id SP "capabilities^{}" NUL cap-list LF)
non_empty_list  =  PKT-LINE(obj-id SP name NUL cap_list LF)
     *ref_record
cap-list        =  capability *(SP capability)
capability      =  1*(LC_ALPHA / DIGIT / "-" / "_")
LC_ALPHA        =  %x61-7A
ref_record      =  any_ref / peeled_ref
any_ref         =  PKT-LINE(obj-id SP name LF)
peeled_ref      =  PKT-LINE(obj-id SP name LF)
     PKT-LINE(obj-id SP name "^{}" LF

スマートサービス git-upload-pack

このサービスは $GIT_URL が指すリポジトリから読み込みます。

クライアントはまず、$GIT_URL/info/refs?service=git-upload-pack を使用して参照発見を実行 MUST (しなければならない) です。

C: POST $GIT_URL/git-upload-pack HTTP/1.0
C: Content-Type: application/x-git-upload-pack-request
C:
C: 0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n
C: 0032have 441b40d833fdfa93eb2908e52742248faf0ee993\n
C: 0000
S: 200 OK
S: Content-Type: application/x-git-upload-pack-result
S: Cache-Control: no-cache
S:
S: ....ACK %s, continue
S: ....NAK

クライアントはキャッシュされた応答を再利用または再検証すべきではありません (MUST NOT)。サーバーは、応答のキャッシュを防止するために十分なCache-Controlヘッダーを含める MUST (しなければならない) です。

サーバーはここで定義されているすべての機能をサポートすべきです (SHOULD)。

クライアントはリクエストボディに少なくとも1つの「want」コマンドを送信 MUST (しなければならない) です。サーバーが機能 allow-tip-sha1-in-want または allow-reachable-sha1-in-want を広告しない限り、クライアントは参照発見によって取得された応答に現れなかったIDを「want」コマンドで参照すべきではありません (MUST NOT)。

compute_request   =  want_list
       have_list
       request_end
request_end       =  "0000" / "done"
want_list         =  PKT-LINE(want SP cap_list LF)
       *(want_pkt)
want_pkt          =  PKT-LINE(want LF)
want              =  "want" SP id
cap_list          =  capability *(SP capability)
have_list         =  *PKT-LINE("have" SP id LF)

TODO: これをさらに文書化する。

ネゴシエーションアルゴリズム

最小限のパックを選択する計算は次のように進行します (C = クライアント、S = サーバー)

初期ステップ

C: 参照発見を使用して広告された参照を取得します。

C: 見たオブジェクトをすべて advertised セットに入れます。

C: 後で両端に存在すると判断されるオブジェクトを保持するために、空のセット common を構築します。

C: 参照発見中に見たものに基づいて、クライアントがフェッチしたい advertised からのオブジェクトのセット want を構築します。

C: コミット時間順に並べられたキュー c_pending を開始します (最新のものを最初にポップ)。すべてのクライアント参照を追加します。コミットがキューからポップされると、その親は自動的に挿入し直される SHOULD (べき) です。コミットはキューに一度だけ入る MUST (しなければならない) です。

1回の計算ステップ

C: 1つの $GIT_URL/git-upload-pack リクエストを送信します

C: 0032want <want-#1>...............................
C: 0032want <want-#2>...............................
....
C: 0032have <common-#1>.............................
C: 0032have <common-#2>.............................
....
C: 0032have <have-#1>...............................
C: 0032have <have-#2>...............................
....
C: 0000

ストリームは「コマンド」に整理され、各コマンドはpkt-lineにそれ自体で現れます。コマンド行内では、最初のスペースまでのテキストがコマンド名であり、行の残りの部分から最初のLFまでが値です。コマンド行は、pkt-lineの値の最後のバイトとしてLFで終了します。

リクエストストリームにコマンドが現れる場合、以下の順序で現れる MUST (しなければならない) です。

  • 「want」

  • 「have」

ストリームはpkt-lineフラッシュ (0000) で終了します。

単一の「want」または「have」コマンドは、その値として16進数形式のオブジェクト名を1つ持つ MUST (しなければならない) です。複数のオブジェクト名は、複数のコマンドを送信することによって送信 MUST (しなければならない) です。オブジェクト名は、object-format 機能(デフォルトはSHA-1)を通じてネゴシエートされたオブジェクト形式を使用して指定 MUST (しなければならない) です。

have リストは、c_pending から最初の32コミットをポップすることによって作成されます。c_pending が空になる場合は、それよりも少なく提供されてもよい (MAY)。

クライアントが256個の「have」コミットを送信し、まだ s_common からそれらのうちの1つを受け取っていない場合、またはクライアントが c_pending を空にした場合、サーバーにこれ以上続行しないことを知らせるために「done」コマンドを含める SHOULD (べき) です。

C: 0009done

S: git-upload-pack リクエストを解析します

want 内のすべてのオブジェクトが参照から直接到達可能であることを確認します。

サーバーは、わずかに古いリクエストを許可するために、履歴またはリフロッグを逆方向にたどってもよい (MAY)。

「want」オブジェクトが受信されなかった場合、エラーを送信します: TODO: 「want」行が要求されなかった場合のエラーを定義する。

いずれかの「want」オブジェクトが到達不可能である場合、エラーを送信します: TODO: 無効な「want」が要求された場合のエラーを定義する。

空のリスト s_common を作成します。

「have」が送信された場合

クライアントから提供された順序でオブジェクトをループします。

各オブジェクトについて、サーバーが参照からオブジェクトに到達できる場合、それを s_common に追加します。コミットが s_common に追加された場合、たとえ have にも現れていても、祖先を追加すべきではありません。

S: git-upload-pack 応答を送信します

サーバーがパックするオブジェクトの閉じたセットを見つけた場合、またはリクエストが「done」で終わる場合、パックで応答します。TODO: パックベースの応答を文書化する。

S: PACK...

返されるストリームはgit-upload-packサービスでサポートされているサイドバンド64kプロトコルであり、パックはストリーム1に埋め込まれています。サーバー側からの進捗メッセージはストリーム2に現れてもよい (MAY)。

ここで「オブジェクトの閉じたセット」とは、すべての「want」から少なくとも1つの「common」オブジェクトへのパスが少なくとも1つあると定義されます。

サーバーがより多くの情報を必要とする場合、ステータス継続応答で応答します: TODO: 非パック応答を文書化する。

C: upload-pack 応答を解析します: TODO: 応答の解析を文書化する。

別の計算ステップを実行します。

スマートサービス git-receive-pack

このサービスは $GIT_URL が指すリポジトリから読み込みます。

クライアントはまず、$GIT_URL/info/refs?service=git-receive-pack を使用して参照発見を実行 MUST (しなければならない) です。

C: POST $GIT_URL/git-receive-pack HTTP/1.0
C: Content-Type: application/x-git-receive-pack-request
C:
C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\0 report-status
C: 0000
C: PACK....
S: 200 OK
S: Content-Type: application/x-git-receive-pack-result
S: Cache-Control: no-cache
S:
S: ....

クライアントはキャッシュされた応答を再利用または再検証すべきではありません (MUST NOT)。サーバーは、応答のキャッシュを防止するために十分なCache-Controlヘッダーを含める MUST (しなければならない) です。

サーバーはここで定義されているすべての機能をサポートすべきです (SHOULD)。

クライアントはリクエストボディに少なくとも1つのコマンドを送信 MUST (しなければならない) です。リクエストボディのコマンド部分では、クライアントは参照発見を通じて取得したIDをold_idとして送信 SHOULD (べき) です。

update_request  =  command_list
     "PACK" <binary-data>
command_list    =  PKT-LINE(command NUL cap_list LF)
     *(command_pkt)
command_pkt     =  PKT-LINE(command LF)
cap_list        =  *(SP capability) SP
command         =  create / delete / update
create          =  zero-id SP new_id SP name
delete          =  old_id SP zero-id SP name
update          =  old_id SP new_id SP name

TODO: これをさらに文書化する。

GIT

git[1] スイートの一部

scroll-to-top