コンテンツへスキップ

プロトコル

Pitmasterはgitサーバーとの通信に複数のネットワークトランスポートプロトコルをサポートします。スマートHTTPが主要なトランスポートです。互換性を広げるため、ほかのプロトコルも利用できます。

スマートHTTP(主要)

推奨トランスポートです。HTTPS経由で動作し、最も広く導入されているプロトコルです。カスタムヘッダーや認証情報用のAPIはありません。認証情報はURL(https://user:token@host/repo.git)でのみ渡すことができ、PHPはそれをBasic認証として送信します。clone()は認証情報を含むURLを.git/config内のremote.origin.urlとして保存します。リクエストではPHPのストリームラッパーを使用するため、allow_url_fopenを有効にする必要があります。

PHP
use Pitmaster\Protocol\SmartHttpClient;

$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');

詳しくはスマートHTTPを参照してください。

プロトコルv1

従来のスマートHTTPプロトコルです。検出時にすべてのrefが送信され、ネゴシエーションではwant/have/done行を使用します。

PHP
use Pitmaster\Protocol\ProtocolV1;

プロトコルv2

構造化コマンド(ls-refs、fetch)を備えた新しいプロトコルです。クライアントがref一覧を絞り込めるため、refの多いリポジトリでより効率的です。

clone()とfetch()は常にプロトコルv1を使用します。プロトコルv2は、SmartHttpClient::discoverRefsV2()とUploadPackClient::fetchV2()経由のスマートHTTPで明示的に利用できます。

ダムHTTP

スマートHTTPプロトコルに対応していないサーバー向けのフォールバックです。ダムプロトコルでは、通常のHTTP GETリクエストを使ってオブジェクトやpackを個別に取得します。

PHP
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();

ダムHTTPの制限:

  • ネゴシエーションなし(クライアントはすべてをダウンロードする必要があります)
  • 転送中のデルタ圧縮なし
  • スマートHTTPより大幅に低速
  • 一部のサーバー(GitHub、GitLab)は非対応

ダムプロトコルでは次を取得します。

  1. GET /info/refs(プレーンテキスト、pkt-lineなし)
  2. GET /HEAD(デフォルトブランチ)
  3. GET /objects/info/packs(利用可能なpackの一覧)
  4. GET /objects/pack/pack-<hash>.packと.idx(一覧にある各packとそのインデックス)
  5. GET /objects/<xx>/<rest>(refの先端からたどった個々のルースオブジェクト)

手順5は、サーバーがpackを1つも提示しない場合にのみ実行されます。packが提示される場合、サーバー上にルースファイルとしてのみ存在するオブジェクトはダウンロードされません(#18)。ダムクライアントが受け付けるオブジェクトIDは40文字(SHA-1)のみです。スマートHTTPの通信に失敗すると、clone()とfetch()はダムHTTPにフォールバックします。

SSH

SSHトランスポートでは、PHP拡張機能が読み込まれている場合はssh2を使用します。そうでない場合は、proc_open()を介してシステムのsshクライアントを起動します。どちらの場合も、リモートでgit-upload-packまたはgit-receive-packを実行します。

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

SSH URL:

コード
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git

拡張機能は不要です。2つの方法では動作が異なります。

システムのsshクライアント(ssh2が読み込まれていない場合に使用)。Pitmasterはssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>を実行するため、認証とホストキーの確認はSSH設定およびエージェントに従います。次の環境変数でコマンドを調整できます。

変数 効果
PITMASTER_SSH_COMMAND sshの代わりに実行する実行ファイル
PITMASTER_SSH_IDENTITY_FILE -i <file>として渡される
PITMASTER_SSH_KNOWN_HOSTS -o UserKnownHostsFile=<file>として渡される
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING -o StrictHostKeyChecking=<value>として渡される

この方法ではプロセスを起動するため、['processes' => false]で開いたハンドルでは利用できません。

ssh2拡張機能(読み込まれている場合は常に優先)。Pitmasterは~/.ssh/id_rsaで認証し、RSAキーが存在するものの拒否された場合は~/.ssh/id_ed25519で認証します。それ以外の場合はSSHエージェントを使用します。PITMASTER_SSH_*環境変数は無視され、この方法ではサーバーのホストキーを検証しません(#22)。

SSHトランスポートはリモートコマンドとしてgit-upload-packまたはgit-receive-packを実行し、スマートHTTPと同じpkt-lineプロトコルを使ってSSHチャネル上で通信します。

Gitプロトコル(TCP)

ネイティブのgitプロトコルは、PHPソケットを使用してTCPポート9418で通信します。GitProtocolClientはrefの検出とupload-pack(フェッチ)を実装していますが、プッシュはできません。clone()とfetch()はgit:// URLをこのプロトコルに振り分けないため、クライアントを直接使用してください。

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

Git URL:

コード
git://github.com/user/repo.git

特徴:

  • 認証なし(実質読み取り専用)
  • 暗号化なし
  • ほとんどのホスティングプロバイダーで非推奨
  • スマートHTTPと同じpkt-line形式を使用

gitプロトコルでは、最初のリクエストとしてサービス名とリポジトリパスを送信し、その後、標準のpkt-line形式によるrefの検出とpackのネゴシエーションを行います。

バンドル

Gitバンドルは、ref情報を含むオフライン用のpackファイルです。ネットワーク接続なしでリポジトリデータを転送できます。

PHP
use Pitmaster\Protocol\Bundle;

// Read a bundle file
$bundle = Bundle::open('/path/to/repo.bundle');
$refs = $bundle->refs();
$packData = $bundle->packData();
$prerequisites = $bundle->prerequisites();

// Create one
$bundle = Bundle::create(['refs/heads/main' => $commitId], $packData);
$bundle->writeTo('/path/to/out.bundle');

Pitmasterはv2とv3のバンドルヘッダーを読み込みます。バンドルをインポートするRepositoryメソッドはありません。packData()を.git/objects/pack/に書き込み、PackIndexer::writeIndex()でインデックスを作成してから、自分でrefを更新してください。

バンドル形式:

コード
# v2 git bundle\n
-<prerequisite hash>\n    (zero or more)
<hash> <refname>\n        (one or more)
\n
<pack data>               (standard pack file format)

バンドルは次の用途に便利です。

  • USBドライブによる物理的な転送
  • 増分バックアップ
  • エアギャップ環境でのクローンの初期データ提供

シャロークローン

Pitmasterは、取得するコミット履歴の深さを制限するシャロークローンをサポートします。

PHP
use Pitmaster\Protocol\ShallowClone;

Pitmaster::clone($url, $path, $depth)または$repo->fetch($remote, $depth)に深さを渡します。リクエストにはshallow機能とdeepen行が追加されます。

コード
want <hash>
deepen <depth>

サーバーは、履歴がどこで切り詰められたかを示すshallow <hash>行を返します。Pitmasterは深さ自体からシャロー境界を計算し、その計算で見つからない場合はサーバーのshallow行を使用します。結果は.git/shallowに保存されます。ShallowClone::readShallow()、writeShallow()、isShallow()はこのファイルを直接使用します。

プロトコルの比較

プロトコル 認証 暗号化 プッシュ 主な用途
スマートHTTP URL内の認証情報 HTTPS 可 主要トランスポート
ダムHTTP URL内の認証情報 HTTPS 不可 従来方式のフォールバック
SSH SSHキーまたはエージェント SSH 可 プライベートリポジトリ、CI
Git(TCP) なし なし 不可 読み取り専用ミラー
バンドル 該当なし 該当なし 該当なし オフライン転送

トランスポートの選択

Pitmaster::clone()、$repo->fetch()、$repo->push()はURLからトランスポートを選択します。

URLパターン トランスポート
ssh://... SSH
user@host:path SSH
その他(https://...、http://...) スマートHTTP。cloneとfetchはダムHTTPにフォールバック

git:// URLとローカルパスはこれらのメソッドではサポートされていません。スマートHTTPクライアントに渡され、失敗します。git://にはGitProtocolClientを直接使用してください。ユーザーとポートの両方を含むHTTPSURL(https://user@host:8443/repo.git)は、現在SSHURLと誤認されます(#17)。