Tárolók írása
Az Pitmaster ugyanazokkal a bináris formátumokkal írja a git-adattárakat, mint a kanonikus git bináris. Az objektumokat a lazaobjektum-tárolóba írja (zlib-tömörítéssel), az indexet pedig v2 formátumban (vagy v3 formátumban, ha a bejegyzéseknek kiterjesztett jelzőkre van szükségük; a meglévő index megtartja a verzióját), a hivatkozásokat pedig különálló fájlokként. Az írt adatok a git fsck --strict segítségével ellenőrizhetők.
Tároló inicializálása
use Pitmaster\Pitmaster;
$repo = Pitmaster::init('/path/to/new-project');
Ez hozza létre a következőket:
.git/objects/(üres objektumtároló).git/refs/heads/és.git/refs/tags/(üres hivatkozáskönyvtárak).git/HEAD, amely azref: refs/heads/mainértéket tartalmazza.git/hooks/,.git/info/excludeés.git/description.git/configalapértelmezett beállításokkal
Adja meg az 'sha256' értéket második argumentumként egy SHA-256 tároló létrehozásához: Pitmaster::init($path, 'sha256').
Az alapértelmezett konfiguráció nem állítja be az core.logallrefupdates értéket, ezért az Pitmaster nem rögzít reflog-bejegyzéseket az általa létrehozott tárolókban, amíg ezt a kulcsot true értékre nem állítja (#8). Az git init által létrehozott tárolókban ez már be van állítva.
Fájlok előkészítése
add
$repo->add('src/Feature.php');
$repo->add('src/Feature.php', 'tests/FeatureTest.php', 'README.md');
Minden argumentum a munkafa gyökérkönyvtárához viszonyított fájlútvonal. A könyvtárakat és globmintákat nem bontja ki, hiányzó fájl esetén pedig RuntimeException hibát dob. Minden fájlnál az Pitmaster:
- Beolvassa a fájl tartalmát a munkafából
Blobobjektumot hoz létre, és kiszámítja a hashét- A blobot az
.git/objects/helyre írja (zlibbel tömörítve) - Frissíti az adott útvonal indexbejegyzését az új hash-sel és fájlmetaadatokkal
remove
$repo->remove('old-file.txt');
$repo->remove('-r', 'src');
$repo->remove('--cached', 'old-file.txt');
Eltávolítja a követett útvonalakat az indexből és a munkafából. Az indexből történő eltávolításhoz használja az --cached értéket; követett könyvtárakhoz pedig az -r / --recursive értéket.
mv
$repo->mv('old-name.php', 'new-name.php');
Átnevezi a fájlt a munkafában, eltávolítja a régi indexbejegyzést, és hozzáadja az újat.
Commitok létrehozása
$commitId = $repo->commit('Fix null pointer bug');
echo $commitId->hex;
A commit létrehozásának folyamata:
- Fa felépítése az indexből: az indexbejegyzések lapos listáját fastruktúrába rendezi (a könyvtárak faobjektumokká, a fájlok pedig blobhivatkozásokká válnak). Minden fa bekerül az objektumtárolóba.
- Szülő meghatározása: az aktuális HEAD commit lesz a szülő. A gyökércommitoknak (a tároló első commitjainak) nincs szülőjük.
- Szerző meghatározása: az
PITMASTER_AUTHOR_*ésGIT_AUTHOR_*környezeti változók, majd azPITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAILkonstansok, aztán az.git/config(user.name/user.email), végül azPitmaster <pitmaster@localhost>alapján. A commitoló feloldása ugyanígy történik. - Commitobjektum írása: a commit tartalmát (
tree,parent,author,committerés az üzenet) szerializálja, hash-eli, majd kiírja. - HEAD frissítése: frissíti azt az ág-hivatkozást az új commit hashére, amelyre a HEAD mutat.
A hookok e lépések előtt és után futnak (pre-commit, prepare-commit-msg, commit-msg, post-commit), kivéve, ha a fogantyút ['hooks' => false] értékkel nyitották meg. Az commit() hibát dob, ha hiányzik az üzenet, ha a fa nem változott a HEAD-hez képest, vagy ha az indexben fel nem oldott útvonalak vannak.
Egyéni szerző
$author = 'Jane Smith <jane@example.com> 1700000000 +0000';
$commitId = $repo->commit('Add feature', $author);
Ellenőrzés a git fsck segítségével
Az Pitmaster integrációs tesztjei az git fsck --strict segítségével ellenőrzik a kiírt objektumokat; ugyanezt manuálisan is megteheti:
cd /path/to/repo
git fsck --strict
Ha az Pitmaster érvénytelen objektumot ír, az git fsck azonnal jelzi a hibát.
Ágak kezelése
Ág létrehozása
// Branch from HEAD
$repo->createBranch('feature/new-thing');
// Branch from a specific commit
$repo->createBranch('hotfix', $repo->resolve('v1.0.0'));
Létrehoz egy hivatkozásfájlt az .git/refs/heads/<name> helyen, amely a cél commit hashét tartalmazza.
Ág törlése
$repo->deleteBranch('feature/old');
Ágak közötti váltás
$repo->checkout('feature/login');
A HEAD-et az ágra mutató szimbolikus hivatkozásra állítja, visszaállítja az indexet az ág csúcsának fájára, és frissíti a munkafát.
Azokban az útvonalakban lévő helyi módosítások, amelyek eltérnek a két fa között, RuntimeException hibával leállítják a váltást. Minden más követett fájl nem véglegesített módosításait az ág tartalma váltja fel, amelyeket a Git megtartana (#2). Váltás előtt véglegesítse vagy tegye félre a módosításokat.
Ellenőrzés, hogy egyesült-e
if ($repo->isBranchMerged('feature/done')) {
$repo->deleteBranch('feature/done');
}
Címkék kezelése
Könnyűsúlyú címke
$repo->createLightweightTag('v1.0.0'); // At HEAD
$repo->createLightweightTag('v0.9.0', $repo->resolve('HEAD~5'));
A könnyűsúlyú címke egyszerűen egy közvetlenül egy commitra mutató hivatkozás.
Megjegyzéssel ellátott címke
$tagId = $repo->createTag('v2.0.0', 'Release version 2.0.0');
A megjegyzéssel ellátott címke létrehoz egy címkeobjektumot (címkézővel, üzenettel és céllal), valamint egy rá mutató hivatkozást. A címkéző az aktuális commitoló személyazonossága, amelyet a commit szerzőjével azonos módon old fel.
Egyéni címkéző
$tagId = $repo->createTag(
'v2.0.0',
'Release version 2.0.0',
$repo->resolve('HEAD'),
'Jane Smith <jane@example.com> 1700000000 +0000',
);
Hivatkozások közvetlen frissítése
$repo->updateRef('refs/heads/main', $commitId);
$repo->updateRef('refs/tags/latest', $commitId);
Objektumok közvetlen írása
Speciális felhasználási esetekben objektumokat a magas szintű API megkerülésével is írhat.
Blob írása
use Pitmaster\Object\Blob;
$blob = Blob::fromContent('Hello, world!');
$id = $repo->writeObject($blob);
echo $id->hex; // SHA-1 of "blob 13\0Hello, world!"
Egy SHA-256 tárolóban add át az algoritmust: Blob::fromContent('Hello, world!', 'sha256').
Fa írása
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);
Az Tree::fromEntries() a megadott sorrendben írja ki a bejegyzéseket, és változtatás nélkül hagyja a megadott módkarakterláncokat. Adja meg őket az git fája szerinti sorrendben (név szerint rendezve, a könyvtárakat úgy kezelve, mintha a nevük / karakterrel végződne), a könyvtárak módját pedig 40000 formában írja meg: az git a kezdő nulla nélküli fa módokat tárolja, az git fsck --strict pedig elutasítja az 040000-t.
Commit írása
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);
Visszaállítás alaphelyzetbe
// 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');
Visszaállítás
// 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 és visszavonás
// Apply a commit on the current branch
$newId = $repo->cherryPick('feature~1');
// Undo a commit
$revertId = $repo->revert('HEAD~2');
Mindkettő bármilyen, a resolve() által elfogadott revíziót kezel. A teljes hash-ek működnek, a rövidített hash-ek nem.