
# Status

Pitmaster beregner arbejdstræets status ved at sammenligne tre tilstande: HEAD-committens tree, indekset (staging-området) og arbejdstræet (de faktiske filer på disken). CLI udskriver en opsummering i `git status`-stil, og `statusPorcelainV2()` udskriver git's porcelain-format v2.

## Grundlæggende brug

```php
$entries = $repo->status();

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

`shortFormat()` udskriver git's korte format:

```
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

Hver fils status vises med en `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()` rapporterer ikke ignorerede filer, så `Ignored` vises ikke i resultatet.

## Porcelain v2-output

Til maskinlæsbar status, der matcher `git status --porcelain=v2`:

```php
echo $repo->statusPorcelainV2();
```

Output:

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

Sporede poster kommer først, derefter ikke-sporede. Omdøbninger bruger linjer af typen `2`, og konflikter bruger linjer af typen `u`. `git status --porcelain=v2 --branch`-headere af `# branch` udskrives ikke, og ignorerede filer vises ikke.

## Sådan beregnes status

Klassen `WorkingTreeStatus` udfører trevejssammenligningen:

```php
use Pitmaster\Status\WorkingTreeStatus;

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

### Trin 1: Byg HEAD-tree-kort

Fold HEAD-committens tree ud til et kort over `path => blob hash`. Dette repræsenterer den senest committede tilstand.

### Trin 2: Sammenlign HEAD med indekset

For hver fil i HEAD-tree og indekset:
- I HEAD, men ikke i indekset: `Deleted` i indekskolonnen
- I indekset, men ikke i HEAD: `Added` i indekskolonnen
- I begge, men med forskellig hash: `Modified` i indekskolonnen
- I begge med samme hash: `Unmodified` i indekskolonnen

### Trin 3: Sammenlign indekset med arbejdstræet

For hver fil i indekset og arbejdstræet:
- I indekset, men ikke på disken: `Deleted` i arbejdstræskolonnen
- I begge, men med forskelligt indhold: `Modified` i arbejdstræskolonnen
- I begge med identisk indhold: `Unmodified` i arbejdstræskolonnen

### Trin 4: Find ikke-sporede filer

Gennemgå arbejdstræets mappe, spring `.git/` og ignorerede stier over, og rapporter filer, der ikke findes i indekset, som `Untracked` i begge kolonner.

## Understøttelse af .gitignore

Pitmaster fortolker `.gitignore`-filer for at afgøre, hvilke ikke-sporede filer der skal rapporteres som ignorerede eller ikke-sporede.

```php
use Pitmaster\Status\GitIgnore;
```

Klassen `GitIgnore` fortolker gitignore-mønstre fra:
- `.gitignore` i repositoryets rodmappe
- `.gitignore` i undermapper
- `.git/info/exclude`

Understøttet syntaks for mønstre:
- Glob-mønstre (`*.log`, `build/`)
- Negation (`!important.log`)
- Mønstre kun for mapper (afsluttende `/`)
- Indledende `/` for mønstre relative til roden
- `**` til rekursiv matching

## Kategorisering af statusposter

Et almindeligt mønster til visning af 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;
    }
}
```

## Brug af CLI

```bash
./vendor/bin/pitmaster status
```

Output:

```
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 indeholder en hjælper til git's fsmonitor-protokol:

```php
use Pitmaster\Status\Fsmonitor;
```

Klassen `Fsmonitor` kan forespørge `core.fsmonitor`-hooket (med en scanning efter ændringstidspunkt som fallback) for at finde ud af, hvilke filer der er ændret siden et token. Den slår sig selv fra for handles, der er åbnet med `['processes' => false]`. `status()` kalder det ikke i øjeblikket; den sammenligner stat-data og indhold direkte.
