Preskočiť na obsah

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

PHP
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/HEAD obsahujúci ref: refs/heads/main
  • .git/hooks/, .git/info/exclude a .git/description
  • .git/config s 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

PHP
$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:

  1. Načíta obsah súboru z pracovného stromu
  2. Vytvorí objekt Blob a vypočíta jeho hash
  3. Zapíše blob do .git/objects/ (komprimovaný pomocou zlib)
  4. Aktualizuje položku indexu pre danú cestu novým hashom a metadátami súboru

remove

PHP
$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

PHP
$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

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

Postup vytvorenia commitu:

  1. 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.
  2. Určenie rodiča: aktuálny commit HEAD sa stane rodičom. Koreňové commity (prvý commit v repozitári) nemajú rodičov.
  3. Určenie autora: údaje sa prevezmú z premenných prostredia PITMASTER_AUTHOR_* a GIT_AUTHOR_*, potom z konštánt PITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, ďalej z .git/config (user.name/user.email) a napokon z Pitmaster <pitmaster@localhost>. Autor commitu sa určí rovnakým spôsobom.
  4. Zápis objektu commitu: obsah commitu (tree, parent, author, committer, správa) sa serializuje, zahashuje a zapíše.
  5. 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

PHP
$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:

Shell
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

PHP
// 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

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

Prepnutie vetiev

PHP
$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á

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

Správa tagov

Ľahký tag

PHP
$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

PHP
$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

PHP
$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

PHP
$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

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 repozitári SHA-256 odovzdajte algoritmus: Blob::fromContent('Hello, world!', 'sha256').

Zápis stromu

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

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

Reset

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

Obnovenie

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 a vrátenie zmien

PHP
// 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.