セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
- 2.44.1 → 2.50.1 変更なし
-
2.44.0
2024-02-23
- 2.43.2 → 2.43.7 変更なし
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.38.1 → 2.42.4 変更なし
-
2.38.0
2022-10-02
説明
Git は、2つの HTTP ベース転送プロトコルをサポートしています。接続のサーバー側で標準の HTTP サーバーのみを必要とする「ダム」プロトコルと、Git 対応の CGI (またはサーバーモジュール) を必要とする「スマート」プロトコルです。このドキュメントでは、両方のプロトコルについて説明します。
設計機能として、スマートクライアントは「ダム」プロトコル 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/refs
を foo/info/refs
として展開 MUST (しなければならない) です。foo//info/refs
として展開してはなりません。
認証
リポジトリへのアクセスに認証が必要な場合は、標準の HTTP 認証が使用され、HTTP サーバーソフトウェアによって構成および強制 MAY (してもよい) です。
Git リポジトリは標準のパスコンポーネントによってアクセスされるため、サーバー管理者は HTTP サーバー内でディレクトリベースの権限を使用してリポジトリアクセスを制御 MAY (してもよい) です。
クライアントは、RFC 2617 に記載されている基本認証をサポート SHOULD (すべき) です。サーバーは、Git サーバーソフトウェアの前に配置された HTTP サーバーに依存することで、基本認証をサポート SHOULD (すべき) です。
サーバーは、認証またはアクセス制御の目的で HTTP クッキーを要求 SHOULD NOT (すべきではない) です。
クライアントとサーバーは、ダイジェスト認証などの他の一般的な HTTP ベース認証形式をサポート MAY (してもよい) です。
セッション状態
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
Found
、410
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
Modified
を 200
OK
と同様に扱わなければなりません MUST (しなければならない) 。
Cache-Control および/または Expires ヘッダーがキャッシュを許可する場合、クライアントは再検証なしでキャッシュされたエンティティを再利用 MAY (してもよい) です。クライアントとサーバーは、キャッシュ制御に関して RFC 2616 に従わなければなりません MUST (しなければならない) 。
参照の検出
すべての HTTP クライアントは、リモートリポジトリで利用可能な参照を検出することによって、フェッチまたはプッシュの交換を開始 MUST (しなければならない) です。
ダムクライアント
「ダム」プロトコルのみをサポートする HTTP クライアントは、リポジトリの特別な info/refs ファイルへのリクエストを行うことによって参照を検出 MUST (しなければならない) です。
ダム HTTP クライアントは、検索/クエリパラメータなしで $GIT_URL/info/refs
への GET
リクエストを生成 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 (しなければならない) です。
リクエストには、厳密に1つのクエリパラメータ service=$servicename
が含まれ 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
オプションを使用します。
スマートサーバーの応答
サーバーが要求されたサービス名を認識しない場合、または要求されたサービス名がサーバー管理者によって無効にされている場合、サーバーは 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
機能をアドバタイズしない限り、クライアントは参照検出を通じて取得した応答に表示されなかった「want」コマンド内の ID を参照 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
が空になった場合は、より少ない数を指定できます。
クライアントが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 サービスによってサポートされる side-band-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]スイートの一部