Gå til indhold

Skrivning til repositories

Pitmaster skriver til git-repositories med de samme binære formater som den kanoniske git-binær. Objekter skrives til lageret for løse objekter (zlib-komprimeret), indekset skrives i formatet v2 (eller v3, når poster kræver udvidede flag; et eksisterende indeks beholder sin version), og refs skrives som løse filer. De skrevne data kan verificeres med git fsck --strict.

Initialisering af et repository

PHP
use Pitmaster\Pitmaster;

$repo = Pitmaster::init('/path/to/new-project');

Dette opretter:

  • .git/objects/ (tomt objektlager)
  • .git/refs/heads/ og .git/refs/tags/ (tomme ref-mapper)
  • .git/HEAD, der indeholder ref: refs/heads/main
  • .git/hooks/, .git/info/exclude og .git/description
  • .git/config med standardindstillinger

Angiv 'sha256' som det andet argument for at oprette et SHA-256-repository: Pitmaster::init($path, 'sha256').

Standardkonfigurationen angiver ikke core.logallrefupdates, så Pitmaster registrerer ingen reflog-poster i et repository, det har oprettet, før du sætter den nøgle til true (#8). Repositories oprettet af git init har allerede denne indstilling.

Tilføjelse af filer til staging-området

add

PHP
$repo->add('src/Feature.php');
$repo->add('src/Feature.php', 'tests/FeatureTest.php', 'README.md');

Hvert argument er en filsti relativ til arbejdstræets rodmappe. Mapper og glob-mønstre udvides ikke, og en manglende fil udløser RuntimeException. For hver fil gør Pitmaster følgende:

  1. Læser filindholdet fra arbejdstræet
  2. Opretter et Blob-objekt og beregner dets hash
  3. Skriver blobben til .git/objects/ (zlib-komprimeret)
  4. Opdaterer indeks-posten for stien med den nye hash og filmetadata

remove

PHP
$repo->remove('old-file.txt');
$repo->remove('-r', 'src');
$repo->remove('--cached', 'old-file.txt');

Fjerner sporede stier fra indekset og arbejdstræet. Brug --cached til kun at fjerne fra indekset, eller -r / --recursive til sporede mapper.

mv

PHP
$repo->mv('old-name.php', 'new-name.php');

Omdøber filen i arbejdstræet, fjerner den gamle indeks-post og tilføjer den nye.

Oprettelse af commits

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

Commit-processen:

  1. Byg tree fra indekset: Den flade liste over indeks-poster organiseres i et tree-hierarki (mapper bliver til tree-objekter, filer bliver til blob-referencer). Hvert tree skrives til objektlageret.
  2. Bestem forælder: Den aktuelle HEAD-commit bliver forælder. Rod-commits (den første commit i et repository) har ingen forældre.
  3. Bestem forfatter: Hentes fra miljøvariablerne PITMASTER_AUTHOR_* og GIT_AUTHOR_*, derefter konstanterne PITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, derefter .git/config (user.name/user.email) og til sidst Pitmaster <pitmaster@localhost>. Committeren findes på samme måde.
  4. Skriv commit-objekt: Commit-indholdet (tree, parent, author, committer, besked) serialiseres, hashes og skrives.
  5. Opdater HEAD: Branch-ref'en, som HEAD peger på, opdateres til den nye commit-hash.

Hooks køres før og efter disse trin (pre-commit, prepare-commit-msg, commit-msg, post-commit), medmindre handle blev åbnet med ['hooks' => false]. commit() udløser en fejl, hvis beskeden mangler, hvis tree'et er uændret i forhold til HEAD, eller hvis indekset indeholder umergede stier.

Brugerdefineret forfatter

PHP
$author = 'Jane Smith <jane@example.com> 1700000000 +0000';
$commitId = $repo->commit('Add feature', $author);

Verifikation med git fsck

Integrationsdækningen for Pitmaster kontrollerer skrevne objekter mod git fsck --strict, og du kan selv foretage samme verifikation:

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

Hvis Pitmaster skriver et ugyldigt objekt, rapporterer git fsck fejlen med det samme.

Administration af brancher

Opret en branch

PHP
// Branch from HEAD
$repo->createBranch('feature/new-thing');

// Branch from a specific commit
$repo->createBranch('hotfix', $repo->resolve('v1.0.0'));

Opretter en ref-fil på .git/refs/heads/<name> med target-committens hash.

Slet en branch

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

Skift branch

PHP
$repo->checkout('feature/login');

Opdaterer HEAD til en symbolsk ref, der peger på branchen, nulstiller indekset, så det matcher branchens spids-tree, og opdaterer arbejdstræet.

Lokale ændringer i stier, der er forskellige mellem de to træer, stopper checkout med en RuntimeException. Ikke-committede ændringer i alle andre sporede filer erstattes af branchens indhold, hvor git ellers ville bevare dem (#2). Commit eller stash dem, før du skifter.

Kontrollér, om den er flettet

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

Håndtering af tags

Letvægtstag

PHP
$repo->createLightweightTag('v1.0.0');                          // At HEAD
$repo->createLightweightTag('v0.9.0', $repo->resolve('HEAD~5'));

Et letvægtstag er blot en ref, der peger direkte på et commit.

Annoteret tag

PHP
$tagId = $repo->createTag('v2.0.0', 'Release version 2.0.0');

Et annoteret tag opretter et tagobjekt (med tagger, meddelelse og mål) samt en ref, der peger på det. Taggeren er den aktuelle committer-identitet, som bestemmes på samme måde som commitforfatteren.

Brugerdefineret tagger

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

Direkte opdatering af refs

PHP
$repo->updateRef('refs/heads/main', $commitId);
$repo->updateRef('refs/tags/latest', $commitId);

Direkte skrivning af objekter

Til avancerede anvendelsestilfælde kan du skrive objekter uden at gå gennem den overordnede 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 et SHA-256-repository skal algoritmen angives: Blob::fromContent('Hello, world!', 'sha256').

Skriv et træ

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 posterne i den angivne rækkefølge og bruger de angivne tilstandsstrenge. Angiv dem i gits træsortering (efter navn, hvor mapper sammenlignes, som om deres navn sluttede på /), og angiv mappetilstande som 40000: git gemmer trætilstande uden det indledende nul, og git fsck --strict afviser 040000.

Skriv et commit

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

Nulstil

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

Gendan

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 og revert

PHP
// Apply a commit on the current branch
$newId = $repo->cherryPick('feature~1');

// Undo a commit
$revertId = $repo->revert('HEAD~2');

Begge accepterer enhver revision, som resolve() accepterer. Fuldstændige hashes virker; forkortede hashes gør ikke.