Preskoči na vsebino

Pisanje v repozitorije

Pitmaster zapisuje repozitorije git z enakimi binarnimi formati kot kanarni binarni program git. Objekti se zapišejo v shrambo razvezanih objektov (stisnjeno z zlib), indeks se zapiše v formatu v2 (ali v3, kadar vnosi potrebujejo razširjene zastavice; obstoječi indeks ohrani svojo različico), sklici pa se zapišejo kot razvezane datoteke. Zapisane podatke je mogoče preveriti z git fsck --strict.

Inicializacija repozitorija

PHP
use Pitmaster\Pitmaster;

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

To ustvari:

  • .git/objects/ (prazna shramba objektov)
  • .git/refs/heads/ in .git/refs/tags/ (prazna imenika sklicev)
  • .git/HEAD, ki vsebuje ref: refs/heads/main
  • .git/hooks/, .git/info/exclude in .git/description
  • .git/config s privzetimi nastavitvami

Za ustvarjanje repozitorija SHA-256 kot drugi argument podajte 'sha256': Pitmaster::init($path, 'sha256').

Privzeta konfiguracija ne nastavi core.logallrefupdates, zato Pitmaster v ustvarjenem repozitoriju ne zabeleži nobenega vnosa refloga, dokler tega ključa ne nastavite na true (#8). Repozitoriji, ki jih ustvari git init, ga že imajo nastavljenega.

Priprava datotek

add

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

Vsak argument je pot do datoteke glede na koren delovnega drevesa. Imeniki in globi se ne razširijo, manjkajoča datoteka pa sproži RuntimeException. Za vsako datoteko Pitmaster:

  1. Prebere vsebino datoteke iz delovnega drevesa
  2. Ustvari objekt Blob in izračuna njegovo zgoščeno vrednost
  3. Zapiše blob v .git/objects/ (stisnjen z zlib)
  4. Posodobi vnos v indeksu za to pot z novo zgoščeno vrednostjo in metapodatki datoteke

remove

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

Odstrani sledene poti iz indeksa in delovnega drevesa. Za odstranitev samo iz indeksa uporabite --cached, za sledene imenike pa -r / --recursive.

mv

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

Preimenuje datoteko v delovnem drevesu, odstrani stari vnos iz indeksa in doda novega.

Ustvarjanje potrditev

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

Postopek potrditve:

  1. Izdelava drevesa iz indeksa: ploščat seznam vnosov indeksa se uredi v hierarhijo dreves (imeniki postanejo objekti dreves, datoteke pa reference na blobe). Vsako drevo se zapiše v shrambo objektov.
  2. Določitev nadrejenega elementa: trenutna potrditev HEAD postane nadrejeni element. Korenske potrditve (prva potrditev v repozitoriju) nimajo nadrejenih elementov.
  3. Določitev avtorja: vzame se iz spremenljivk okolja PITMASTER_AUTHOR_* in GIT_AUTHOR_*, nato iz konstant PITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, nato iz .git/config (user.name/user.email), nazadnje pa iz Pitmaster <pitmaster@localhost>. Potrditelj se določi na enak način.
  4. Zapis objekta potrditve: vsebina potrditve (tree, parent, author, committer, sporočilo) se serializira, zgosti in zapiše.
  5. Posodobitev HEAD: sklic veje, na katero kaže HEAD, se posodobi na novo zgoščeno vrednost potrditve.

Okoli teh korakov se izvedejo kavlji (pre-commit, prepare-commit-msg, commit-msg, post-commit), razen če je bil ročaj odprt z ['hooks' => false]. commit() sproži napako, če manjka sporočilo, če se drevo ni spremenilo glede na HEAD ali če so v indeksu nerazrešene poti.

Avtor po meri

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

Preverjanje z fsck ukaza git

Integracijski testi za Pitmaster preverjajo zapisane objekte glede na git fsck --strict, enako pa lahko preverite tudi ročno:

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

Če Pitmaster zapiše neveljaven objekt, git fsck napako takoj prikaže.

Upravljanje vej

Ustvarjanje veje

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

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

Ustvari datoteko sklica na .git/refs/heads/<name>, ki vsebuje zgoščeno vrednost ciljne potrditve.

Brisanje veje

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

Preklapljanje med vejami

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

Posodobi HEAD v simbolični sklic na vejo, ponastavi indeks, da se ujema z drevesom na vrhu veje, in posodobi delovno drevo.

Lokalne spremembe na poteh, ki se med drevesoma razlikujejo, ustavijo prevzem z RuntimeException. Nepotrjene spremembe v vseh drugih sledenih datotekah se nadomestijo z vsebino veje; ukaz git bi jih ohranil (#2). Pred preklopom jih potrdite ali shranite v zalogo.

Preverjanje združitve

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

Upravljanje oznak

Lahka oznaka

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

Lahka oznaka je zgolj sklic, ki kaže neposredno na potrditev.

Označena oznaka

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

Označena oznaka ustvari objekt oznake (z avtorjem oznake, sporočilom in ciljem) ter sklic, ki kaže nanj. Avtor oznake je trenutna identiteta potrditelja, določena enako kot avtor potrditve.

Avtor oznake po meri

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

Neposredno posodabljanje sklicev

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

Neposredno zapisovanje objektov

Za napredne primere uporabe lahko objekte zapišete brez uporabe visokoravenskega API.

Zapis bloba

PHP
use Pitmaster\Object\Blob;

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

V repozitoriju SHA-256 podajte algoritem: Blob::fromContent('Hello, world!', 'sha256').

Zapis drevesa

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() zapiše vnose v navedenem vrstnem redu in nize načinov takšne, kot so podani. Podajte jih v drevesnem vrstnem redu git (po imenu, pri čemer se imeniki primerjajo, kot da bi se njihovo ime končalo z /), načine imenikov pa zapišite kot 40000: git shrani načine dreves brez začetne ničle, git fsck --strict pa zavrne 040000.

Zapis potrditve

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

Ponastavitev

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

Obnovitev

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 in razveljavitev

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

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

Oba sprejmeta katero koli revizijo, ki jo sprejema resolve(). Polne zgoščene vrednosti delujejo; skrajšane ne.