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
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 vsebujeref: refs/heads/main.git/hooks/,.git/info/excludein.git/description.git/configs 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
$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:
- Prebere vsebino datoteke iz delovnega drevesa
- Ustvari objekt
Blobin izračuna njegovo zgoščeno vrednost - Zapiše blob v
.git/objects/(stisnjen z zlib) - Posodobi vnos v indeksu za to pot z novo zgoščeno vrednostjo in metapodatki datoteke
remove
$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
$repo->mv('old-name.php', 'new-name.php');
Preimenuje datoteko v delovnem drevesu, odstrani stari vnos iz indeksa in doda novega.
Ustvarjanje potrditev
$commitId = $repo->commit('Fix null pointer bug');
echo $commitId->hex;
Postopek potrditve:
- 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.
- Določitev nadrejenega elementa: trenutna potrditev HEAD postane nadrejeni element. Korenske potrditve (prva potrditev v repozitoriju) nimajo nadrejenih elementov.
- Določitev avtorja: vzame se iz spremenljivk okolja
PITMASTER_AUTHOR_*inGIT_AUTHOR_*, nato iz konstantPITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, nato iz.git/config(user.name/user.email), nazadnje pa izPitmaster <pitmaster@localhost>. Potrditelj se določi na enak način. - Zapis objekta potrditve: vsebina potrditve (
tree,parent,author,committer, sporočilo) se serializira, zgosti in zapiše. - 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
$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:
cd /path/to/repo
git fsck --strict
Če Pitmaster zapiše neveljaven objekt, git fsck napako takoj prikaže.
Upravljanje vej
Ustvarjanje veje
// 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
$repo->deleteBranch('feature/old');
Preklapljanje med vejami
$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
if ($repo->isBranchMerged('feature/done')) {
$repo->deleteBranch('feature/done');
}
Upravljanje oznak
Lahka oznaka
$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
$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
$tagId = $repo->createTag(
'v2.0.0',
'Release version 2.0.0',
$repo->resolve('HEAD'),
'Jane Smith <jane@example.com> 1700000000 +0000',
);
Neposredno posodabljanje sklicev
$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
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
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
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
// 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
// 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
// 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.