Schrijven naar repositories
Pitmaster schrijft git-repositories met dezelfde binaire indelingen als de canonieke git-binary git. Objecten worden naar de opslag voor losse objecten geschreven (zlib-gecomprimeerd), de index wordt geschreven in v2-indeling (of v3 wanneer items uitgebreide vlaggen vereisen; een bestaande index behoudt zijn versie) en refs worden als losse bestanden geschreven. De geschreven gegevens kunnen worden geverifieerd met git fsck --strict.
Een repository initialiseren
use Pitmaster\Pitmaster;
$repo = Pitmaster::init('/path/to/new-project');
Dit maakt het volgende aan:
.git/objects/(lege objectopslag).git/refs/heads/en.git/refs/tags/(lege refmappen).git/HEADmetref: refs/heads/main.git/hooks/,.git/info/excludeen.git/description.git/configmet standaardinstellingen
Geef 'sha256' als tweede argument mee om een SHA-256-repository aan te maken: Pitmaster::init($path, 'sha256').
De standaardconfiguratie stelt core.logallrefupdates niet in, dus Pitmaster legt geen reflog-items vast in een repository die hiermee is aangemaakt totdat u die sleutel op true instelt (#8). Repositories die door git init zijn aangemaakt, hebben deze instelling al.
Bestanden stagen
add
$repo->add('src/Feature.php');
$repo->add('src/Feature.php', 'tests/FeatureTest.php', 'README.md');
Elk argument is een bestandspad relatief aan de root van de werkboom. Mappen en globpatronen worden niet uitgebreid en bij een ontbrekend bestand wordt RuntimeException gegenereerd. Voor elk bestand doet Pitmaster het volgende:
- Leest de bestandsinhoud uit de werkboom
- Maakt een
Blob-object aan en berekent de hash ervan - Schrijft de blob naar
.git/objects/(zlib-gecomprimeerd) - Werkt de indexvermelding voor dat pad bij met de nieuwe hash en bestandsmetagegevens
remove
$repo->remove('old-file.txt');
$repo->remove('-r', 'src');
$repo->remove('--cached', 'old-file.txt');
Verwijdert bijgehouden paden uit de index en werkboom. Gebruik --cached om alleen uit de index te verwijderen, of -r / --recursive voor bijgehouden mappen.
mv
$repo->mv('old-name.php', 'new-name.php');
Hernoemt het bestand in de werkboom, verwijdert de oude indexvermelding en voegt de nieuwe toe.
Commits aanmaken
$commitId = $repo->commit('Fix null pointer bug');
echo $commitId->hex;
Het commitproces:
- Tree opbouwen vanuit de index: de vlakke lijst met indexitems wordt omgezet in een tree-hiërarchie (mappen worden tree-objecten, bestanden blobverwijzingen). Elke tree wordt naar de objectopslag geschreven.
- Ouder bepalen: de huidige HEAD-commit wordt de ouder. Rootcommits (de eerste commit in een repo) hebben geen ouders.
- Auteur bepalen: afkomstig uit de omgevingsvariabelen
PITMASTER_AUTHOR_*enGIT_AUTHOR_*, vervolgens de constantenPITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, daarna.git/config(user.name/user.email) en ten slottePitmaster <pitmaster@localhost>. De committer wordt op dezelfde manier bepaald. - Commitobject schrijven: de commitinhoud (
tree,parent,author,committer, bericht) wordt geserialiseerd, gehasht en geschreven. - HEAD bijwerken: de branchref waar HEAD naar verwijst, wordt bijgewerkt met de nieuwe commithash.
Hooks worden rond deze stappen uitgevoerd (pre-commit, prepare-commit-msg, commit-msg, post-commit), tenzij de handle is geopend met ['hooks' => false]. commit() genereert een fout als het bericht ontbreekt, als de tree ongewijzigd is ten opzichte van HEAD of als de index niet-samengevoegde paden bevat.
Aangepaste auteur
$author = 'Jane Smith <jane@example.com> 1700000000 +0000';
$commitId = $repo->commit('Add feature', $author);
Verifiëren met git fsck
De integratiedekking van Pitmaster controleert geschreven objecten aan de hand van git fsck --strict; u kunt dit ook zelf handmatig verifiëren:
cd /path/to/repo
git fsck --strict
Als Pitmaster een ongeldig object schrijft, meldt git fsck de fout direct.
Branches beheren
Een branch aanmaken
// Branch from HEAD
$repo->createBranch('feature/new-thing');
// Branch from a specific commit
$repo->createBranch('hotfix', $repo->resolve('v1.0.0'));
Maakt een refbestand aan op .git/refs/heads/<name> met de hash van de doelcommit.
Een branch verwijderen
$repo->deleteBranch('feature/old');
Van branch wisselen
$repo->checkout('feature/login');
Werkt HEAD bij naar een symbolische ref die naar de branch verwijst, zet de index terug zodat deze overeenkomt met de tree van de branchkop en werkt de werkboom bij.
Lokale wijzigingen in paden die verschillen tussen de twee trees stoppen het uitchecken met een RuntimeException. Niet-vastgelegde wijzigingen in alle andere bijgehouden bestanden worden vervangen door de inhoud van de branch, waar git ze zou behouden (#2). Commit of stash ze voordat u van branch wisselt.
Controleren of samengevoegd
if ($repo->isBranchMerged('feature/done')) {
$repo->deleteBranch('feature/done');
}
Tags beheren
Lichtgewicht tag
$repo->createLightweightTag('v1.0.0'); // At HEAD
$repo->createLightweightTag('v0.9.0', $repo->resolve('HEAD~5'));
Een lichtgewicht tag is slechts een ref die rechtstreeks naar een commit verwijst.
Geannoteerde tag
$tagId = $repo->createTag('v2.0.0', 'Release version 2.0.0');
Een geannoteerde tag maakt een tagobject aan (met tagger, bericht en doel) en een ref die ernaar verwijst. De tagger is de huidige committeridentiteit, die op dezelfde manier wordt bepaald als de commit-auteur.
Aangepaste tagger
$tagId = $repo->createTag(
'v2.0.0',
'Release version 2.0.0',
$repo->resolve('HEAD'),
'Jane Smith <jane@example.com> 1700000000 +0000',
);
Refs rechtstreeks bijwerken
$repo->updateRef('refs/heads/main', $commitId);
$repo->updateRef('refs/tags/latest', $commitId);
Objecten rechtstreeks schrijven
Voor geavanceerde toepassingen kunt u objecten schrijven zonder de high-level API te gebruiken.
Een blob schrijven
use Pitmaster\Object\Blob;
$blob = Blob::fromContent('Hello, world!');
$id = $repo->writeObject($blob);
echo $id->hex; // SHA-1 of "blob 13\0Hello, world!"
Geef het algoritme in een SHA-256-repository door: Blob::fromContent('Hello, world!', 'sha256').
Een tree schrijven
use Pitmaster\Object\Tree;
use Pitmaster\Object\TreeEntry;
use Pitmaster\Object\ObjectId;
$entries = [
new TreeEntry('100644', 'README.md', $blobId),
new TreeEntry('40000', 'src', $subtreeId),
];
$tree = Tree::fromEntries($entries);
$id = $repo->writeObject($tree);
Tree::fromEntries() schrijft de entries in de opgegeven volgorde en met de opgegeven mode-strings. Geef ze op in de tree-volgorde van git (op naam, waarbij directories worden vergeleken alsof hun naam eindigt op /) en schrijf directory-modes als 40000: git slaat tree-modes op zonder de voorloopnul, en git fsck --strict weigert 040000.
Een commit schrijven
use Pitmaster\Object\Commit;
use Pitmaster\Object\ObjectId;
use Pitmaster\Object\ObjectType;
$content = Commit::buildContent(
tree: $treeId,
parents: [$parentId],
author: 'Name <email> 1700000000 +0000',
committer: 'Name <email> 1700000000 +0000',
message: "Commit message\n",
);
$commitId = ObjectId::compute(ObjectType::Commit, $content);
$commit = Commit::parse($content, $commitId);
$repo->writeObject($commit);
Resetten
// Soft: move HEAD only
$repo->reset('HEAD~1', 'soft');
// Mixed: move HEAD + reset index (default)
$repo->reset('HEAD~1');
// Hard: move HEAD + reset index + reset working tree
$repo->reset('HEAD~3', 'hard');
Herstellen
// Restore a file from the index into the worktree
$repo->restore('src/File.php');
// Restore the index version from HEAD (the worktree is left alone)
$repo->restore('src/File.php', staged: true);
// Restore from a specific commit
$repo->restore('src/File.php', 'HEAD~1');
// Restore both index and worktree from a specific commit
$repo->restore('src/File.php', 'HEAD~1', staged: true, worktree: true);
Cherry-picken en terugdraaien
// Apply a commit on the current branch
$newId = $repo->cherryPick('feature~1');
// Undo a commit
$revertId = $repo->revert('HEAD~2');
Beide accepteren elke revision die resolve() accepteert. Volledige hashes werken; verkorte hashes niet.