Pāriet uz saturu

Rakstīšana repozitorijos

Pitmaster raksta git repozitorijus, izmantojot tos pašus bināros formātus kā kanoniskajā git binārajā failā. Objekti tiek ierakstīti nesaspiesto objektu krātuvē (saspiesti ar zlib), indekss tiek rakstīts v2 formātā (vai v3, ja ierakstiem nepieciešami paplašinātie karodziņi; esošais indekss saglabā savu versiju), bet atsauces tiek rakstītas kā nesaspiesti faili. Ierakstītos datus var pārbaudīt ar git fsck --strict.

Repozitorija inicializēšana

PHP
use Pitmaster\Pitmaster;

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

Tiek izveidoti:

  • .git/objects/ (tukša objektu krātuve)
  • .git/refs/heads/ un .git/refs/tags/ (tukši atsauču direktoriji)
  • .git/HEAD ar ref: refs/heads/main
  • .git/hooks/, .git/info/exclude un .git/description
  • .git/config ar noklusējuma iestatījumiem

Lai izveidotu SHA-256 repozitoriju, kā otro argumentu norādiet 'sha256': Pitmaster::init($path, 'sha256').

Noklusējuma konfigurācijā core.logallrefupdates nav iestatīts, tāpēc Pitmaster neveido reflog ierakstus izveidotajā repozitorijā, kamēr šo atslēgu neiestata uz true (#8). Repozitorijos, ko izveido git init, šī atslēga jau ir iestatīta.

Failu pievienošana indeksam

add

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

Katrs arguments ir faila ceļš attiecībā pret darba koka sakni. Direktoriji un glob izteiksmes netiek izvērstas, un, ja fails neeksistē, tiek izmests RuntimeException. Katram failam Pitmaster:

  1. Nolasa faila saturu no darba koka
  2. Izveido Blob objektu un aprēķina tā jaucējvērtību
  3. Ieraksta blob objektu .git/objects/ (saspiestu ar zlib)
  4. Atjaunina indeksa ierakstu šim ceļam ar jauno jaucējvērtību un faila metadatiem

remove

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

Noņem izsekotos ceļus no indeksa un darba koka. Lai noņemtu tikai no indeksa, izmantojiet --cached, bet izsekotiem direktorijiem — -r / --recursive.

mv

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

Pārdēvē failu darba kokā, noņem veco indeksa ierakstu un pievieno jauno.

Komitējumu izveide

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

Komitēšanas process:

  1. Koka izveide no indeksa: plakanais indeksa ierakstu saraksts tiek sakārtots koka hierarhijā (direktoriji kļūst par koka objektiem, faili — par blob atsaucēm). Katrs koks tiek ierakstīts objektu krātuvē.
  2. Vecākkomitējuma noteikšana: pašreizējais HEAD komitējums kļūst par vecākkomitējumu. Saknes komitējumiem (pirmajam komitējumam repozitorijā) vecākkomitējumu nav.
  3. Autora noteikšana: autors tiek iegūts no vides mainīgajiem PITMASTER_AUTHOR_* un GIT_AUTHOR_*, pēc tam no konstantēm PITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, tad no .git/config (user.name/user.email) un visbeidzot no Pitmaster <pitmaster@localhost>. Komitētājs tiek noteikts tāpat.
  4. Komitējuma objekta ierakstīšana: komitējuma saturs (tree, parent, author, committer, ziņojums) tiek serializēts, tam aprēķina jaucējvērtību un tas tiek ierakstīts.
  5. HEAD atjaunināšana: zara atsauce, uz kuru norāda HEAD, tiek atjaunināta uz jaunā komitējuma jaucējvērtību.

Šo darbību laikā tiek izpildīti āķi (pre-commit, prepare-commit-msg, commit-msg, post-commit), ja vien deskriptors nav atvērts ar ['hooks' => false]. commit() izmet kļūdu, ja trūkst ziņojuma, koks nav mainījies salīdzinājumā ar HEAD vai indeksam ir neapvienoti ceļi.

Pielāgots autors

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

Pārbaude ar git fsck

Pitmaster integrācijas testos pārbauda rakstītos objektus, salīdzinot tos ar git fsck --strict; to pašu varat pārbaudīt arī manuāli:

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

Ja Pitmaster ieraksta nederīgu objektu, git fsck nekavējoties ziņos par kļūdu.

Zaru pārvaldība

Zara izveide

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

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

Izveido atsauces failu .git/refs/heads/<name> ar mērķa komitējuma jaucējvērtību.

Zara dzēšana

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

Zaru pārslēgšana

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

Atjaunina HEAD, lai tas būtu simboliska atsauce uz zaru, atiestata indeksu atbilstoši zara jaunākā komitējuma kokam un atjaunina darba koku.

Ja starp abiem kokiem atšķirīgie ceļi ietver lokālas izmaiņas, pāreja tiek apturēta ar RuntimeException. Visu pārējo izsekoto failu nekomitētās izmaiņas tiek aizstātas ar zara saturu, kā to darītu git, saglabājot šīs izmaiņas (#2). Pirms zara pārslēgšanas izveidojiet komitējumu vai noglabājiet izmaiņas.

Apvienošanas statusa pārbaude

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

Birkas pārvaldība

Vieglā birka

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

Vieglā birka ir tikai atsauce, kas tieši norāda uz komitējumu.

Anotētā birka

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

Anotēta birka izveido birkas objektu (ar birkas autoru, ziņojumu un mērķi) un atsauci, kas uz to norāda. Birkas autors ir pašreizējā komitētāja identitāte, ko nosaka tāpat kā komitējuma autoru.

Pielāgots birkas autors

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

Tieša atsauču atjaunināšana

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

Objektu tieša ierakstīšana

Papildu lietojuma gadījumos objektus var ierakstīt, neizmantojot augsta līmeņa API.

Blob objekta ierakstīšana

PHP
use Pitmaster\Object\Blob;

$blob = Blob::fromContent('Hello, world!');
$id = $repo->writeObject($blob);
echo $id->hex;  // SHA-1 of "blob 13\0Hello, world!"

SHA-256 repozitorijā norādiet algoritmu kā argumentu: Blob::fromContent('Hello, world!', 'sha256').

Koka ierakstīšana

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() ieraksta ierakstus norādītajā secībā un režīma virknes tādas, kādas tās norādītas. Padodiet tās git koka secībā (pēc nosaukuma, direktorijus salīdzinot tā, it kā to nosaukuma beigās būtu /) un ierakstiet direktoriju režīmus kā 40000: git glabā koka režīmus bez sākuma nulles, bet git fsck --strict noraida 040000.

Komitējuma ierakstīšana

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

Atiestatīšana

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

Atjaunošana

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 un atgriešana

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

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

Abi pieņem jebkuru pārskatījumu, ko atbalsta resolve(). Pilni jaucējkodi darbojas, saīsināti — ne.