Erste Schritte
Installation
Installiere Pitmaster mit Composer:
composer require pitmaster/pitmaster
Voraussetzungen
- PHP 8.2+ mit readonly-Klassen, Enums und Konstruktor-Promotion
- ext-zlib für die Komprimierung und Dekomprimierung von Objekten (bei den meisten Installationen integriert)
- ext-json für Statusdateien von Operationen und API-Nutzdaten von Git LFS
- ext-mbstring, deklariert in
composer.json, weshalb Composer es bei der Installation verlangt - ext-ctype für die Hash-Validierung (in den meisten PHP-Builds aktiviert, aber nicht in
composer.jsondeklariert)
Für grundlegende Repository-Operationen sind weder das git-Binary noch FFI oder externe Hilfsprogramme erforderlich. Optionale Funktionen haben zusätzliche Laufzeitanforderungen: Hooks werden mit proc_open() ausgeführt, und der SSH-Transport verwendet ext-ssh2, wenn es geladen ist, andernfalls startet er das System-ssh-Binary über proc_open().
Ein vorhandenes Repository öffnen
use Pitmaster\Pitmaster;
$repo = Pitmaster::open('/path/to/project');
Damit wird das Repository am angegebenen Pfad geöffnet. Pitmaster ermittelt das .git-Verzeichnis (oder löst bei verknüpften Worktrees eine .git-Datei auf) und initialisiert die Objektdatenbank, die Referenzdatenbank und die Konfiguration.
open(), init() und clone() akzeptieren als letztes Argument ein Options-Array:
// 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());
Hooks werden standardmäßig ausgeführt. Pitmaster::processFreeOptions() gibt ['processes' => false, 'hooks' => false] zurück; lokale Lese- und Schreibvorgänge funktionieren mit diesem Handle weiterhin.
Prüfen, ob ein Pfad ein Repository ist
if (Pitmaster::isRepository('/path/to/project')) {
$repo = Pitmaster::open('/path/to/project');
}
Ein neues Repository initialisieren
$repo = Pitmaster::init('/path/to/new-project');
Dadurch wird die .git-Verzeichnisstruktur mit Objekten, Referenzen, HEAD (der auf refs/heads/main verweist) und einer Standardkonfiguration erstellt.
Um ein Repository mit SHA-256 anzulegen, übergib das Objektformat als zweites Argument:
$repo = Pitmaster::init('/path/to/new-project', 'sha256');
Objekt-IDs in diesem Repository bestehen aus 64 Hex-Zeichen, und die Konfiguration speichert extensions.objectformat = sha256. Bei späterem Öffnen übernehmen Repositorys das Format aus diesem Konfigurationseintrag.
Den HEAD-Commit lesen
$head = $repo->head();
echo "Commit: {$head->id->hex}\n";
echo "Author: {$head->author}\n";
echo "Message: {$head->message}\n";
Die Methode head() löst HEAD auf (einschließlich symbolischer Referenzen) und gibt ein Commit-Objekt zurück.
Branches und Tags auflisten
// 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']
Commit-Historie durchlaufen
// Last 20 commits from HEAD
$commits = $repo->log(20);
foreach ($commits as $commit) {
echo substr($commit->id->hex, 0, 7) . " {$commit->message}\n";
}
Du kannst auch bei einem bestimmten Commit beginnen:
$from = $repo->resolve('feature/login');
$commits = $repo->log(10, $from);
Status des Arbeitsverzeichnisses prüfen
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";
}
}
Dateien zum Commit vormerken und committen
// 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";
Name und E-Mail-Adresse des Autors werden in dieser Reihenfolge ermittelt: aus den Umgebungsvariablen PITMASTER_AUTHOR_NAME / PITMASTER_AUTHOR_EMAIL, den Umgebungsvariablen GIT_AUTHOR_NAME / GIT_AUTHOR_EMAIL, den Konstanten PITMASTER_AUTHOR_NAME / PITMASTER_AUTHOR_EMAIL, der Repository-Konfiguration (.git/config sowie user.name und user.email) und schließlich Pitmaster <pitmaster@localhost>. Gelesen wird nur die Repository-Konfigurationsdatei (und die darin eingebundenen Dateien), nicht ~/.gitconfig. Der Committer wird auf dieselbe Weise anhand der Namen unter *_COMMITTER_* ermittelt; falls dort keine Werte vorhanden sind, werden die Autorenkonstanten verwendet.
Diffs berechnen
// 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();
Ein Remote-Repository klonen
$repo = Pitmaster::clone('https://github.com/user/repo.git', '/path/to/destination');
Dabei werden Referenzen ermittelt, die Pack-Datei abgerufen, Remote-Tracking-Branches eingerichtet und der Standardbranch ausgecheckt. HTTP(S)-URLs verwenden Smart-HTTP und greifen bei Bedarf auf Dumb-HTTP zurück; für SSH-URLs wird der SSH-Transport verwendet. Für einen flachen Klon übergib die Tiefe als drittes Argument: Pitmaster::clone($url, $path, 1).
Ein beliebiges Objekt anhand seines Hashes lesen
$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;
}
Konfiguration
Pitmaster berücksichtigt die .git/config des Repositorys für Autoreninformationen und Remote-URLs. Du kannst mit den Konstanten PHP auch globale Standardwerte festlegen. Definiere sie, bevor Pitmaster ausgeführt wird:
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');
| Konstante | Standardwert | Wirkung |
|---|---|---|
PITMASTER_AUTHOR_NAME, PITMASTER_AUTHOR_EMAIL |
none | Identität des Autors (siehe Reihenfolge oben) |
PITMASTER_COMMITTER_NAME, PITMASTER_COMMITTER_EMAIL |
Autorenwerte | Identität des Committers |
PITMASTER_HTTP_TIMEOUT |
30 |
Timeout für Smart-HTTP in Sekunden (Ganzzahl) |
PITMASTER_MAX_DELTA_CHAIN |
50 |
Maximale Delta-Kettentiefe beim Lesen von Packs (Ganzzahl) |
PITMASTER_OBJECT_CACHE_ENTRIES |
1024 |
Objekte im In-Memory-Objektcache |
PITMASTER_OBJECT_CACHE_BYTES |
16M |
Byte-Budget des Objekt-Caches |
PITMASTER_PACK_RESOLVED_CACHE_ENTRIES |
4096 |
Aufgelöste Delta-Objekte, die pro Pack im Cache gehalten werden |
PITMASTER_PACK_RESOLVED_CACHE_BYTES |
32M |
Byte-Budget dieses Pack-Caches |
PITMASTER_MAX_PACK_MEMORY |
none | Älterer Name für das Byte-Budget des Pack-Caches, wird nur verwendet, wenn PITMASTER_PACK_RESOLVED_CACHE_BYTES nicht definiert ist |
Byte-Werte können als Ganzzahl oder als Zeichenfolge mit dem Suffix k, m oder g angegeben werden ('256M'). Ungültige Werte werden durch den Standardwert ersetzt.
Umgebungsvariablen überschreiben die Identitätskonstanten: PITMASTER_AUTHOR_NAME, PITMASTER_AUTHOR_EMAIL, PITMASTER_AUTHOR_DATE, die entsprechenden PITMASTER_COMMITTER_*-Variablen sowie die git-eigenen Variablen GIT_AUTHOR_* und GIT_COMMITTER_*. Der SSH-Transport liest die unter Protokolle beschriebenen Variablen PITMASTER_SSH_*.
Für den Hash-Algorithmus gibt es keine Konstante. Das Objektformat wird beim Erstellen des Repositorys gewählt (Pitmaster::init($path, 'sha256') oder init --object-format=sha256 auf dem CLI) und anschließend aus der Repository-Konfiguration gelesen.