Ga naar de inhoud

Status

Pitmaster berekent de status van de werkboom door drie toestanden te vergelijken: de tree van de HEAD-commit, de index (staginggebied) en de werkboom (de bestanden op schijf). CLI toont hiervan een samenvatting in git status-stijl en statusPorcelainV2() toont de porcelain-v2-indeling van git.

Eenvoudig gebruik

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

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

shortFormat() toont de korte indeling van git:

Code
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

De status van elk bestand wordt weergegeven met een 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"

FileStatus-enum

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() rapporteert geen genegeerde bestanden, dus Ignored komt niet voor in het resultaat.

Uitvoer van porcelain-v2

Voor machineleesbare statusuitvoer die overeenkomt met git status --porcelain=v2:

PHP
echo $repo->statusPorcelainV2();

Uitvoer:

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

Bijgehouden items komen eerst, gevolgd door niet-bijgehouden items. Bij hernoemingen worden 2-regels gebruikt en bij conflicten u-regels. De # branch-koppen van git status --porcelain=v2 --branch worden niet weergegeven en genegeerde bestanden worden niet vermeld.

Hoe de status wordt berekend

De klasse WorkingTreeStatus voert de vergelijking tussen de drie toestanden uit:

PHP
use Pitmaster\Status\WorkingTreeStatus;

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

Stap 1: Bouw een HEAD-treemap

Vlak de tree van de HEAD-commit af tot een map met path => blob hash. Dit geeft de laatst vastgelegde toestand weer.

Stap 2: Vergelijk HEAD met de index

Voor elk bestand in de HEAD-tree en de index:

  • In HEAD maar niet in de index: Deleted in de indexkolom
  • In de index maar niet in HEAD: Added in de indexkolom
  • In beide, maar met een andere hash: Modified in de indexkolom
  • In beide, met dezelfde hash: Unmodified in de indexkolom

Stap 3: Vergelijk de index met de werkboom

Voor elk bestand in de index en de werkboom:

  • In de index maar niet op schijf: Deleted in de werkboomkolom
  • In beide, maar met verschillende inhoud: Modified in de werkboomkolom
  • In beide, met overeenkomende inhoud: Unmodified in de werkboomkolom

Stap 4: Detecteer niet-bijgehouden bestanden

Doorloop de werkboommap, sla .git/ en genegeerde paden over en rapporteer bestanden die niet in de index staan als Untracked in beide kolommen.

Ondersteuning voor .gitignore

Pitmaster verwerkt .gitignore-bestanden om te bepalen welke niet-bijgehouden bestanden als genegeerd of niet-bijgehouden moeten worden gerapporteerd.

PHP
use Pitmaster\Status\GitIgnore;

De klasse GitIgnore verwerkt gitignore-patronen uit:

  • .gitignore in de repositoryroot
  • .gitignore in submappen
  • .git/info/exclude

Ondersteunde patroonsyntaxis:

  • Globpatronen (*.log, build/)
  • Negatie (!important.log)
  • Patronen die alleen voor mappen gelden (afsluitende /)
  • Voorafgaande / voor patronen relatief aan de root
  • ** voor recursieve overeenkomst

Statusitems categoriseren

Een gebruikelijk patroon voor de weergave van 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;
    }
}

Gebruik van CLI

Shell
./vendor/bin/pitmaster status

Uitvoer:

Code
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 bevat een helper voor het fsmonitor-protocol van git:

PHP
use Pitmaster\Status\Fsmonitor;

De klasse Fsmonitor kan de hook core.fsmonitor opvragen (met een controle op wijzigingstijd als terugvaloptie) om te achterhalen welke bestanden sinds een token zijn gewijzigd. Deze schakelt zichzelf uit voor handles die met ['processes' => false] zijn geopend. status() roept deze momenteel niet aan; het vergelijkt rechtstreeks stat-gegevens en inhoud.