Menulis ke Repositori
Pitmaster menulis repositori git menggunakan format biner yang sama dengan biner git kanonis. Objek ditulis ke penyimpanan objek lepas (terkompresi zlib), index ditulis dalam format v2 (atau v3 jika entri memerlukan flag tambahan; index yang sudah ada mempertahankan versinya), dan ref ditulis sebagai file lepas. Data yang ditulis dapat diverifikasi dengan git fsck --strict.
Menginisialisasi repositori
use Pitmaster\Pitmaster;
$repo = Pitmaster::init('/path/to/new-project');
Ini membuat:
.git/objects/(penyimpanan objek kosong).git/refs/heads/dan.git/refs/tags/(direktori ref kosong).git/HEADyang berisiref: refs/heads/main.git/hooks/,.git/info/exclude, dan.git/description.git/configdengan pengaturan default
Berikan 'sha256' sebagai argumen kedua untuk membuat repositori SHA-256: Pitmaster::init($path, 'sha256').
Konfigurasi default tidak menetapkan core.logallrefupdates, sehingga Pitmaster tidak mencatat entri reflog di repositori yang dibuatnya sampai Anda menetapkan kunci tersebut ke true (#8). Repositori yang dibuat oleh git init sudah menetapkannya.
Memasukkan file ke staging
add
$repo->add('src/Feature.php');
$repo->add('src/Feature.php', 'tests/FeatureTest.php', 'README.md');
Setiap argumen adalah path file yang relatif terhadap root working tree. Direktori dan pola glob tidak diperluas, dan file yang tidak ditemukan akan menimbulkan RuntimeException. Untuk setiap file, Pitmaster:
- Membaca konten file dari working tree
- Membuat objek
Blobdan menghitung hash-nya - Menulis blob ke
.git/objects/(terkompresi zlib) - Memperbarui entri index untuk path tersebut dengan hash dan metadata file yang baru
remove
$repo->remove('old-file.txt');
$repo->remove('-r', 'src');
$repo->remove('--cached', 'old-file.txt');
Menghapus path yang dilacak dari index dan working tree. Gunakan --cached untuk menghapus dari index saja, atau -r / --recursive untuk direktori yang dilacak.
mv
$repo->mv('old-name.php', 'new-name.php');
Mengganti nama file di working tree, menghapus entri index lama, lalu menambahkan entri baru.
Membuat commit
$commitId = $repo->commit('Fix null pointer bug');
echo $commitId->hex;
Proses commit:
- Bangun tree dari index: daftar datar entri index disusun menjadi hierarki tree (direktori menjadi objek tree, file menjadi referensi blob). Setiap tree ditulis ke penyimpanan objek.
- Tentukan induk: commit HEAD saat ini menjadi induknya. Commit root (commit pertama di repo) tidak memiliki induk.
- Tentukan author: diambil dari variabel lingkungan
PITMASTER_AUTHOR_*danGIT_AUTHOR_*, lalu konstantaPITMASTER_AUTHOR_NAME/PITMASTER_AUTHOR_EMAIL, kemudian.git/config(user.name/user.email), laluPitmaster <pitmaster@localhost>. Identitas committer ditentukan dengan cara yang sama. - Tulis objek commit: konten commit (
tree,parent,author,committer, pesan) diserialisasi, di-hash, lalu ditulis. - Perbarui HEAD: ref branch yang ditunjuk HEAD diperbarui ke hash commit baru.
Hook dijalankan di sekitar langkah-langkah ini (pre-commit, prepare-commit-msg, commit-msg, post-commit), kecuali jika handle dibuka dengan ['hooks' => false]. commit() menimbulkan error jika pesan tidak ada, tree tidak berubah dari HEAD, atau index memiliki path yang belum digabung.
Author khusus
$author = 'Jane Smith <jane@example.com> 1700000000 +0000';
$commitId = $repo->commit('Add feature', $author);
Memverifikasi dengan git fsck
Cakupan integrasi Pitmaster memeriksa objek yang ditulis dengan git fsck --strict, dan Anda dapat memverifikasi hal yang sama secara manual:
cd /path/to/repo
git fsck --strict
Jika Pitmaster menulis objek yang tidak valid, git fsck akan segera melaporkan kesalahan tersebut.
Mengelola branch
Membuat branch
// Branch from HEAD
$repo->createBranch('feature/new-thing');
// Branch from a specific commit
$repo->createBranch('hotfix', $repo->resolve('v1.0.0'));
Membuat file ref di .git/refs/heads/<name> yang berisi hash commit target.
Menghapus branch
$repo->deleteBranch('feature/old');
Beralih branch
$repo->checkout('feature/login');
Memperbarui HEAD menjadi ref simbolis yang menunjuk ke branch, mengatur ulang index agar sesuai dengan tree ujung branch, lalu memperbarui working tree.
Perubahan lokal pada path yang berbeda di antara kedua tree akan menghentikan checkout dengan RuntimeException. Perubahan yang belum di-commit pada file terlacak lainnya akan diganti dengan konten branch jika git akan mempertahankannya (#2). Commit atau stash perubahan tersebut sebelum beralih.
Memeriksa apakah sudah digabung
if ($repo->isBranchMerged('feature/done')) {
$repo->deleteBranch('feature/done');
}
Mengelola tag
Tag ringan
$repo->createLightweightTag('v1.0.0'); // At HEAD
$repo->createLightweightTag('v0.9.0', $repo->resolve('HEAD~5'));
Tag ringan hanyalah ref yang langsung menunjuk ke commit.
Tag beranotasi
$tagId = $repo->createTag('v2.0.0', 'Release version 2.0.0');
Tag beranotasi membuat objek tag (dengan pembuat tag, pesan, dan target) serta ref yang menunjuk ke objek itu. Pembuat tag adalah identitas committer saat ini, yang ditentukan seperti author commit.
Pembuat tag khusus
$tagId = $repo->createTag(
'v2.0.0',
'Release version 2.0.0',
$repo->resolve('HEAD'),
'Jane Smith <jane@example.com> 1700000000 +0000',
);
Memperbarui ref secara langsung
$repo->updateRef('refs/heads/main', $commitId);
$repo->updateRef('refs/tags/latest', $commitId);
Menulis objek secara langsung
Untuk kasus penggunaan lanjutan, Anda dapat menulis objek tanpa melalui API tingkat tinggi.
Menulis blob
use Pitmaster\Object\Blob;
$blob = Blob::fromContent('Hello, world!');
$id = $repo->writeObject($blob);
echo $id->hex; // SHA-1 of "blob 13\0Hello, world!"
Dalam repositori SHA-256, jalankan algoritmanya: Blob::fromContent('Hello, world!', 'sha256').
Menulis 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() menulis entri sesuai urutan yang diberikan dan string mode persis seperti yang diberikan. Berikan entri dalam urutan tree git (berdasarkan nama, dengan direktori dibandingkan seolah namanya diakhiri /) dan tulis mode direktori sebagai 40000: git menyimpan mode tree tanpa nol di depan, dan git fsck --strict menolak 040000.
Menulis 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);
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');
Restore
// 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 dan revert
// Apply a commit on the current branch
$newId = $repo->cherryPick('feature~1');
// Undo a commit
$revertId = $repo->revert('HEAD~2');
Keduanya menerima revisi apa pun yang diterima resolve(). Hash lengkap dapat digunakan; hash singkat tidak.