PHPackages                             pitmaster/pitmaster - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. pitmaster/pitmaster

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

pitmaster/pitmaster
===================

Pure PHP Git implementation. Reads and writes Git repositories without shelling out to git.

v0.2.7(3w ago)0612↓50%1MITShellPHP ^8.2CI failing

Since Apr 7Pushed 2w agoCompare

[ Source](https://github.com/inline0/pitmaster)[ Packagist](https://packagist.org/packages/pitmaster/pitmaster)[ Docs](https://github.com/inline0/pitmaster)[ RSS](/packages/pitmaster-pitmaster/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (9)Dependencies (3)Versions (10)Used By (1)

    ![Pitmaster](./docs/public/logo-light.svg)

 Pure PHP Git implementation

 [![CI](https://github.com/inline0/pitmaster/actions/workflows/ci.yml/badge.svg)](https://github.com/inline0/pitmaster/actions/workflows/ci.yml) [![Packagist](https://camo.githubusercontent.com/19239bc9d03919f8b505d31759d913aae6395bc1693d931772157bd8e47c2ca5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7069746d61737465722f7069746d61737465722e737667)](https://packagist.org/packages/pitmaster/pitmaster) [![license](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](https://github.com/inline0/pitmaster/blob/main/LICENSE)

---

What is Pitmaster?
------------------

[](#what-is-pitmaster)

Pitmaster reads and writes Git repositories in pure PHP. Core repository operations do not shell out to the `git` binary or rely on FFI. Objects, refs, pack files, the index, and smart HTTP transport are handled natively in PHP.

**The problem:** PHP applications that need to interact with Git repositories either shell out to the `git` binary (requires `exec()`, hard to deploy, security surface) or use FFI/extension bindings (complex setup, version coupling). There's no way to read a pack file, create a commit, or diff two trees from pure PHP.

**Pitmaster solves this** by implementing the Git object model, binary formats, and protocols natively:

- Read and write loose objects (blob, tree, commit, tag)
- Read and write pack files with full delta chain resolution
- Read and write the index (staging area)
- Compute diffs (Myers O(ND) algorithm, byte-exact with `git diff`)
- Three-way merge with conflict markers
- Walk commit graphs, compute merge bases
- Speak the Git smart HTTP protocol (clone, fetch, push)

Quick Start
-----------

[](#quick-start)

```
composer require pitmaster/pitmaster
```

```
use Pitmaster\Pitmaster;

// Open an existing repository
$repo = Pitmaster::open('/path/to/project');

// Disable Git hook execution for this repository handle
$repo = Pitmaster::open('/path/to/project', ['hooks' => false]);

// Disable host-process and network write paths for restricted runtimes
$repo = Pitmaster::open('/path/to/project', Pitmaster::processFreeOptions());

// Read
$head = $repo->head();                    // Current HEAD commit
$log  = $repo->log(10);                   // Last 10 commits
$refs = $repo->allRefs();                 // All branches and tags
$obj  = $repo->readObject($hash);         // Any object by hash

// Write
$repo->add('src/main.php');               // Stage a file
$repo->commit("Fix the bug\n");           // Create a commit
$repo->createBranch('feature');           // Create a branch
$repo->merge('feature');                  // Merge a branch

// Diff
$diffs = $repo->diff();                   // Unstaged changes
$diffs = $repo->diffStaged();             // Staged changes
$diffs = $repo->diffTree($treeA, $treeB); // Tree-to-tree

// Status
$status = $repo->status();                // WorkingTreeStatus
foreach ($status as $entry) {
    echo $entry->shortFormat() . "\n";    // "M  src/main.php"
}

// Network
$repo->fetch('origin');                   // Fetch from remote
$repo->push('origin', 'main');            // Push to remote

// Init and clone
$repo = Pitmaster::init('/path/to/new');
$repo = Pitmaster::clone('https://github.com/user/repo.git', '/path');
```

Hooks stay enabled by default. Pass `['hooks' => false]` to `Pitmaster::open()`, `Pitmaster::init()`, or `Pitmaster::clone()` when the caller must avoid executing `.git/hooks/*` scripts for that repository handle.

For hosted runtimes that must not execute host processes, pass `['processes' => false]` or `Pitmaster::processFreeOptions()`. Process-free handles disable hook execution, fsmonitor hook execution, clone/fetch/push network operations, and SSH process transport paths while keeping local repository reads and writes in PHP.

CLI
---

[](#cli)

Pitmaster ships with a CLI that mirrors a subset of `git` commands:

```
./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 feature
./vendor/bin/pitmaster stash push
./vendor/bin/pitmaster blame file.txt
./vendor/bin/pitmaster grep "pattern"
./vendor/bin/pitmaster tag v1.0 -m "Release"
./vendor/bin/pitmaster reset --hard HEAD~1
./vendor/bin/pitmaster refs
./vendor/bin/pitmaster init
```

Testing
-------

[](#testing)

Pitmaster is exercised with unit tests, integration tests against the canonical `git` binary, and imported oracle-style scenarios from upstream Git implementations.

```
# Unit tests (no git binary needed)
composer test:unit

# Integration tests (verified against git)
composer test:integration

# Oracle regression corpus (vendored upstream fixtures)
composer test:oracle

# Full test matrix: phpunit + upstream oracle regression
composer test

# Full verification: analysis + standards + full test matrix
./bin/verify-all

# Evidence / proof / drift checks
composer verify:evidence
composer verify:drift
composer verify:proof
composer test:mutation
composer audit:composer

# Benchmark smoke
composer bench -- --suite=smoke --runs=1 --warmups=0

# Full benchmark baseline
composer bench:baseline

# Compare two reports
composer bench:compare -- bench/reports/baseline.json bench/reports/candidate.local.json

# Print a sorted human summary
composer bench:summary -- bench/reports/baseline.json

# Verify the smoke report against committed thresholds
composer bench:verify -- bench/reports/ci-smoke.local.json bench/reports/smoke-thresholds.json

# Optional multi-git smoke matrix when multiple git binaries are installed
PITMASTER_TEST_GIT_BINARIES=/path/to/git-2.45:/path/to/git-2.46 \
  phpunit --filter MultiGitVersionSmokeTest

# Static analysis
composer analyse

# Coding standards
composer cs
```

The upstream oracle fixtures are vendored under [`fixtures/upstream`](fixtures/upstream), so the full regression corpus is runnable from a fresh checkout without machine-local `/tmp` dependencies. Use `composer test` for the full matrix and `./bin/verify-all` for release-grade verification. CI also validates upstream drift and publishes a machine-readable proof artifact from [`bin/build-proof-artifact`](bin/build-proof-artifact).

Feature work and fixture changes use the same bar: keep scenarios self-contained inside the repo, avoid absolute-path and machine-local-port snapshots, and do not treat a change as done until `./bin/verify-all` is green.

Performance
-----------

[](#performance)

Pitmaster now has a repo-local benchmark harness under [`bench/`](bench). Performance claims should be backed by measured before/after reports, not intuition.

```
# Run the fast benchmark subset
composer bench -- --suite=smoke --runs=1 --warmups=0

# Run one focused case when iterating on a hotspot
composer bench -- --suite=all --case=workflow.reset.hard.large --runs=5 --warmups=1

# Run the instrumentation-only suite to split a hotspot into sub-costs
composer bench -- --suite=instrumentation --runs=3 --warmups=0

# Capture the full baseline report
composer bench:baseline

# Compare two benchmark reports
composer bench:compare -- bench/reports/baseline.json bench/reports/post-opt.local.json

# Print a sorted summary for a single report
composer bench:summary -- bench/reports/baseline.json

# Verify a report against the committed smoke thresholds
composer bench:verify -- bench/reports/ci-smoke.local.json bench/reports/smoke-thresholds.json
```

Benchmark fixtures are deterministic and repo-local. They are generated under `bench/fixtures/repos` from committed definitions, not from `/tmp` or public network dependencies. The committed smoke thresholds live in [`bench/reports/smoke-thresholds.json`](bench/reports/smoke-thresholds.json), and CI verifies the smoke report against them. For optimization work, measure the focused case first, keep only wins that hold up across reruns, then refresh the canonical baseline. Do not treat a change as done until the relevant benchmark moves in the right direction and `./bin/verify-all` still passes.

The instrumentation suite is intentionally separate from the canonical baseline and smoke thresholds. Use it when a remaining hotspot needs attribution first, for example splitting smart HTTP fetch into discovery and upload-pack costs or separating SSH command startup from PHP-side parsing.

Requirements
------------

[](#requirements)

- PHP 8.2+
- `ext-zlib` (built-in)
- `ext-mbstring` (built-in)
- `ext-json` (built-in)

Core repository operations do not require the `git` binary or FFI. Optional features have extra runtime expectations: hook execution uses `proc_open()`, and SSH transport requires `ext-ssh2`.

Features
--------

[](#features)

See [SUPPORT\_MATRIX.md](SUPPORT_MATRIX.md) for the full feature list. The rendered matrix is generated from [`config/support-matrix.json`](config/support-matrix.json) and backed by [`config/support-evidence.json`](config/support-evidence.json), which CI validates so every `DONE` row resolves to concrete tests and oracle scenarios. Highlights:

CategoryFeaturesObjectsBlob, tree, commit, tag (SHA-1 + SHA-256)StorageLoose objects, pack files (v1/v2 index, OFS/REF delta), MIDX, commit-graphIndexv2/v3/v4 with extensions (TREE, REUC, FSMN)RefsLoose, packed, symbolic, reftable, reflogDiffMyers O(ND), patience, histogram, word diff, rename detectionMergeThree-way, recursive, ours, octopus, fast-forward, conflict markersNetworkSmart HTTP (v1/v2), SSH, git://, dumb HTTP, bundlesOperationsadd, commit, status, diff, merge, checkout, reset, stash, cherry-pick, revert, rebase, blame, grep, bisect, notesAdvancedSubmodules, worktrees, sparse checkout, hooks, LFS, rerere, fsmonitorArchitecture
------------

[](#architecture)

```
src/
├── Pitmaster.php              # Static facade (open, init, clone)
├── Repository.php             # All operations
├── Object/                    # Blob, Tree, Commit, Tag, ObjectId
├── Storage/                   # LooseObjectStore, PackFileStore, ObjectDatabase
├── Pack/                      # PackFile, PackIndex, DeltaApplier, PackWriter
├── Index/                     # Index reader/writer
├── Ref/                       # LooseRefStore, PackedRefStore, RefDatabase
├── Diff/                      # MyersDiff (O(ND)), TreeDiff, DiffResult
├── Merge/                     # ThreeWayMerge, MergeBase, ConflictMarker
├── Graph/                     # CommitWalker, Blame, Grep, Bisect, Rebase
├── Status/                    # WorkingTreeStatus, GitIgnore, Fsmonitor
├── Protocol/                  # SmartHttpClient, PktLine, UploadPackClient
├── Stash/                     # Stash (push/pop/apply/list/drop)
├── Config/                    # GitConfig, GitAttributes
├── Encoding/                  # BinaryReader, VarInt, Leb128
├── Hooks/                     # HookRunner
├── Lfs/                       # LfsClient, LfsPointer
├── Submodule/                 # SubmoduleManager
├── Worktree/                  # WorktreeManager
├── Checkout/                  # SparseCheckout
└── Exceptions/                # Typed exceptions

```

License
-------

[](#license)

MIT

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance96

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Total

9

Last Release

21d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/dc81a975082b6843421de211768cfb67d8237bed4c972c9a1eaad46aac14b372?d=identicon)[dnnsjsk](/maintainers/dnnsjsk)

---

Top Contributors

[![dnnsjsk](https://avatars.githubusercontent.com/u/73965001?v=4)](https://github.com/dnnsjsk "dnnsjsk (103 commits)")

---

Tags

phpdiffgitmergerepositorypackvcs

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/pitmaster-pitmaster/health.svg)

```
[![Health](https://phpackages.com/badges/pitmaster-pitmaster/health.svg)](https://phpackages.com/packages/pitmaster-pitmaster)
```

###  Alternatives

[gehrisandro/tailwind-merge-php

TailwindMerge for PHP merges multiple Tailwind CSS classes by automatically resolving conflicts between them

1391.7M12](/packages/gehrisandro-tailwind-merge-php)[lukascivil/treewalker

TreeWalker is a simple and small Library that will help you to work faster with manipulation of structures in PHP

741.1M7](/packages/lukascivil-treewalker)[balbuf/composer-git-merge-driver

Custom git merge driver to minimize merge conflicts in composer.json and composer.lock files.

137278.1k](/packages/balbuf-composer-git-merge-driver)[yieldstudio/tailwind-merge-php

Merge Tailwind CSS classes without style conflicts

4974.6k1](/packages/yieldstudio-tailwind-merge-php)[phalcongelist/php-diff

A comprehensive library for generating differences between two hashable objects (strings or arrays).

12435.6k2](/packages/phalcongelist-php-diff)[wcm/git-php-hooks-library

A collection of Git PHP Hooks

1210.1k3](/packages/wcm-git-php-hooks-library)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
