Pitmaster
Git in PHP: read and write repositories, diff, merge and speak smart HTTP without shelling out to git.
composer require pitmaster/pitmasterLatest release v0.2.11 MIT PHP 8.2+
# List all branches (current marked with *)
./bin/pitmaster branch
# Create a new branch from HEAD
./bin/pitmaster branch feature/new-thing
# Delete a branch
./bin/pitmaster branch -d feature/old
./bin/pitmaster branch -D feature/oldIn practice
Open a repository, then read and write it with method calls or from the shell.
Read a repository from PHP
Pitmaster::open() locates the .git directory and returns a repository handle. Each status entry carries a separate state for the index and the working tree.
From the shell, ./vendor/bin/pitmaster mirrors a subset of git commands and works from a Composer install since 0.2.11.
use Pitmaster\Pitmaster;
$repo = Pitmaster::open('/path/to/project');
// Read the current HEAD commit
$head = $repo->head();
echo $head->message;
// List branches
foreach ($repo->branches() as $branch) {
echo $branch . "\n";
}
// Check status
foreach ($repo->status() as $entry) {
echo "{$entry->path}: {$entry->index->value}{$entry->worktree->value}\n";
}./vendor/bin/pitmaster log
./vendor/bin/pitmaster status
./vendor/bin/pitmaster diff
./vendor/bin/pitmaster show HEAD
./vendor/bin/pitmaster add file.txt
./vendor/bin/pitmaster commit -m "message"
./vendor/bin/pitmaster branch feature
./vendor/bin/pitmaster checkout feature
./vendor/bin/pitmaster merge featureNo git Binary
Core operations run in PHP 8.2+ with no git binary or FFI. Hooks and the SSH fallback start processes unless you pass ['hooks' => false] or processFreeOptions().
Read & Write
Loose objects, pack files with delta resolution, the index, refs, and config. git reads what Pitmaster writes for index versions 2 and 3 and loose refs.
Diff & Merge
Myers, patience and histogram diffs with rename detection. Three-way merge with conflict markers.
Network Protocol
Clone, fetch, and push over smart HTTP or SSH, with a dumb HTTP fallback for clone and fetch. Protocol v2 is available through the lower-level clients.
Git Operations
add, commit, status, diff, merge, checkout, reset, stash, cherry-pick, revert, rebase, blame, grep.
CLI
22 git-style commands, including init, log, status, diff, add, commit, branch, merge, stash, blame and grep. Clone, fetch and push are library-only.
Oracle-Tested
761 scenarios compare results with output captured from real git and run in CI; 605 come from the test suites of git itself, libgit2, go-git, isomorphic-git, dulwich and JGit.
Full Search
Blame, grep, bisect, notes and a log path filter, without shelling out to git.
Why Pitmaster
Works without a git install
Commits, diffs, status and history are computed in PHP, so containers and hosts without a git binary can still work with repositories.
Process-free handles
Pitmaster::processFreeOptions() turns off hooks, fsmonitor hooks, clone, fetch, push and SSH process transport. Local reads and writes keep working.
Checked against git
Integration tests run against the git binary, and the support matrix counts 146 of 146 in-scope features as oracle-verified within its declared parity scope.
SHA-1 and SHA-256
Create a SHA-256 repository with Pitmaster::init($path, 'sha256') or init --object-format=sha256. Pack files are read and written; commit-graph, multi-pack index and reftable files can be read.
Compared with
Other ways to work with Git repositories from PHP, and where Pitmaster differs.
| Tool | Good at | Difference with Pitmaster |
|---|---|---|
| git (command line) | Good atThe reference implementation, with a rich command set that covers both high-level operations and full access to internals. | Difference with PitmasterPitmaster runs inside the PHP process and core operations do not shell out to git. Its CLI mirrors only a subset of git commands. |
| czproject/git-php | Good atA compact PHP API for init, clone, commit, merge, branches, tags and remotes. It runs on PHP 8.0 or later and drives the installed git client. | Difference with PitmasterPitmaster needs no git client for core operations because it reads and writes objects, pack files and the index itself. It requires PHP 8.2 or later. |
| gitonomy/gitlib | Good atRepository access from PHP 8.4 or later with nothing to build. It works by making shell calls to git. | Difference with PitmasterPitmaster makes no shell calls for core operations, and a process-free handle disables the parts that would start a process. |
| libgit2 | Good atA portable C implementation of the Git core methods as a linkable library, with bindings for Ruby, .NET, Python, Node.js, Rust and more. | Difference with PitmasterPitmaster is plain PHP installed with Composer, with no compiled library or FFI. It imports 63 of its oracle scenarios from libgit2's test resources. |
Sources, checked
Questions and answers
Short answers from the Pitmaster documentation.
No. Core repository operations do not use the git binary or FFI. Objects, refs, pack files, the index and smart HTTP are handled in PHP.
Yes. Pass Pitmaster::processFreeOptions() or ['processes' => false] when opening the repository. Hooks, clone, fetch, push and SSH process transport are then disabled, while local reads and writes stay available.
Yes, hooks stay enabled by default and run through proc_open(). Pass ['hooks' => false] to Pitmaster::open(), Pitmaster::init() or Pitmaster::clone() to skip the scripts in .git/hooks for that handle.
Pitmaster::clone(), fetch() and push() use SSH for SSH URLs and smart HTTP otherwise, and clone and fetch fall back to dumb HTTP when the smart exchange fails. SSH uses the ssh2 extension when it is loaded and the system ssh binary otherwise.
Yes. Pass 'sha256' as the second argument to Pitmaster::init(), or run init with --object-format=sha256. Objects then use 64-character hashes.
No. It mirrors a subset of git commands, such as log, status, diff, commit, merge, blame and grep. Clone, fetch and push are available only through the PHP API.
Start with the getting started guide to open your first repository from PHP, then use the API and CLI references for the rest.