Skriva till arkiv
Pitmaster skriver git-arkiv med samma binära format som den kanoniska git-binären. Objekt skrivs till lagret med lösa objekt (zlib-komprimerade), indexet skrivs i formatet v2 (eller v3 när poster behöver utökade flaggor; ett befintligt index behåller sin version) och refs skrivs som lösa filer. Data som skrivits kan verifieras med git fsck --strict.
Initiera ett arkiv
use Pitmaster\Pitmaster;
$repo = Pitmaster::init('/path/to/new-project');
Detta skapar:
.git/objects/(tomt objektlager).git/refs/heads/och.git/refs/tags/(tomma ref-kataloger).git/HEADsom innehållerref: refs/heads/main.git/hooks/,.git/info/excludeoch.git/description.git/configmed standardinställningar
Skicka med 'sha256' som det andra argumentet för att skapa ett SHA-256-arkiv: Pitmaster::init($path, 'sha256').
Standardkonfigurationen anger inte core.logallrefupdates, så Pitmaster registrerar inga reflog-poster i arkiv som det har skapat förrän du ställer in nyckeln till true (#8). Arkiv som skapats av git init har redan denna inställning.
Mellanlagra filer
add
$repo->add('src/Feature.php');
$repo->add('src/Feature.php', 'tests/FeatureTest.php', 'README.md');
Varje argument är en filsökväg relativ till arbetsträdets rot. Kataloger och globmönster expanderas inte, och en saknad fil utlöser RuntimeException. För varje fil gör Pitmaster följande:
- Läser filinnehållet från arbetsträdet
- Skapar ett
Blob-objekt och beräknar dess hash - Skriver blobben till
.git/objects/(zlib-komprimerad) - Uppdaterar indexposten för sökvägen med den nya hashen och filmetadata
remove
$repo->remove('old-file.txt');
$repo->remove('-r', 'src');
$repo->remove('--cached', 'old-file.txt');
Tar bort spårade sökvägar från indexet och arbetsträdet. Använd --cached för att bara ta bort från indexet, eller -r / --recursive för spårade kataloger.
mv
$repo->mv('old-name.php', 'new-name.php');
Byter namn på filen i arbetsträdet, tar bort den gamla indexposten och lägger till den nya.
Skapa incheckningar
$commitId = $repo->commit('Fix null pointer bug');
echo $commitId->hex;
Incheckningsprocessen:
- Bygg ett träd från indexet: den platta listan med indexposter organiseras i en trädstruktur (kataloger blir trädobjekt och filer blir blob-referenser). Varje träd skrivs till objektlagret.
- Fastställ förälder: den aktuella HEAD-incheckningen blir förälder. Rotincheckningar (den första incheckningen i ett arkiv) har inga föräldrar.
- Fastställ upphovsperson: hämtas från miljövariablerna
PITMASTER_AUTHOR_*ochGIT_AUTHOR_*, sedan konstanternaPITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, därefter.git/config(user.name/user.email) och sistPitmaster <pitmaster@localhost>. Incheckaren fastställs på samma sätt. - Skriv incheckningsobjektet: incheckningens innehåll (
tree,parent,author,committer, meddelande) serialiseras, hashas och skrivs. - Uppdatera HEAD: grenens ref som HEAD pekar på uppdateras till den nya incheckningens hash.
Krokar körs före och efter dessa steg (pre-commit, prepare-commit-msg, commit-msg, post-commit) om inte handtaget öppnades med ['hooks' => false]. commit() utlöser ett fel om meddelandet saknas, om trädet är oförändrat jämfört med HEAD eller om indexet innehåller sammanfogningssökvägar.
Anpassad upphovsperson
$author = 'Jane Smith <jane@example.com> 1700000000 +0000';
$commitId = $repo->commit('Add feature', $author);
Verifiera med git fsck
Pitmasters integrationstester kontrollerar skrivna objekt mot git fsck --strict, och du kan verifiera dem manuellt på samma sätt:
cd /path/to/repo
git fsck --strict
Om Pitmaster skriver ett ogiltigt objekt rapporterar git fsck felet omedelbart.
Hantera grenar
Skapa en gren
// Branch from HEAD
$repo->createBranch('feature/new-thing');
// Branch from a specific commit
$repo->createBranch('hotfix', $repo->resolve('v1.0.0'));
Skapar en ref-fil på .git/refs/heads/<name> som innehåller mål-incheckningens hash.
Ta bort en gren
$repo->deleteBranch('feature/old');
Byt gren
$repo->checkout('feature/login');
Uppdaterar HEAD till en symbolisk ref som pekar på grenen, återställer indexet så att det matchar grenens trädtopp och uppdaterar arbetsträdet.
Lokala ändringar i sökvägar som skiljer sig mellan de två träden avbryter utcheckningen med ett RuntimeException. Oincheckade ändringar i alla andra spårade filer ersätts med grenens innehåll, medan git skulle behålla dem (#2). Checka in eller stash:a dem innan du byter gren.
Kontrollera om sammanfogad
if ($repo->isBranchMerged('feature/done')) {
$repo->deleteBranch('feature/done');
}
Hantera taggar
Lättviktig tagg
$repo->createLightweightTag('v1.0.0'); // At HEAD
$repo->createLightweightTag('v0.9.0', $repo->resolve('HEAD~5'));
En lättviktig tagg är bara en ref som pekar direkt på en incheckning.
Annoterad tagg
$tagId = $repo->createTag('v2.0.0', 'Release version 2.0.0');
En annoterad tagg skapar ett taggobjekt (med taggare, meddelande och mål) och en ref som pekar på det. Taggaren är den aktuella incheckarens identitet, fastställd på samma sätt som incheckningens upphovsperson.
Anpassad taggare
$tagId = $repo->createTag(
'v2.0.0',
'Release version 2.0.0',
$repo->resolve('HEAD'),
'Jane Smith <jane@example.com> 1700000000 +0000',
);
Uppdatera refs direkt
$repo->updateRef('refs/heads/main', $commitId);
$repo->updateRef('refs/tags/latest', $commitId);
Skriva objekt direkt
För avancerade användningsfall kan du skriva objekt utan att gå via det överordnade API.
Skriv en blob
use Pitmaster\Object\Blob;
$blob = Blob::fromContent('Hello, world!');
$id = $repo->writeObject($blob);
echo $id->hex; // SHA-1 of "blob 13\0Hello, world!"
I ett SHA-256-arkiv anger du algoritmen: Blob::fromContent('Hello, world!', 'sha256').
Skriv ett träd
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() skriver posterna i den angivna ordningen och lägessträngarna som de anges. Skicka dem i trädordningen för git (efter namn, där kataloger jämförs som om namnet slutade med /) och ange kataloglägen som 40000: git lagrar trädens lägen utan inledande nolla, och git fsck --strict avvisar 040000.
Skriv en incheckning
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);
Återställning
// 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');
Återskapa
// 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-pick och återställning
// Apply a commit on the current branch
$newId = $repo->cherryPick('feature~1');
// Undo a commit
$revertId = $repo->revert('HEAD~2');
Båda accepterar valfri revision som resolve() godtar. Fullständiga hashar fungerar; förkortade hashar gör det inte.