Lewati ke konten

Status

Pitmaster menghitung status working tree dengan membandingkan tiga keadaan: tree dari commit HEAD, index (area staging), dan working tree (file aktual di disk). CLI mencetak ringkasan bergaya git status darinya, sedangkan statusPorcelainV2() mencetak format porcelain v2 milik git.

Penggunaan dasar

PHP
$entries = $repo->status();

foreach ($entries as $entry) {
    echo $entry->shortFormat() . "\n";
}

shortFormat() mencetak format singkat milik git:

Kode
M  src/Modified.php          (staged modification)
 M src/WorktreeModified.php  (unstaged modification)
A  src/NewFile.php           (staged new file)
 D src/Deleted.php           (deleted in worktree)
?? untracked.txt             (untracked file)

StatusEntry

Status setiap file ditampilkan dengan StatusEntry:

PHP
use Pitmaster\Status\StatusEntry;

$entry->path;       // File path relative to repo root
$entry->index;      // FileStatus: HEAD-to-index state
$entry->worktree;   // FileStatus: index-to-worktree state
$entry->origPath;   // Original path for renamed entries, otherwise null
$entry->renameScore; // Similarity score for renamed entries, otherwise null
$entry->shortFormat(); // "XY path", "?? path", or "R  old -> new"

Enum FileStatus

PHP
use Pitmaster\Status\FileStatus;

FileStatus::Added;      // 'A' - new file
FileStatus::Modified;   // 'M' - content changed
FileStatus::Deleted;    // 'D' - file removed
FileStatus::Renamed;    // 'R' - file renamed
FileStatus::Copied;     // 'C' - file copied
FileStatus::Unmerged;   // 'U' - unresolved merge conflict
FileStatus::Untracked;  // '?' - not in index
FileStatus::Ignored;    // '!' - matched by .gitignore
FileStatus::Unmodified; // ' ' - no change

status() tidak melaporkan file yang diabaikan, jadi Ignored tidak muncul dalam hasilnya.

Output Porcelain v2

Untuk output status yang dapat dibaca mesin dan sesuai dengan git status --porcelain=v2:

PHP
echo $repo->statusPorcelainV2();

Keluaran:

Kode
1 .M N... 100644 100644 100644 ce013625030ba8dba906f756967f9e9ca394464a ce013625030ba8dba906f756967f9e9ca394464a modified-file.txt
? untracked-file.txt

Entri yang dilacak ditampilkan lebih dahulu, lalu entri yang tidak dilacak. Penggantian nama menggunakan baris 2 dan konflik menggunakan baris u. Header # branch dari git status --porcelain=v2 --branch tidak dicetak, dan file yang diabaikan tidak dicantumkan.

Cara status dihitung

Kelas WorkingTreeStatus melakukan perbandingan tiga arah:

PHP
use Pitmaster\Status\WorkingTreeStatus;

$status = new WorkingTreeStatus($repo->objectDatabase(), $repo->workDir(), $repo->gitDir());
$entries = $status->compute($repo->index(), $repo->resolve('HEAD'));

Langkah 1: Buat peta tree HEAD

Ratakan tree dari commit HEAD menjadi peta path => blob hash. Ini mewakili keadaan commit terakhir.

Langkah 2: Bandingkan HEAD dengan index

Untuk setiap file di tree HEAD dan index:

  • Ada di HEAD tetapi tidak di index: Deleted di kolom index
  • Ada di index tetapi tidak di HEAD: Added di kolom index
  • Ada di keduanya tetapi hash berbeda: Modified di kolom index
  • Ada di keduanya dengan hash yang sama: Unmodified di kolom index

Langkah 3: Bandingkan index dengan worktree

Untuk setiap file di index dan working tree:

  • Ada di index tetapi tidak di disk: Deleted di kolom worktree
  • Ada di keduanya tetapi kontennya berbeda: Modified di kolom worktree
  • Ada di keduanya dengan konten yang sama: Unmodified di kolom worktree

Langkah 4: Deteksi file yang tidak dilacak

Telusuri direktori working tree, lewati .git/ dan path yang diabaikan, lalu laporkan file yang tidak ada di index sebagai Untracked di kedua kolom.

Dukungan .gitignore

Pitmaster mengurai file .gitignore untuk menentukan file yang tidak dilacak mana yang harus dilaporkan sebagai diabaikan atau tidak dilacak.

PHP
use Pitmaster\Status\GitIgnore;

Kelas GitIgnore mengurai pola gitignore dari:

  • .gitignore di root repositori
  • .gitignore di subdirektori
  • .git/info/exclude

Sintaks pola yang didukung:

  • Pola glob (*.log, build/)
  • Negasi (!important.log)
  • Pola khusus direktori (/ di akhir)
  • / di awal untuk pola yang relatif terhadap root
  • ** untuk pencocokan rekursif

Mengategorikan entri status

Pola umum untuk menampilkan UI:

PHP
$staged = [];
$unstaged = [];
$untracked = [];

foreach ($repo->status() as $entry) {
    if ($entry->index === FileStatus::Untracked) {
        $untracked[] = $entry;
    } elseif ($entry->index !== FileStatus::Unmodified) {
        $staged[] = $entry;
    }

    if ($entry->worktree !== FileStatus::Unmodified
        && $entry->index !== FileStatus::Untracked
    ) {
        $unstaged[] = $entry;
    }
}

Penggunaan CLI

Shell
./vendor/bin/pitmaster status

Keluaran:

Kode
On branch main

Changes to be committed:
	new file:   src/Feature.php

Changes not staged for commit:
	modified:   src/Existing.php

Untracked files:
	notes.txt

Fsmonitor

Pitmaster menyertakan helper untuk protokol fsmonitor milik git:

PHP
use Pitmaster\Status\Fsmonitor;

Kelas Fsmonitor dapat meminta informasi dari hook core.fsmonitor (dengan pemindaian waktu modifikasi sebagai fallback) untuk mengetahui file yang berubah sejak suatu token. Fitur ini dinonaktifkan pada handle yang dibuka dengan ['processes' => false]. status() saat ini tidak memanggilnya; kelas tersebut membandingkan data stat dan konten secara langsung.