
# Aan de slag

## Installatie

Installeer Pitmaster via Composer:

```bash
composer require pitmaster/pitmaster
```

## Vereisten

- **PHP 8.2+** met readonly-klassen, enums en constructor-promotie
- **ext-zlib** voor objectcompressie en -decompressie (ingebouwd in de meeste installaties)
- **ext-json** voor statusbestanden van bewerkingen en payloads van Git LFS API
- **ext-mbstring**, gedeclareerd in `composer.json`, dus Composer vereist dit tijdens de installatie
- **ext-ctype** voor hashvalidatie (ingeschakeld in de meeste PHP-builds, maar niet gedeclareerd in `composer.json`)

Voor kernbewerkingen van de repository zijn het binaire bestand `git`, FFI of externe hulpprogramma's niet nodig. Optionele functies hebben aanvullende runtimevereisten: hook-uitvoering gebruikt `proc_open()`, en voor SSH-transport wordt `ext-ssh2` gebruikt als dit is geladen; anders wordt het systeem-binaire bestand `ssh` gestart via `proc_open()`.

## Een bestaande repository openen

```php
use Pitmaster\Pitmaster;

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

Hiermee open je de repository op het opgegeven pad. Pitmaster vindt de map `.git` (of lost een bestand `.git` op voor gekoppelde worktrees) en initialiseert de objectdatabase, ref-database en configuratie.

`open()`, `init()` en `clone()` accepteren een opties-array als laatste argument:

```php
// Do not run .git/hooks scripts for this handle
$repo = Pitmaster::open('/path/to/project', ['hooks' => false]);

// Do not start any process: no hooks, no fsmonitor hook, no clone/fetch/push, no SSH
$repo = Pitmaster::open('/path/to/project', Pitmaster::processFreeOptions());
```

Hooks worden standaard uitgevoerd. `Pitmaster::processFreeOptions()` retourneert `['processes' => false, 'hooks' => false]`; lokale lees- en schrijfbewerkingen blijven werken met zo'n handle.

## Controleren of een pad een repository is

```php
if (Pitmaster::isRepository('/path/to/project')) {
    $repo = Pitmaster::open('/path/to/project');
}
```

## Een nieuwe repository initialiseren

```php
$repo = Pitmaster::init('/path/to/new-project');
```

Hiermee maak je de directorystructuur `.git` aan met objecten, refs, HEAD (verwijzend naar `refs/heads/main`) en een standaardconfiguratie.

Geef bij het aanmaken van een SHA-256-repository het objectformaat mee als tweede argument:

```php
$repo = Pitmaster::init('/path/to/new-project', 'sha256');
```

Object-ID's in die repository bestaan uit 64 hex-tekens, en de configuratie bevat `extensions.objectformat = sha256`. Later geopende repositories halen het formaat op uit dat configuratie-item.

## De HEAD-commit lezen

```php
$head = $repo->head();

echo "Commit: {$head->id->hex}\n";
echo "Author: {$head->author}\n";
echo "Message: {$head->message}\n";
```

De methode `head()` lost HEAD op (volgt symbolische refs) en retourneert een object `Commit`.

## Branches en tags weergeven

```php
// All branch names
$branches = $repo->branches();
// ['main', 'feature/login', 'bugfix/typo']

// Current branch name (null if detached)
$current = $repo->branch();
// 'main'

// All tag names
$tags = $repo->tags();
// ['v1.0.0', 'v1.1.0']
```

## De commitgeschiedenis doorlopen

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

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

Je kunt ook beginnen bij een specifieke commit:

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

## De status van de werkboom controleren

```php
use Pitmaster\Status\FileStatus;

$entries = $repo->status();

foreach ($entries as $entry) {
    if ($entry->index === FileStatus::Untracked) {
        echo "?? {$entry->path}\n";
    } elseif ($entry->index === FileStatus::Modified) {
        echo "M  {$entry->path}\n";
    } elseif ($entry->worktree === FileStatus::Modified) {
        echo " M {$entry->path}\n";
    }
}
```

## Bestanden stagen en committen

```php
// Stage specific files
$repo->add('src/Feature.php', 'tests/FeatureTest.php');

// Create a commit
$commitId = $repo->commit('Add new feature with tests');

echo "Created commit: {$commitId->hex}\n";
```

De naam en het e-mailadres van de auteur worden in deze volgorde bepaald: de omgevingsvariabelen `PITMASTER_AUTHOR_NAME` / `PITMASTER_AUTHOR_EMAIL`, de omgevingsvariabelen `GIT_AUTHOR_NAME` / `GIT_AUTHOR_EMAIL`, de constanten `PITMASTER_AUTHOR_NAME` / `PITMASTER_AUTHOR_EMAIL`, de eigen `.git/config` van de repository (`user.name` en `user.email`), en tot slot `Pitmaster <pitmaster@localhost>`. Alleen het configuratiebestand van de repository (en bestanden die het insluit) wordt gelezen, niet `~/.gitconfig`. De committer wordt op dezelfde manier bepaald met de namen `*_COMMITTER_*` en valt terug op de constanten voor de auteur.

## Diffs berekenen

```php
// Unstaged changes (worktree vs index)
$diffs = $repo->diff();

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

// Staged changes (index vs HEAD)
$staged = $repo->diffStaged();
```

## Een externe repository klonen

```php
$repo = Pitmaster::clone('https://github.com/user/repo.git', '/path/to/destination');
```

Hiermee worden refs gevonden, het pack-bestand opgehaald, remote tracking branches ingesteld en de standaardbranch uitgecheckt. HTTP(S)-URL's gebruiken smart HTTP en vallen terug op dumb HTTP; SSH-URL's gebruiken het transport SSH. Geef als derde argument een diepte op voor een shallow clone: `Pitmaster::clone($url, $path, 1)`.

## Elk object op hash lezen

```php
$object = $repo->readObject($fullHash); // full 40-character (or 64 for SHA-256) hex hash

if ($object instanceof \Pitmaster\Object\Blob) {
    echo $object->content;
} elseif ($object instanceof \Pitmaster\Object\Commit) {
    echo $object->message;
}
```

## Configuratie

Pitmaster volgt de `.git/config` van de repository voor auteursgegevens en remote URL's. Je kunt ook globale standaardwaarden instellen met constanten PHP, die zijn gedefinieerd voordat Pitmaster wordt uitgevoerd:

```php
define('PITMASTER_AUTHOR_NAME', 'Your Name');
define('PITMASTER_AUTHOR_EMAIL', 'you@example.com');
define('PITMASTER_HTTP_TIMEOUT', 60);        // Seconds
define('PITMASTER_MAX_DELTA_CHAIN', 50);     // Max delta chain depth
define('PITMASTER_OBJECT_CACHE_BYTES', '64M');
```

| Constante | Standaard | Effect |
|----------|---------|--------|
| `PITMASTER_AUTHOR_NAME`, `PITMASTER_AUTHOR_EMAIL` | geen | Auteursidentiteit (zie de bovenstaande volgorde) |
| `PITMASTER_COMMITTER_NAME`, `PITMASTER_COMMITTER_EMAIL` | auteurwaarden | Committeridentiteit |
| `PITMASTER_HTTP_TIMEOUT` | `30` | Time-out voor smart HTTP in seconden (geheel getal) |
| `PITMASTER_MAX_DELTA_CHAIN` | `50` | Maximale diepte van de delta-keten bij het lezen van packs (geheel getal) |
| `PITMASTER_OBJECT_CACHE_ENTRIES` | `1024` | Objecten in de objectcache in het geheugen |
| `PITMASTER_OBJECT_CACHE_BYTES` | `16M` | Bytebudget van de objectcache |
| `PITMASTER_PACK_RESOLVED_CACHE_ENTRIES` | `4096` | Opgeloste delta-objecten die per pack worden gecachet |
| `PITMASTER_PACK_RESOLVED_CACHE_BYTES` | `32M` | Bytebudget van die packcache |
| `PITMASTER_MAX_PACK_MEMORY` | geen | Oudere naam voor het bytebudget van de packcache, alleen gebruikt als `PITMASTER_PACK_RESOLVED_CACHE_BYTES` niet is gedefinieerd |

Bytewaarden accepteren een geheel getal of een tekenreeks met een achtervoegsel `k`, `m` of `g` (`'256M'`). Ongeldige waarden vallen terug op de standaardwaarde.

Omgevingsvariabelen overschrijven de identiteitsconstanten: `PITMASTER_AUTHOR_NAME`, `PITMASTER_AUTHOR_EMAIL`, `PITMASTER_AUTHOR_DATE`, de `PITMASTER_COMMITTER_*`-equivalenten en de eigen variabelen `GIT_AUTHOR_*` en `GIT_COMMITTER_*` van git. Het transport SSH leest variabelen `PITMASTER_SSH_*`, beschreven in [Protocollen](https://pitmaster.inline0.dev/nl/docs/network/protocols).

Er is geen constante voor het hash-algoritme. Het objectformaat wordt gekozen wanneer de repository wordt aangemaakt (`Pitmaster::init($path, 'sha256')` of `init --object-format=sha256` op de CLI) en wordt daarna uit de repositoryconfiguratie gelezen.
