Hoppa till innehåll

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

PHP
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/HEAD som innehåller ref: refs/heads/main
  • .git/hooks/, .git/info/exclude och .git/description
  • .git/config med 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

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

  1. Läser filinnehållet från arbetsträdet
  2. Skapar ett Blob-objekt och beräknar dess hash
  3. Skriver blobben till .git/objects/ (zlib-komprimerad)
  4. Uppdaterar indexposten för sökvägen med den nya hashen och filmetadata

remove

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

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

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

Incheckningsprocessen:

  1. 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.
  2. 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.
  3. Fastställ upphovsperson: hämtas från miljövariablerna PITMASTER_AUTHOR_* och GIT_AUTHOR_*, sedan konstanterna PITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, därefter .git/config (user.name/user.email) och sist Pitmaster <pitmaster@localhost>. Incheckaren fastställs på samma sätt.
  4. Skriv incheckningsobjektet: incheckningens innehåll (tree, parent, author, committer, meddelande) serialiseras, hashas och skrivs.
  5. 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

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

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

Om Pitmaster skriver ett ogiltigt objekt rapporterar git fsck felet omedelbart.

Hantera grenar

Skapa en gren

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

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

Byt gren

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

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

Hantera taggar

Lättviktig tagg

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

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

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

Uppdatera refs direkt

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

PHP
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

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() 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

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);

Återställning

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');

Återskapa

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-pick och återställning

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