Lewati ke konten

Membaca Repositori

Pitmaster membaca repositori git dengan mengurai format di disk secara langsung: objek lepas (file terkompresi zlib di .git/objects/), file pack (.git/objects/pack/), ref (file di .git/refs/ dan packed-refs), serta index (.git/index).

Membuka repositori

PHP
use Pitmaster\Pitmaster;

$repo = Pitmaster::open('/path/to/project');

Pitmaster mendukung tiga tata letak repositori:

  1. Repositori reguler: .git adalah direktori di root proyek.
  2. Worktree tertaut: .git adalah file yang berisi gitdir: <path> yang menunjuk ke .git/worktrees/<name>/.
  3. Repositori bare: path itu sendiri berisi HEAD, objects/, dan seterusnya.
PHP
// Detection helpers
Pitmaster::isRepository('/path');  // true for any of the above
Pitmaster::isWorktree('/path');    // true only for linked worktrees

Membaca objek

Setiap data dalam repositori git disimpan sebagai objek yang diidentifikasi oleh hash-nya: SHA-1 (40 karakter heksadesimal) sebagai default, atau SHA-256 (64 karakter heksadesimal) di repositori yang dibuat dengan Pitmaster::init($path, 'sha256'). Ada empat jenis objek: blob, tree, commit, dan tag.

Metode berbasis hash di bawah ini menerima hash heksadesimal lengkap; hash singkat tidak diterima.

readObject

PHP
use Pitmaster\Object\Blob;
use Pitmaster\Object\Tree;
use Pitmaster\Object\Commit;
use Pitmaster\Object\Tag;

$object = $repo->readObject('a1b2c3d4e5f6...');

match (true) {
    $object instanceof Blob   => handleBlob($object),
    $object instanceof Tree   => handleTree($object),
    $object instanceof Commit => handleCommit($object),
    $object instanceof Tag    => handleTag($object),
};

Objek dicari terlebih dahulu di penyimpanan lepas, lalu di file pack. Pencarian file pack menggunakan tabel fanout .idx untuk pencarian biner O(log n).

catFile

Untuk mengambil konten secara sederhana tanpa pemeriksaan jenis:

PHP
$content = $repo->catFile('a1b2c3d4e5f6...');
echo $content;

objectExists

PHP
if ($repo->objectExists('a1b2c3d4e5f6...')) {
    // Object is in the repository
}

listObjects

PHP
$hashes = $repo->listObjects();
// ['a1b2c3d4...', 'f6e5d4c3...', ...]

Mengembalikan hash heksadesimal untuk semua objek (lepas dan yang dikemas).

Bekerja dengan blob

Blob menyimpan konten file mentah.

PHP
$blob = $repo->readObject($hash);
echo $blob->content;     // Raw file bytes
echo $blob->size();      // Content length
echo $blob->id->hex;     // Object hash

Bekerja dengan tree

Tree adalah daftar direktori. Setiap entri memiliki mode, nama, dan hash.

PHP
$tree = $repo->readObject($hash);

foreach ($tree->entries as $entry) {
    echo "{$entry->mode} {$entry->name} {$entry->hash->hex}\n";
    // 100644 README.md abc123...
    // 40000 src def456...
    // 100755 deploy.sh 789012...

    if ($entry->isTree()) {
        // Recurse into subdirectory (mode 40000)
    } elseif ($entry->isExecutable()) {
        // Executable file (mode 100755)
    } elseif ($entry->isBlob()) {
        // Regular file (any 10xxxx mode, so executables match too)
    } elseif ($entry->isSymlink()) {
        // Symbolic link (mode 120000)
    } elseif ($entry->isGitlink()) {
        // Submodule (mode 160000)
    }
}

Bekerja dengan commit

Commit menghubungkan snapshot tree dengan induk dan metadatanya.

PHP
$commit = $repo->head();

echo $commit->id->hex;      // Full object hash
echo $commit->tree->hex;    // Tree object hash
echo $commit->author;       // "Name <email> timestamp tz"
echo $commit->committer;    // "Name <email> timestamp tz"
echo $commit->message;      // Full commit message

// Parent commits
foreach ($commit->parents as $parentId) {
    $parent = $repo->readObject($parentId->hex);
}

// Merge detection
if ($commit->isMerge()) {
    // Two or more parents
}

Bekerja dengan tag

Tag beranotasi adalah objek yang berisi target, jenis, nama, pembuat tag, dan pesan.

PHP
$tag = $repo->readObject($hash);

echo $tag->object->hex;           // Target object hash
echo $tag->objectType->value;     // 'commit', 'tree', 'blob', or 'tag'
echo $tag->name;            // Tag name
echo $tag->tagger;          // "Name <email> timestamp tz"
echo $tag->message;         // Tag message

Membaca ref

HEAD saat ini

PHP
$commit = $repo->head();

Menyelesaikan HEAD (dengan mengikuti ref simbolis seperti HEAD -> refs/heads/main -> commit hash) dan mengembalikan objek commit.

Branch saat ini

PHP
$branch = $repo->branch();  // 'main' or null if detached

Mencantumkan branch dan tag

PHP
$branches = $repo->branches();  // ['bugfix/typo', 'feature/login', 'main']
$tags = $repo->tags();          // ['v1.0.0', 'v1.1.0']

Semua ref

PHP
$refs = $repo->allRefs();
// [
//     'refs/heads/main' => 'abc123...',
//     'refs/heads/feature' => 'def456...',
//     'refs/tags/v1.0.0' => '789012...',
//     'refs/remotes/origin/main' => 'abc123...',
// ]

Menyelesaikan revisi

PHP
$id = $repo->resolve('HEAD');
$id = $repo->resolve('main');
$id = $repo->resolve('v1.0.0');
$id = $repo->resolve('HEAD~3');
$id = $repo->resolve('main^2');
$id = $repo->resolve('3f2c1e0b9d6a4f8e7c5b2a1d0e9f8c7b6a5d4e3f');

Parser revisi mendukung operator ~N (leluhur) dan ^N (induk), yang dapat dirangkai tanpa batas. Hash harus diberikan secara lengkap.

Menelusuri riwayat commit

log

Commit dikembalikan dari yang terbaru terlebih dahulu, diurutkan berdasarkan stempel waktu committer.

PHP
// Last 20 commits from HEAD
$commits = $repo->log(20);

foreach ($commits as $commit) {
    $short = substr($commit->id->hex, 0, 7);
    echo "{$short} {$commit->message}\n";
}

log dari commit tertentu

PHP
$from = $repo->resolve('feature/login');
$commits = $repo->log(10, $from);

log yang difilter berdasarkan path file

PHP
$commits = $repo->logPath('src/Repository.php', 20);

Hanya mengembalikan commit yang mengubah file yang ditentukan (ditambahkan, diubah, dihapus, atau diganti namanya) dibandingkan dengan induk pertama. Path harus berupa path file yang persis; direktori tidak cocok. Hanya 5 * $limit commit terbaru yang diperiksa, sehingga kecocokan yang lebih lama mungkin tidak ditemukan (#7).

show

PHP
$result = $repo->show('HEAD');
$commit = $result['commit'];
$diffs = $result['diff'];

echo "Author: {$commit->author}\n";
echo "Message: {$commit->message}\n\n";

foreach ($diffs as $diff) {
    echo $diff->format();
}

Deteksi branch default

PHP
$default = $repo->defaultBranch();
// Checks: remote HEAD symref -> local HEAD -> main/master fallback

Saat remote.origin.url ditetapkan dan proses diaktifkan, pemeriksaan pertama mengirim permintaan HTTP yang cerdas ke remote. Kesalahan jaringan diabaikan dan pemeriksaan lokal dilanjutkan.

Ancestry penggabungan

PHP
// Is feature fully merged into main?
$merged = $repo->isBranchMerged('feature/done', 'main');

// Find the merge base of two commits
$base = $repo->mergeBase(
    $repo->resolve('main'),
    $repo->resolve('feature/login'),
);