Zápis do repozitárov
Pitmaster zapisuje repozitáre git pomocou rovnakých binárnych formátov ako kanonický binárny súbor git. Objekty sa zapisujú do úložiska voľných objektov (komprimované pomocou zlib), index sa zapisuje vo formáte v2 (alebo v3, ak položky potrebujú rozšírené príznaky; existujúci index si zachová svoju verziu) a odkazy sa zapisujú ako voľné súbory. Zapísané údaje možno overiť pomocou git fsck --strict.
Inicializácia repozitára
use Pitmaster\Pitmaster;
$repo = Pitmaster::init('/path/to/new-project');
Vytvorí sa:
.git/objects/(prázdne úložisko objektov).git/refs/heads/a.git/refs/tags/(prázdne adresáre odkazov).git/HEADobsahujúciref: refs/heads/main.git/hooks/,.git/info/excludea.git/description.git/configs predvolenými nastaveniami
Ak chcete vytvoriť repozitár SHA-256, odovzdajte 'sha256' ako druhý argument: Pitmaster::init($path, 'sha256').
Predvolená konfigurácia nenastavuje core.logallrefupdates, takže Pitmaster nezaznamenáva žiadne položky reflogu v repozitári, ktorý vytvorí, kým tento kľúč nenastavíte na true (#8). Repozitáre vytvorené pomocou git init ho už majú nastavený.
Zaraďovanie súborov do indexu
add
$repo->add('src/Feature.php');
$repo->add('src/Feature.php', 'tests/FeatureTest.php', 'README.md');
Každý argument je cesta k súboru relatívna ku koreňovému adresáru pracovného stromu. Adresáre a glob vzory sa nerozbaľujú a pri chýbajúcom súbore sa vyvolá RuntimeException. Pre každý súbor Pitmaster:
- Načíta obsah súboru z pracovného stromu
- Vytvorí objekt
Bloba vypočíta jeho hash - Zapíše blob do
.git/objects/(komprimovaný pomocou zlib) - Aktualizuje položku indexu pre danú cestu novým hashom a metadátami súboru
remove
$repo->remove('old-file.txt');
$repo->remove('-r', 'src');
$repo->remove('--cached', 'old-file.txt');
Odstráni sledované cesty z indexu a pracovného stromu. Na odstránenie iba z indexu použite --cached alebo pri sledovaných adresároch použite -r / --recursive.
mv
$repo->mv('old-name.php', 'new-name.php');
Premenuje súbor v pracovnom strome, odstráni starú položku indexu a pridá novú.
Vytváranie commitov
$commitId = $repo->commit('Fix null pointer bug');
echo $commitId->hex;
Postup vytvorenia commitu:
- Zostavenie stromu z indexu: plochý zoznam položiek indexu sa usporiada do hierarchie stromov (z adresárov sa stanú objekty stromu, súbory sú odkazy na bloby). Každý strom sa zapíše do úložiska objektov.
- Určenie rodiča: aktuálny commit HEAD sa stane rodičom. Koreňové commity (prvý commit v repozitári) nemajú rodičov.
- Určenie autora: údaje sa prevezmú z premenných prostredia
PITMASTER_AUTHOR_*aGIT_AUTHOR_*, potom z konštántPITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, ďalej z.git/config(user.name/user.email) a napokon zPitmaster <pitmaster@localhost>. Autor commitu sa určí rovnakým spôsobom. - Zápis objektu commitu: obsah commitu (
tree,parent,author,committer, správa) sa serializuje, zahashuje a zapíše. - Aktualizácia HEAD: odkaz vetvy, na ktorý ukazuje HEAD, sa aktualizuje novým hashom commitu.
Hooky sa spúšťajú pred týmito krokmi a po nich (pre-commit, prepare-commit-msg, commit-msg, post-commit), pokiaľ nebol handle otvorený pomocou ['hooks' => false]. commit() vyvolá chybu, ak chýba správa, strom sa nezmenil oproti HEAD alebo index obsahuje nezlúčené cesty.
Vlastný autor
$author = 'Jane Smith <jane@example.com> 1700000000 +0000';
$commitId = $repo->commit('Add feature', $author);
Overenie pomocou fsck nástroja git
Integračné testy nástroja Pitmaster overujú zapísané objekty pomocou git fsck --strict a rovnaké overenie môžete vykonať aj ručne:
cd /path/to/repo
git fsck --strict
Ak Pitmaster zapíše neplatný objekt, git fsck chybu okamžite nahlási.
Správa vetiev
Vytvorenie vetvy
// Branch from HEAD
$repo->createBranch('feature/new-thing');
// Branch from a specific commit
$repo->createBranch('hotfix', $repo->resolve('v1.0.0'));
Vytvorí súbor odkazu v .git/refs/heads/<name> obsahujúci hash cieľového commitu.
Odstránenie vetvy
$repo->deleteBranch('feature/old');
Prepnutie vetiev
$repo->checkout('feature/login');
Aktualizuje HEAD na symbolický odkaz ukazujúci na vetvu, resetuje index tak, aby zodpovedal špičke vetvy, a aktualizuje pracovný strom.
Lokálne zmeny na cestách, ktoré sa medzi týmito dvoma stromami líšia, zastavia checkout s chybou RuntimeException. Nepotvrdené zmeny vo všetkých ostatných sledovaných súboroch sa nahradia obsahom vetvy; git by ich zachoval (#2). Pred prepnutím ich commitnite alebo odložte.
Kontrola, či je zlúčená
if ($repo->isBranchMerged('feature/done')) {
$repo->deleteBranch('feature/done');
}
Správa tagov
Ľahký tag
$repo->createLightweightTag('v1.0.0'); // At HEAD
$repo->createLightweightTag('v0.9.0', $repo->resolve('HEAD~5'));
Ľahký tag je jednoducho odkaz smerujúci priamo na commit.
Anotovaný tag
$tagId = $repo->createTag('v2.0.0', 'Release version 2.0.0');
Anotovaný tag vytvorí objekt tagu (s autorom tagu, správou a cieľom) a odkaz, ktorý naň ukazuje. Autorom tagu je aktuálna identita autora commitu, určená rovnakým spôsobom ako autor commitu.
Vlastný autor tagu
$tagId = $repo->createTag(
'v2.0.0',
'Release version 2.0.0',
$repo->resolve('HEAD'),
'Jane Smith <jane@example.com> 1700000000 +0000',
);
Priama aktualizácia odkazov
$repo->updateRef('refs/heads/main', $commitId);
$repo->updateRef('refs/tags/latest', $commitId);
Priamy zápis objektov
V pokročilých prípadoch použitia môžete zapisovať objekty bez použitia vysokoúrovňového rozhrania API.
Zápis blobu
use Pitmaster\Object\Blob;
$blob = Blob::fromContent('Hello, world!');
$id = $repo->writeObject($blob);
echo $id->hex; // SHA-1 of "blob 13\0Hello, world!"
V repozitári SHA-256 odovzdajte algoritmus: Blob::fromContent('Hello, world!', 'sha256').
Zápis stromu
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() zapisuje položky v zadanom poradí a reťazce režimov tak, ako boli zadané. Odovzdajte ich v poradí stromu nástroja git (podľa názvu, pričom názvy adresárov sa porovnávajú, akoby sa končili znakom /) a režimy adresárov zapisujte ako 40000: git ukladá režimy stromov bez úvodnej nuly a git fsck --strict odmieta 040000.
Zápis commitu
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);
Reset
// 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');
Obnovenie
// 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 a vrátenie zmien
// Apply a commit on the current branch
$newId = $repo->cherryPick('feature~1');
// Undo a commit
$revertId = $repo->revert('HEAD~2');
Oba príkazy prijímajú ľubovoľnú revíziu, ktorú prijíma resolve(). Celé hashe fungujú; skrátené nie.