コンテンツへスキップ

はじめに

インストール

ComposerでPitmasterをインストールします:

シェル
composer require pitmaster/pitmaster

必要条件

  • PHP 8.2+(読み取り専用クラス、enum、コンストラクタープロモーションを使用)
  • オブジェクトの圧縮/展開用のext-zlib(ほとんどの環境で標準搭載)
  • 操作状態ファイルとGit LFSのAPIペイロード用のext-json
  • ext-mbstring(composer.jsonで宣言されているため、Composerのインストール時に必要)
  • ハッシュ検証用のext-ctype(ほとんどのPHPビルドで有効ですが、composer.jsonでは宣言されていません)

コアとなるリポジトリ操作にgitバイナリ、FFI、外部ヘルパーは必要ありません。オプション機能には追加の実行時要件があります。フックの実行にはproc_open()を使用し、SSHトランスポートはext-ssh2が読み込まれている場合はそれを使い、そうでない場合はproc_open()を通じてシステムのsshバイナリを起動します。

既存のリポジトリを開く

PHP
use Pitmaster\Pitmaster;

$repo = Pitmaster::open('/path/to/project');

指定したパスにあるリポジトリを開きます。Pitmasterは.gitディレクトリを特定し(リンクされたワークツリーの場合は.gitファイルを解決)、オブジェクトデータベース、参照データベース、設定を初期化します。

open()、init()、clone()は、最後の引数としてオプション配列を受け取ります:

PHP
// Do not run .git/hooks scripts for this handle
$repo = Pitmaster::open('/path/to/project', ['hooks' => false]);

// Do not start any process: no hooks, no fsmonitor hook, no clone/fetch/push, no SSH
$repo = Pitmaster::open('/path/to/project', Pitmaster::processFreeOptions());

フックは既定で実行されます。Pitmaster::processFreeOptions()は['processes' => false, 'hooks' => false]を返します。このハンドルを使ったローカルの読み書きは引き続き可能です。

パスがリポジトリかどうかを確認する

PHP
if (Pitmaster::isRepository('/path/to/project')) {
    $repo = Pitmaster::open('/path/to/project');
}

新しいリポジトリを初期化する

PHP
$repo = Pitmaster::init('/path/to/new-project');

オブジェクト、参照、HEAD(refs/heads/mainを指す)、既定の設定を含む.gitディレクトリ構造を作成します。

SHA-256リポジトリを作成するには、2番目の引数としてオブジェクト形式を渡します:

PHP
$repo = Pitmaster::init('/path/to/new-project', 'sha256');

このリポジトリのオブジェクトIDは64文字の16進数で、設定にはextensions.objectformat = sha256が記録されます。後でリポジトリを開くと、この設定項目から形式が取得されます。

HEADのコミットを読む

PHP
$head = $repo->head();

echo "Commit: {$head->id->hex}\n";
echo "Author: {$head->author}\n";
echo "Message: {$head->message}\n";

head()メソッドはHEADを解決し(シンボリック参照をたどり)、Commitオブジェクトを返します。

ブランチとタグを一覧表示する

PHP
// All branch names
$branches = $repo->branches();
// ['main', 'feature/login', 'bugfix/typo']

// Current branch name (null if detached)
$current = $repo->branch();
// 'main'

// All tag names
$tags = $repo->tags();
// ['v1.0.0', 'v1.1.0']

コミット履歴をたどる

PHP
// Last 20 commits from HEAD
$commits = $repo->log(20);

foreach ($commits as $commit) {
    echo substr($commit->id->hex, 0, 7) . " {$commit->message}\n";
}

特定のコミットから開始することもできます:

PHP
$from = $repo->resolve('feature/login');
$commits = $repo->log(10, $from);

作業ツリーの状態を確認する

PHP
use Pitmaster\Status\FileStatus;

$entries = $repo->status();

foreach ($entries as $entry) {
    if ($entry->index === FileStatus::Untracked) {
        echo "?? {$entry->path}\n";
    } elseif ($entry->index === FileStatus::Modified) {
        echo "M  {$entry->path}\n";
    } elseif ($entry->worktree === FileStatus::Modified) {
        echo " M {$entry->path}\n";
    }
}

ファイルをステージしてコミットする

PHP
// Stage specific files
$repo->add('src/Feature.php', 'tests/FeatureTest.php');

// Create a commit
$commitId = $repo->commit('Add new feature with tests');

echo "Created commit: {$commitId->hex}\n";

作成者名とメールアドレスは次の順で解決されます:PITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL環境変数、GIT_AUTHOR_NAME/GIT_AUTHOR_EMAIL環境変数、PITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL定数、リポジトリ独自の.git/config(user.nameとuser.email)、最後にPitmaster <pitmaster@localhost>です。リポジトリの設定ファイルとそこから読み込まれるファイルだけが対象で、~/.gitconfigは読み込まれません。コミッターも同じ方法で*_COMMITTER_*の名前から解決され、作成者定数にフォールバックします。

差分を計算する

PHP
// Unstaged changes (worktree vs index)
$diffs = $repo->diff();

foreach ($diffs as $diff) {
    echo $diff->format(); // Unified diff output
}

// Staged changes (index vs HEAD)
$staged = $repo->diffStaged();

リモートリポジトリをクローンする

PHP
$repo = Pitmaster::clone('https://github.com/user/repo.git', '/path/to/destination');

参照を検出し、パックファイルを取得して、リモート追跡ブランチを設定し、既定のブランチをチェックアウトします。HTTP(S)のURLではsmart HTTPを使い、失敗した場合はdumb HTTPにフォールバックします。SSHのURLではSSHトランスポートを使います。浅いクローンを作成するには、3番目の引数として深さを渡します:Pitmaster::clone($url, $path, 1)。

ハッシュから任意のオブジェクトを読む

PHP
$object = $repo->readObject($fullHash); // full 40-character (or 64 for SHA-256) hex hash

if ($object instanceof \Pitmaster\Object\Blob) {
    echo $object->content;
} elseif ($object instanceof \Pitmaster\Object\Commit) {
    echo $object->message;
}

設定

Pitmasterは、作成者情報とリモートURLにリポジトリの.git/configを使用します。Pitmasterの実行前に定義したPHP定数で、グローバルな既定値を設定することもできます:

PHP
define('PITMASTER_AUTHOR_NAME', 'Your Name');
define('PITMASTER_AUTHOR_EMAIL', 'you@example.com');
define('PITMASTER_HTTP_TIMEOUT', 60);        // Seconds
define('PITMASTER_MAX_DELTA_CHAIN', 50);     // Max delta chain depth
define('PITMASTER_OBJECT_CACHE_BYTES', '64M');
定数 既定値 効果
PITMASTER_AUTHOR_NAME、PITMASTER_AUTHOR_EMAIL なし 作成者の識別情報(上記の順序を参照)
PITMASTER_COMMITTER_NAME、PITMASTER_COMMITTER_EMAIL 作成者の値 コミッターの識別情報
PITMASTER_HTTP_TIMEOUT 30 Smart HTTPのタイムアウト(秒、整数)
PITMASTER_MAX_DELTA_CHAIN 50 パック読み込み時のデルタチェーンの最大深度(整数)
PITMASTER_OBJECT_CACHE_ENTRIES 1024 メモリ内オブジェクトキャッシュに保持するオブジェクト数
PITMASTER_OBJECT_CACHE_BYTES 16M オブジェクトキャッシュのバイト数上限
PITMASTER_PACK_RESOLVED_CACHE_ENTRIES 4096 パックごとにキャッシュする解決済みデルタオブジェクト数
PITMASTER_PACK_RESOLVED_CACHE_BYTES 32M パックキャッシュのバイト数上限
PITMASTER_MAX_PACK_MEMORY なし パックキャッシュのバイト数上限を表す旧名称。PITMASTER_PACK_RESOLVED_CACHE_BYTESが未定義の場合のみ使用

バイト数は、整数またはk、m、gのいずれかのサフィックス付き文字列('256M')で指定できます。無効な値の場合は既定値が使用されます。

環境変数は、ID定数であるPITMASTER_AUTHOR_NAME、PITMASTER_AUTHOR_EMAIL、PITMASTER_AUTHOR_DATEと、それぞれに対応するPITMASTER_COMMITTER_*の値、さらにgit固有のGIT_AUTHOR_*およびGIT_COMMITTER_*変数を上書きします。SSHトランスポートはPITMASTER_SSH_*変数を読み込みます。詳細はプロトコルを参照してください。

ハッシュアルゴリズムを指定する定数はありません。オブジェクト形式はリポジトリの作成時に選択され(CLIでPitmaster::init($path, 'sha256')またはinit --object-format=sha256を指定)、その後はリポジトリの設定から読み込まれます。