Treci la conținut

Stare

Pitmaster calculează starea arborelui de lucru comparând trei stări: arborele commitului HEAD, indexul (zona de pregătire) și arborele de lucru (fișierele efective de pe disc). CLI afișează pe această bază un rezumat în stilul git status, iar statusPorcelainV2() afișează formatul porcelain v2 al git.

Utilizare de bază

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

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

shortFormat() afișează formatul scurt al git:

Cod
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

Starea fiecărui fișier este reprezentată de un 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"

Enumerarea 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() nu raportează fișierele ignorate, așa că Ignored nu apare în rezultatul său.

Ieșire porcelain v2

Pentru o ieșire de stare lizibilă automat, care corespunde cu git status --porcelain=v2:

PHP
echo $repo->statusPorcelainV2();

Rezultat:

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

Intrările urmărite apar primele, apoi cele neurmărite. Redenumirile folosesc linii 2, iar conflictele, linii u. Antetele # branch din git status --porcelain=v2 --branch nu sunt afișate, iar fișierele ignorate nu sunt listate.

Cum se calculează starea

Clasa WorkingTreeStatus efectuează comparația în trei direcții:

PHP
use Pitmaster\Status\WorkingTreeStatus;

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

Pasul 1: Construirea hărții arborelui HEAD

Aplatizați arborele commitului HEAD într-o hartă de path => blob hash. Aceasta reprezintă ultima stare confirmată.

Pasul 2: Compararea HEAD cu indexul

Pentru fiecare fișier din arborele HEAD și din index:

  • În HEAD, dar nu și în index: Deleted în coloana indexului
  • În index, dar nu și în HEAD: Added în coloana indexului
  • În ambele, dar cu hashuri diferite: Modified în coloana indexului
  • În ambele, cu același hash: Unmodified în coloana indexului

Pasul 3: Compararea indexului cu arborele de lucru

Pentru fiecare fișier din index și din arborele de lucru:

  • În index, dar nu pe disc: Deleted în coloana arborelui de lucru
  • În ambele, dar cu conținut diferit: Modified în coloana arborelui de lucru
  • În ambele, cu conținut identic: Unmodified în coloana arborelui de lucru

Pasul 4: Detectarea fișierelor neurmărite

Parcurgeți directorul arborelui de lucru, omiteți .git/ și căile ignorate, apoi raportați ca Untracked în ambele coloane fișierele care nu sunt prezente în index.

Compatibilitate cu .gitignore

Pitmaster analizează fișierele .gitignore pentru a determina ce fișiere neurmărite trebuie raportate ca ignorate sau neurmărite.

PHP
use Pitmaster\Status\GitIgnore;

Clasa GitIgnore analizează modelele gitignore din:

  • .gitignore din directorul rădăcină al depozitului
  • .gitignore din subdirectoare
  • .git/info/exclude

Sintaxa modelelor acceptată:

  • Modele glob (*.log, build/)
  • Negare (!important.log)
  • Modele doar pentru directoare (/ la final)
  • / la început pentru modele relative la rădăcină
  • ** pentru potrivire recursivă

Clasificarea intrărilor de stare

Un model uzual de afișare pentru 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;
    }
}

Utilizarea CLI

Shell
./vendor/bin/pitmaster status

Rezultat:

Cod
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 include un ajutor pentru protocolul fsmonitor al git:

PHP
use Pitmaster\Status\Fsmonitor;

Clasa Fsmonitor poate interoga hookul core.fsmonitor (revenind la o scanare a timpilor de modificare) pentru a afla ce fișiere s-au schimbat de la un token. Se dezactivează pentru handle-urile deschise cu ['processes' => false]. status() nu îl apelează momentan; compară direct datele stat și conținutul.