
# Kom godt i gang

## Installation

Installér Pitmaster via Composer:

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

## Krav

- **PHP 8.2+** med readonly-klasser, enums og constructor promotion
- **ext-zlib** til komprimering og dekomprimering af objekter (indbygget i de fleste installationer)
- **ext-json** til tilstandsfiler for handlinger og payloads til Git LFS API
- **ext-mbstring**, deklareret i `composer.json`, så Composer kræver den ved installation
- **ext-ctype** til hash-validering (aktiveret i de fleste PHP-builds, men ikke deklareret i `composer.json`)

Kernehandlinger i repositoryet kræver ikke den binære `git`, FFI eller eksterne hjælpeværktøjer. Valgfrie funktioner har yderligere krav ved kørsel: hook-afvikling bruger `proc_open()`, og transport over SSH bruger `ext-ssh2`, når den er indlæst, og starter ellers systemets binære `ssh` via `proc_open()`.

## Åbn et eksisterende repository

```php
use Pitmaster\Pitmaster;

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

Dette åbner repositoryet på den angivne sti. Pitmaster finder mappen `.git` (eller finder en `.git`-fil for sammenkædede worktrees) og initialiserer objektdatabasen, ref-databasen og konfigurationen.

`open()`, `init()` og `clone()` accepterer et options-array som sidste 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 køres som standard. `Pitmaster::processFreeOptions()` returnerer `['processes' => false, 'hooks' => false]`; lokale læsninger og skrivninger fungerer fortsat med sådan et handle.

## Kontrollér, om en sti er et repository

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

## Initialisér et nyt repository

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

Dette opretter mappestrukturen `.git` med objekter, refs, HEAD (der peger på `refs/heads/main`) og en standardkonfiguration.

For at oprette et repository med SHA-256 skal du angive objektformatet som det andet argument:

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

Objekt-id'er i dette repository er 64 hex-tegn, og konfigurationen registrerer `extensions.objectformat = sha256`. Repositories, der åbnes senere, henter formatet fra denne konfigurationspost.

## Læs HEAD-committet

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

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

Metoden `head()` opløser HEAD (ved at følge symbolske refs) og returnerer et `Commit`-objekt.

## Vis branches og tags

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

## Gennemgå commit-historikken

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

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

Du kan også starte fra en bestemt commit:

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

## Kontrollér working tree-status

```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";
    }
}
```

## Tilføj filer til staging og opret et commit

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

Forfatterens navn og e-mail findes i denne rækkefølge: miljøvariablerne `PITMASTER_AUTHOR_NAME` / `PITMASTER_AUTHOR_EMAIL`, miljøvariablerne `GIT_AUTHOR_NAME` / `GIT_AUTHOR_EMAIL`, konstanterne `PITMASTER_AUTHOR_NAME` / `PITMASTER_AUTHOR_EMAIL`, repositoryets egen `.git/config` (`user.name` og `user.email`) og til sidst `Pitmaster <pitmaster@localhost>`. Kun repositoryets konfigurationsfil (og filer, den inkluderer) læses, ikke `~/.gitconfig`. Committerens oplysninger findes på samme måde ud fra navnene `*_COMMITTER_*` og falder tilbage på forfatterkonstanterne.

## Beregn diffs

```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();
```

## Klon et eksternt repository

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

Dette finder refs, henter pack-filen, opsætter branches til fjernsporing og checker standardbranchen ud. URL'er med HTTP(S) bruger smart HTTP og falder tilbage til dumb HTTP; URL'er med SSH bruger transporten SSH. Angiv en dybde som tredje argument for en shallow clone: `Pitmaster::clone($url, $path, 1)`.

## Læs et vilkårligt objekt via hash

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

## Konfiguration

Pitmaster bruger repositoryets `.git/config` til forfatteroplysninger og eksterne URL'er. Du kan også angive globale standardværdier med konstanterne PHP, der defineres, før Pitmaster køres:

```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');
```

| Konstant | Standardværdi | Effekt |
|----------|---------|--------|
| `PITMASTER_AUTHOR_NAME`, `PITMASTER_AUTHOR_EMAIL` | ingen | Forfatteridentitet (se rækkefølgen ovenfor) |
| `PITMASTER_COMMITTER_NAME`, `PITMASTER_COMMITTER_EMAIL` | forfatterværdier | Committeridentitet |
| `PITMASTER_HTTP_TIMEOUT` | `30` | Timeout for smart HTTP i sekunder (heltal) |
| `PITMASTER_MAX_DELTA_CHAIN` | `50` | Maksimal dybde for deltakeden ved læsning af packs (heltal) |
| `PITMASTER_OBJECT_CACHE_ENTRIES` | `1024` | Objekter, der beholdes i objektcachen i hukommelsen |
| `PITMASTER_OBJECT_CACHE_BYTES` | `16M` | Bytebudget for objektcachen |
| `PITMASTER_PACK_RESOLVED_CACHE_ENTRIES` | `4096` | Opløste delta-objekter, der caches pr. pack |
| `PITMASTER_PACK_RESOLVED_CACHE_BYTES` | `32M` | Bytebudget for pakkens cache |
| `PITMASTER_MAX_PACK_MEMORY` | ingen | Ældre navn for pakkecachens bytebudget, bruges kun når `PITMASTER_PACK_RESOLVED_CACHE_BYTES` ikke er defineret |

Byteværdier kan være et heltal eller en streng med suffikset `k`, `m` eller `g` (`'256M'`). Ugyldige værdier bruger standardværdien.

Miljøvariabler tilsidesætter identitetskonstanterne: `PITMASTER_AUTHOR_NAME`, `PITMASTER_AUTHOR_EMAIL`, `PITMASTER_AUTHOR_DATE`, de tilsvarende `PITMASTER_COMMITTER_*` samt git's egne variabler `GIT_AUTHOR_*` og `GIT_COMMITTER_*`. Transporten SSH læser variablerne `PITMASTER_SSH_*`, som er beskrevet i [Protokoller](https://pitmaster.inline0.dev/da/docs/network/protocols).

Der findes ingen konstant for hash-algoritmen. Objektformatet vælges, når repositoryet oprettes (`Pitmaster::init($path, 'sha256')` eller `init --object-format=sha256` på CLI) og læses derefter fra repositoryets konfiguration.
