
# Premiers pas

## Installation

Installez Pitmaster via Composer :

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

## Prérequis

- **PHP 8.2+** avec classes en lecture seule, énumérations et promotion de constructeur
- **ext-zlib** pour la compression et la décompression des objets (intégré dans la plupart des installations)
- **ext-json** pour les fichiers d'état des opérations et les charges utiles Git LFS API
- **ext-mbstring**, déclaré dans `composer.json`, donc Composer en a besoin lors de l'installation
- **ext-ctype** pour la validation des hachages (activé dans la plupart des compilations PHP, mais non déclaré dans `composer.json`)

Les opérations principales sur les dépôts ne nécessitent ni le binaire `git`, ni FFI, ni outils externes. Les fonctionnalités facultatives ont des exigences d'exécution supplémentaires : l'exécution des hooks utilise `proc_open()`, et le transport SSH utilise `ext-ssh2` lorsqu'il est chargé ; sinon, il lance le binaire système `ssh` via `proc_open()`.

## Ouvrir un dépôt existant

```php
use Pitmaster\Pitmaster;

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

Ouvre le dépôt au chemin indiqué. Pitmaster localise le répertoire `.git` (ou résout un fichier `.git` pour les worktrees liés), puis initialise la base d'objets, la base de refs et la configuration.

`open()`, `init()` et `clone()` acceptent un tableau d'options comme dernier 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());
```

Les hooks sont exécutés par défaut. `Pitmaster::processFreeOptions()` renvoie `['processes' => false, 'hooks' => false]` ; les lectures et écritures locales continuent de fonctionner sur un tel handle.

## Vérifier si un chemin est un dépôt

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

## Initialiser un nouveau dépôt

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

Cela crée la structure de répertoires `.git` avec les objets, les refs, HEAD (pointant vers `refs/heads/main`) et une configuration par défaut.

Pour créer un dépôt SHA-256, indiquez le format d'objet en deuxième argument :

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

Les ID d'objet dans ce dépôt font 64 caractères hexadécimaux, et la configuration enregistre `extensions.objectformat = sha256`. Les dépôts ouverts par la suite récupèrent le format dans cette entrée de configuration.

## Lire le commit HEAD

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

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

La méthode `head()` résout HEAD (en suivant les refs symboliques) et renvoie un objet `Commit`.

## Lister les branches et les 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']
```

## Parcourir l'historique des commits

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

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

Vous pouvez aussi partir d'un commit spécifique :

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

## Vérifier l'état de l'arbre de travail

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

## Ajouter des fichiers à l'index et créer un 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";
```

Le nom et l'adresse e-mail de l'auteur sont déterminés dans cet ordre : les variables d'environnement `PITMASTER_AUTHOR_NAME` / `PITMASTER_AUTHOR_EMAIL`, les variables d'environnement `GIT_AUTHOR_NAME` / `GIT_AUTHOR_EMAIL`, les constantes `PITMASTER_AUTHOR_NAME` / `PITMASTER_AUTHOR_EMAIL`, la configuration propre au dépôt `.git/config` (`user.name` et `user.email`), puis `Pitmaster <pitmaster@localhost>`. Seul le fichier de configuration du dépôt (et les fichiers qu'il inclut) est lu, pas `~/.gitconfig`. Le committer est déterminé de la même façon à partir des noms `*_COMMITTER_*` et revient aux constantes de l'auteur en dernier recours.

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

## Cloner un dépôt distant

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

Cette fonction découvre les références, récupère le fichier pack, configure les branches de suivi distant et extrait la branche par défaut. HTTP(S) Les URL utilisent HTTP intelligent et basculent sur HTTP simple ; les URL SSH utilisent le transport SSH. Passez une profondeur en troisième argument pour un clonage superficiel : `Pitmaster::clone($url, $path, 1)`.

## Lire n’importe quel objet à partir de son hachage

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

## Configuration

Pitmaster respecte le `.git/config` du dépôt pour les informations d’auteur et les URL distantes. Vous pouvez également définir des valeurs par défaut globales à l’aide des constantes PHP, définies avant l’exécution de Pitmaster :

```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 | Valeur par défaut | Effet |
|----------|---------|--------|
| `PITMASTER_AUTHOR_NAME`, `PITMASTER_AUTHOR_EMAIL` | aucune | Identité de l’auteur (voir l’ordre ci-dessus) |
| `PITMASTER_COMMITTER_NAME`, `PITMASTER_COMMITTER_EMAIL` | valeurs de l’auteur | Identité du validateur |
| `PITMASTER_HTTP_TIMEOUT` | `30` | Délai d’attente de HTTP intelligent en secondes (entier) |
| `PITMASTER_MAX_DELTA_CHAIN` | `50` | Profondeur maximale de la chaîne de deltas lors de la lecture des packs (entier) |
| `PITMASTER_OBJECT_CACHE_ENTRIES` | `1024` | Objets conservés dans le cache d’objets en mémoire |
| `PITMASTER_OBJECT_CACHE_BYTES` | `16M` | Limite en octets du cache d’objets |
| `PITMASTER_PACK_RESOLVED_CACHE_ENTRIES` | `4096` | Objets delta résolus mis en cache par pack |
| `PITMASTER_PACK_RESOLVED_CACHE_BYTES` | `32M` | Limite en octets de ce cache de pack |
| `PITMASTER_MAX_PACK_MEMORY` | aucune | Ancien nom de la limite en octets du cache de pack, utilisé uniquement si `PITMASTER_PACK_RESOLVED_CACHE_BYTES` n’est pas défini |

Les valeurs en octets acceptent un entier ou une chaîne avec le suffixe `k`, `m` ou `g` (`'256M'`). Les valeurs non valides reprennent la valeur par défaut.

Les variables d’environnement prennent le pas sur les constantes d’identité : `PITMASTER_AUTHOR_NAME`, `PITMASTER_AUTHOR_EMAIL`, `PITMASTER_AUTHOR_DATE`, leurs équivalents `PITMASTER_COMMITTER_*` et les variables `GIT_AUTHOR_*` et `GIT_COMMITTER_*` propres à git. Le transport SSH lit les variables `PITMASTER_SSH_*`, décrites dans [Protocoles](https://pitmaster.inline0.dev/fr/docs/network/protocols).

Il n’existe pas de constante pour l’algorithme de hachage. Le format des objets est choisi lors de la création du dépôt (`Pitmaster::init($path, 'sha256')` ou `init --object-format=sha256` sur le CLI), puis lu dans la configuration du dépôt.
