Εγγραφή σε αποθετήρια
Το Pitmaster γράφει σε αποθετήρια git χρησιμοποιώντας τις ίδιες δυαδικές μορφές με το κανονικό δυαδικό αρχείο git. Τα αντικείμενα γράφονται στο χώρο αποθήκευσης loose αντικειμένων (συμπιεσμένα με zlib), το index γράφεται σε μορφή v2 (ή v3 όταν οι εγγραφές χρειάζονται εκτεταμένες σημαίες· ένα υπάρχον index διατηρεί την έκδοσή του) και τα refs γράφονται ως loose αρχεία. Τα δεδομένα που γράφονται μπορούν να επαληθευτούν με το git fsck --strict.
Αρχικοποίηση αποθετηρίου
use Pitmaster\Pitmaster;
$repo = Pitmaster::init('/path/to/new-project');
Αυτό δημιουργεί:
.git/objects/(κενό χώρο αποθήκευσης αντικειμένων).git/refs/heads/και.git/refs/tags/(κενούς καταλόγους ref).git/HEADπου περιέχειref: refs/heads/main.git/hooks/,.git/info/excludeκαι.git/description.git/configμε προεπιλεγμένες ρυθμίσεις
Περάστε το 'sha256' ως δεύτερο όρισμα για να δημιουργήσετε αποθετήριο SHA-256: Pitmaster::init($path, 'sha256').
Η προεπιλεγμένη διαμόρφωση δεν ορίζει το core.logallrefupdates, επομένως το Pitmaster δεν καταγράφει εγγραφές reflog σε αποθετήριο που δημιούργησε, μέχρι να ορίσετε αυτό το κλειδί σε true (#8). Τα αποθετήρια που δημιουργούνται από το git init το έχουν ήδη ορισμένο.
Σταδιοποίηση αρχείων
προσθήκη
$repo->add('src/Feature.php');
$repo->add('src/Feature.php', 'tests/FeatureTest.php', 'README.md');
Κάθε όρισμα είναι μια διαδρομή αρχείου σχετική με τη ρίζα του working tree. Οι κατάλογοι και τα glob δεν επεκτείνονται, ενώ αν λείπει κάποιο αρχείο προκαλείται RuntimeException. Για κάθε αρχείο, το Pitmaster:
- Διαβάζει το περιεχόμενο του αρχείου από το working tree
- Δημιουργεί ένα αντικείμενο
Blobκαι υπολογίζει το hash του - Γράφει το blob στο
.git/objects/(συμπιεσμένο με zlib) - Ενημερώνει την εγγραφή του index για αυτή τη διαδρομή με το νέο hash και τα μεταδεδομένα αρχείου
αφαίρεση
$repo->remove('old-file.txt');
$repo->remove('-r', 'src');
$repo->remove('--cached', 'old-file.txt');
Αφαιρεί παρακολουθούμενες διαδρομές από το index και το working tree. Χρησιμοποιήστε το --cached για αφαίρεση μόνο από το index ή τα -r / --recursive για παρακολουθούμενους καταλόγους.
μετακίνηση
$repo->mv('old-name.php', 'new-name.php');
Μετονομάζει το αρχείο στο working tree, αφαιρεί την παλιά εγγραφή από το index και προσθέτει τη νέα.
Δημιουργία commits
$commitId = $repo->commit('Fix null pointer bug');
echo $commitId->hex;
Η διαδικασία commit:
- Δημιουργία δέντρου από το index: η επίπεδη λίστα εγγραφών του index οργανώνεται σε ιεραρχία δέντρου (οι κατάλογοι γίνονται αντικείμενα tree, τα αρχεία γίνονται αναφορές blob). Κάθε tree γράφεται στον χώρο αποθήκευσης αντικειμένων.
- Καθορισμός γονέα: το τρέχον commit HEAD γίνεται ο γονέας. Τα commit ρίζας (το πρώτο commit σε ένα repo) δεν έχουν γονείς.
- Καθορισμός συντάκτη: λαμβάνεται από τις μεταβλητές περιβάλλοντος
PITMASTER_AUTHOR_*καιGIT_AUTHOR_*, έπειτα από τις σταθερέςPITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, στη συνέχεια από το.git/config(user.name/user.email) και τέλος από τοPitmaster <pitmaster@localhost>. Ο committer επιλύεται με τον ίδιο τρόπο. - Εγγραφή αντικειμένου commit: το περιεχόμενο του commit (
tree,parent,author,committer, μήνυμα) σειριοποιείται, κατακερματίζεται και γράφεται. - Ενημέρωση HEAD: το ref του branch στο οποίο δείχνει το HEAD ενημερώνεται με το νέο hash commit.
Τα hooks εκτελούνται γύρω από αυτά τα βήματα (pre-commit, prepare-commit-msg, commit-msg, post-commit), εκτός αν το handle ανοίχτηκε με ['hooks' => false]. Το commit() προκαλεί σφάλμα όταν λείπει το μήνυμα, όταν το δέντρο δεν έχει αλλάξει σε σχέση με το HEAD ή όταν το index περιέχει μη συγχωνευμένες διαδρομές.
Προσαρμοσμένος συντάκτης
$author = 'Jane Smith <jane@example.com> 1700000000 +0000';
$commitId = $repo->commit('Add feature', $author);
Επαλήθευση με git fsck
Η κάλυψη ενσωμάτωσης του Pitmaster ελέγχει τα αντικείμενα που γράφτηκαν έναντι του git fsck --strict, ενώ μπορείτε να κάνετε την ίδια επαλήθευση χειροκίνητα:
cd /path/to/repo
git fsck --strict
Αν το Pitmaster γράψει μη έγκυρο αντικείμενο, το git fsck θα αναφέρει αμέσως το σφάλμα.
Διαχείριση branches
Δημιουργία branch
// Branch from HEAD
$repo->createBranch('feature/new-thing');
// Branch from a specific commit
$repo->createBranch('hotfix', $repo->resolve('v1.0.0'));
Δημιουργεί ένα αρχείο ref στο .git/refs/heads/<name> που περιέχει το hash του commit-στόχου.
Διαγραφή branch
$repo->deleteBranch('feature/old');
Εναλλαγή branches
$repo->checkout('feature/login');
Ενημερώνει το HEAD ώστε να είναι συμβολικό ref που δείχνει στο branch, επαναφέρει το index ώστε να ταιριάζει με το δέντρο της κορυφής του branch και ενημερώνει το working tree.
Οι τοπικές αλλαγές σε διαδρομές που διαφέρουν ανάμεσα στα δύο δέντρα σταματούν το checkout με ένα RuntimeException. Οι μη δεσμευμένες αλλαγές σε όλα τα άλλα παρακολουθούμενα αρχεία αντικαθίστανται από το περιεχόμενο του branch, όπως θα τις διατηρούσε το git (#2). Κάντε commit ή stash τις αλλαγές πριν από την εναλλαγή.
Έλεγχος αν έχει γίνει merge
if ($repo->isBranchMerged('feature/done')) {
$repo->deleteBranch('feature/done');
}
Διαχείριση tags
Ελαφρύ tag
$repo->createLightweightTag('v1.0.0'); // At HEAD
$repo->createLightweightTag('v0.9.0', $repo->resolve('HEAD~5'));
Ένα ελαφρύ tag είναι απλώς ένα ref που δείχνει απευθείας σε ένα commit.
Σχολιασμένο tag
$tagId = $repo->createTag('v2.0.0', 'Release version 2.0.0');
Ένα σχολιασμένο tag δημιουργεί ένα αντικείμενο tag (με συντάκτη tag, μήνυμα και στόχο) και ένα ref που δείχνει σε αυτό. Ο συντάκτης tag είναι η ταυτότητα του τρέχοντος committer, η οποία επιλύεται όπως και ο συντάκτης του commit.
Προσαρμοσμένος συντάκτης tag
$tagId = $repo->createTag(
'v2.0.0',
'Release version 2.0.0',
$repo->resolve('HEAD'),
'Jane Smith <jane@example.com> 1700000000 +0000',
);
Άμεση ενημέρωση refs
$repo->updateRef('refs/heads/main', $commitId);
$repo->updateRef('refs/tags/latest', $commitId);
Άμεση εγγραφή αντικειμένων
Για προχωρημένες περιπτώσεις χρήσης, μπορείτε να γράψετε αντικείμενα χωρίς να χρησιμοποιήσετε το υψηλού επιπέδου API.
Εγγραφή blob
use Pitmaster\Object\Blob;
$blob = Blob::fromContent('Hello, world!');
$id = $repo->writeObject($blob);
echo $id->hex; // SHA-1 of "blob 13\0Hello, world!"
Σε αποθετήριο SHA-256, περάστε τον αλγόριθμο: Blob::fromContent('Hello, world!', 'sha256').
Εγγραφή tree
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() γράφει τις εγγραφές με τη σειρά που δίνονται και τις συμβολοσειρές mode όπως δίνονται. Περάστε τις με τη σειρά tree του git (κατά όνομα, με τους καταλόγους να συγκρίνονται σαν το όνομά τους να τελείωνε σε /) και γράψτε τα mode καταλόγων ως 40000: το git αποθηκεύει τα mode tree χωρίς το αρχικό μηδενικό, ενώ το git fsck --strict απορρίπτει το 040000.
Εγγραφή commit
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);
Επαναφορά
// 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');
Αποκατάσταση
// 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 και revert
// Apply a commit on the current branch
$newId = $repo->cherryPick('feature~1');
// Undo a commit
$revertId = $repo->revert('HEAD~2');
Και τα δύο δέχονται οποιοδήποτε revision αποδέχεται το resolve(). Τα πλήρη hash λειτουργούν· τα συντομευμένα όχι.