Ga naar de inhoud

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

PHP
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/HEAD met ref: refs/heads/main
  • .git/hooks/, .git/info/exclude en .git/description
  • .git/config met 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

PHP
$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:

  1. Leest de bestandsinhoud uit de werkboom
  2. Maakt een Blob-object aan en berekent de hash ervan
  3. Schrijft de blob naar .git/objects/ (zlib-gecomprimeerd)
  4. Werkt de indexvermelding voor dat pad bij met de nieuwe hash en bestandsmetagegevens

remove

PHP
$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

PHP
$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

PHP
$commitId = $repo->commit('Fix null pointer bug');
echo $commitId->hex;

Het commitproces:

  1. 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.
  2. Ouder bepalen: de huidige HEAD-commit wordt de ouder. Rootcommits (de eerste commit in een repo) hebben geen ouders.
  3. Auteur bepalen: afkomstig uit de omgevingsvariabelen PITMASTER_AUTHOR_* en GIT_AUTHOR_*, vervolgens de constanten PITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, daarna .git/config (user.name/user.email) en ten slotte Pitmaster <pitmaster@localhost>. De committer wordt op dezelfde manier bepaald.
  4. Commitobject schrijven: de commitinhoud (tree, parent, author, committer, bericht) wordt geserialiseerd, gehasht en geschreven.
  5. 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

PHP
$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:

Shell
cd /path/to/repo
git fsck --strict

Als Pitmaster een ongeldig object schrijft, meldt git fsck de fout direct.

Branches beheren

Een branch aanmaken

PHP
// 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

PHP
$repo->deleteBranch('feature/old');

Van branch wisselen

PHP
$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

PHP
if ($repo->isBranchMerged('feature/done')) {
    $repo->deleteBranch('feature/done');
}

Tags beheren

Lichtgewicht tag

PHP
$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

PHP
$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

PHP
$tagId = $repo->createTag(
    'v2.0.0',
    'Release version 2.0.0',
    $repo->resolve('HEAD'),
    'Jane Smith <jane@example.com> 1700000000 +0000',
);

Refs rechtstreeks bijwerken

PHP
$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

PHP
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

PHP
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

PHP
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

PHP
// 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

PHP
// 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

PHP
// 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.