
# Riferimento CLI

Pitmaster include un CLI che riproduce un sottoinsieme dei comandi git. Opera sul repository nella directory di lavoro corrente.

```bash
./vendor/bin/pitmaster <command> [args...]
```

In un'installazione Composer, lo script è `./vendor/bin/pitmaster`; da 0.2.11, trova lì l'autoloader del progetto. In un checkout del repository Pitmaster stesso, eseguite `./bin/pitmaster` dopo `composer install`. Gli esempi seguenti usano `pitmaster` per entrambi i percorsi. Se eseguito senza argomenti, mostra l'elenco dei comandi.

Le revisioni vengono risolte come in `Repository::resolve()`: `HEAD`, nomi di branch e tag, nomi completi dei riferimenti, hash completi ed espressioni `~N` / `^N`. Gli hash abbreviati non sono accettati. Clone, fetch e push sono disponibili solo tramite PHP API.

## Comandi

### `log`

Mostra la cronologia dei commit, dal più recente.

```bash
# Default: last 10 commits
pitmaster log

# Limit the number of commits
pitmaster log 25
pitmaster log -n 3
pitmaster log -n3
pitmaster log --max-count 3
pitmaster log --max-count=3
pitmaster log -3

# Commits that touch one file
pitmaster log src/Repository.php
pitmaster log -- src/Repository.php

# Commits reachable from all refs, and one line per commit
pitmaster log --all
pitmaster log --oneline
```

Le forme dei limiti di git (`-n N`, `-nN`, `--max-count N`, `--max-count=N`, `-N`) sono state aggiunte in 0.2.11. Un numero senza prefisso è la forma abbreviata di Pitmaster per il limite. Il primo altro argomento è un filtro per percorso; tutto ciò che segue `--` viene trattato come percorso. Qualsiasi altro argomento che inizia con `-` mostra `fatal: unrecognized argument: <arg>` e termina con 128.

L'output include `commit <hash>` (giallo), una riga `Merge:` per i commit di merge, `Author:` con l'identità grezza (nome, email, timestamp e fuso orario) e il messaggio del commit indentato. `--oneline` mostra `abc1234 Subject`. Il filtro per percorso corrisponde a un singolo percorso file esatto ed esamina solo i commit più recenti, fino a cinque volte il limite ([#7](https://github.com/inline0/pitmaster/issues/7)).

### `show`

Mostra i dettagli del commit e le differenze rispetto al primo genitore.

```bash
# Show HEAD
pitmaster show

# Show a specific commit
pitmaster show HEAD~3
pitmaster show v1.0.0
pitmaster show 3f2c1e0b9d6a4f8e7c5b2a1d0e9f8c7b6a5d4e3f
```

Mostra i metadati del commit (con una riga `Date:`), seguiti da un diff unificato. Per un tag annotato, prima vengono mostrati l'intestazione e il messaggio del tag. I colori vengono usati solo quando stdout è un terminale. I commit di merge vengono mostrati senza diff.

### `cat-file`

Stampa il contenuto grezzo di un oggetto git.

```bash
pitmaster cat-file a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
```

Richiede un hash completo. Stampa il contenuto archiviato dell'oggetto: blob, commit e tag come testo, alberi nel loro formato binario. A differenza di `git cat-file -p`, gli alberi non vengono formattati in modo leggibile.

### `status`

Mostra lo stato della working tree.

```bash
pitmaster status
pitmaster status --porcelain=v2
```

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

I file in stage sono mostrati in verde; quelli non in stage, non uniti e non tracciati in rosso. In caso di merge con conflitti, appare una sezione `Unmerged paths:`. Un HEAD scollegato mostra `HEAD detached`, mentre una working tree pulita mostra `nothing to commit, working tree clean`. `--porcelain=v2` mostra l'output di `Repository::statusPorcelainV2()`.

### `diff`

Mostra le modifiche tra l'indice e la working tree (modifiche non in stage).

```bash
# Unstaged changes
pitmaster diff

# Staged changes (index vs HEAD)
pitmaster diff --cached
pitmaster diff --staged

# Choose the algorithm
pitmaster diff --patience
pitmaster diff --histogram
pitmaster diff --minimal
```

L'output è un diff unificato a colori, anche quando stdout non è un terminale. Per i file di testo modificati corrisponde a `git diff`; i file nuovi, eliminati, binari, rinominati e con modalità modificata hanno una formattazione diversa (vedere [Differenze](https://pitmaster.inline0.dev/it/docs/operations/diff)). `diff --cached` non mostra nulla prima del primo commit ([#5](https://github.com/inline0/pitmaster/issues/5)).

### `add`

Mette i file in stage per il commit successivo.

```bash
pitmaster add src/Feature.php
pitmaster add src/Feature.php tests/FeatureTest.php README.md
```

Ogni file viene letto dalla working tree, scritto come oggetto blob e aggiunto all'indice. Gli argomenti sono percorsi di file; le directory e `.` non vengono espansi.

### `commit`

Crea un commit dai file in stage.

```bash
pitmaster commit -m "Add new feature"
```

Output:

```
[main abc1234] Add new feature
```

`-m` è obbligatorio, tranne quando si completa un merge, cherry-pick, revert o rebase interrotto, nel qual caso viene usato il messaggio preparato. L'autore e il committer vengono ricavati dalle variabili d'ambiente, dalle costanti e da `.git/config`, come descritto in [Per iniziare](https://pitmaster.inline0.dev/it/docs/getting-started).

### `branch`

Elenca i branch o ne crea uno nuovo.

```bash
# List all branches (current marked with *)
pitmaster branch

# Create a new branch from HEAD
pitmaster branch feature/new-thing

# Delete a branch
pitmaster branch -d feature/old
pitmaster branch -D feature/old
```

Output dell'elenco:

```
  bugfix/typo
  feature/login
* main
```

La creazione mostra `Created branch <name>`, l'eliminazione mostra `Deleted branch <name>`. `-d` e `-D` si comportano allo stesso modo: non verificano se il branch è stato unito e rifiutano entrambi di eliminare il branch attualmente selezionato.

### `tag`

Elenca i tag o ne crea uno nuovo.

```bash
# List all tags
pitmaster tag

# Create a lightweight tag at HEAD
pitmaster tag v1.0.0

# Create an annotated tag at HEAD
pitmaster tag v2.0.0 -m "Release version 2.0.0"
```

La creazione mostra `Created tag <name>`.

### `checkout`

Passa da un branch all'altro o scollega HEAD.

```bash
# Switch to a branch
pitmaster checkout feature/login

# Detach HEAD at a tag or commit
pitmaster checkout v1.0.0
pitmaster checkout HEAD~2
```

Aggiorna HEAD, l'indice e la working tree affinché corrispondano alla destinazione, quindi mostra `Switched to '<target>'`. Rifiuta l'operazione se modifiche locali o file non tracciati si trovano in percorsi diversi tra i due alberi. Le modifiche non confermate negli altri file tracciati vengono sovrascritte con il contenuto della destinazione, mentre git le manterrebbe ([#2](https://github.com/inline0/pitmaster/issues/2)); eseguite prima il commit o mettetele da parte con stash.

### `merge`

Unisce uno o più branch all'HEAD corrente oppure continua o interrompe un conflitto di merge in corso.

```bash
# Start a merge
pitmaster merge feature/login

# Merge with a strategy
pitmaster merge -s ours feature/login

# Octopus merge of several branches
pitmaster merge feature/a feature/b

# Continue after resolving conflicts
pitmaster add a.txt
pitmaster merge --continue

# Abort and restore the pre-merge state
pitmaster merge --abort
```

Output in caso di successo:

```
Merge successful.
```

Output in caso di conflitto (su stderr, codice di uscita 1):

```
CONFLICT in: src/File.php, src/Other.php
```

`-s` accetta `ours`, `ort` e `recursive`; `ort` e `recursive` usano entrambi il merge predefinito. Con `-s`, CLI mostra `Merge successful.` e termina con codice 0 anche se il merge si è interrotto a causa di conflitti ([#21](https://github.com/inline0/pitmaster/issues/21)); controllate quindi `status`. `merge --continue`, se non è in corso un merge, termina con 128. Unire un branch già unito crea un altro commit di merge ([#6](https://github.com/inline0/pitmaster/issues/6)) e le modifiche non confermate nei file tracciati vengono sovrascritte come con `checkout`.

### `cherry-pick`

Applica un commit sopra l'HEAD corrente oppure continua o interrompe un conflitto in corso.

```bash
# Start a cherry-pick
pitmaster cherry-pick feature~1

# Continue after resolving conflicts
pitmaster add a.txt
pitmaster cherry-pick --continue

# Abort and restore HEAD
pitmaster cherry-pick --abort
```

In caso di successo non mostra nulla. `--continue` e `--abort`, se non è in corso un cherry-pick, terminano con 128.

### `revert`

Crea un commit di revert oppure continua o interrompe un conflitto in corso.

```bash
# Start a revert
pitmaster revert HEAD~1

# Continue after resolving conflicts
pitmaster add a.txt
pitmaster revert --continue

# Abort and restore HEAD
pitmaster revert --abort
```

In caso di successo non mostra nulla. `--continue` e `--abort`, se non è in corso un revert, terminano con 128.

### `rebase`

Esegue il rebase del branch corrente su un altro riferimento.

```bash
# Start a rebase
pitmaster rebase main

# Continue after resolving conflicts
pitmaster rebase --continue

# Skip the current commit
pitmaster rebase --skip

# Abort and restore the original branch tip
pitmaster rebase --abort
```

In caso di successo non mostra nulla. Se non è in corso un rebase, `--continue`, `--skip` e `--abort` mostrano `fatal: no rebase in progress` e terminano con 128.

### `bisect`

Trova il commit che ha introdotto una modifica tramite ricerca binaria.

```bash
# Start with a bad and a good revision; checks out and prints the first candidate
pitmaster bisect start HEAD v1.0.0

# Mark the checked-out candidate (or a given revision)
pitmaster bisect good
pitmaster bisect bad
pitmaster bisect bad HEAD~3

# End the session and return to the starting branch
pitmaster bisect reset
```

`start`, `good` e `bad` mostrano l'hash completo del candidato successivo, di cui viene eseguito il checkout. Quando resta un solo sospettato, lo stesso hash viene mostrato di nuovo: quel commit è il primo commit errato. A differenza di git, non viene mostrato il riepilogo "è il primo commit errato".

### `stash`

Salva e ripristina le modifiche alla directory di lavoro.

```bash
# Save current changes (push)
pitmaster stash
pitmaster stash push
pitmaster stash push "Work in progress on login"
pitmaster stash save "Work in progress on login"

# Apply and remove the top stash entry
pitmaster stash pop

# Apply without removing
pitmaster stash apply

# List stash entries
pitmaster stash list

# Drop the top stash entry
pitmaster stash drop
```

Il messaggio è l'argomento dopo `push` o `save`; `-m` non è supportato e verrebbe salvato come messaggio. `pop`, `apply` e `drop` usano sempre `stash@{0}`. Mostrano `Saved working directory to stash abc1234`, `Applied and dropped stash`, `Applied stash` e `Dropped stash`.

Output dell'elenco stash:

```
stash@{0}: On main: Work in progress on login
stash@{1}: WIP on main: abc1234 Add new feature
```

Se sono presenti più voci, attualmente `drop` e `pop` lasciano la voce nell'elenco ([#10](https://github.com/inline0/pitmaster/issues/10)) e `apply` sovrascrive le modifiche non confermate nei file non interessati dallo stash ([#11](https://github.com/inline0/pitmaster/issues/11)).

### `blame`

Mostra l'autore di ogni riga di un file a HEAD.

```bash
pitmaster blame src/Repository.php
```

Output:

```
a1b2c3d4 (Jane Smith <jane@example.com> ) <?php
a1b2c3d4 (Jane Smith <jane@example.com> )
f5e6d7c8 (Ann Lee <ann@example.com> 1700) declare(strict_types=1);
```

Ogni riga mostra i primi 8 caratteri dell'hash del commit e i primi 30 caratteri dell'identità dell'autore (`Name <email> timestamp timezone`), senza padding.

### `grep`

Cerca i contenuti dei file nell'albero HEAD corrente.

```bash
pitmaster grep "function merge"
pitmaster grep -i -E "h.llo"
```

Output:

```
src/Repository.php:2257:    public function merge(string $branch, string $strategy = 'recursive'): MergeResult
src/Merge/ThreeWayMerge.php:23:    public static function merge(
```

Le opzioni devono precedere il pattern:

- `-i`, `--ignore-case`: corrispondenza senza distinzione tra maiuscole e minuscole
- `-E`, `--extended-regexp`, `--regex`: interpreta il pattern come un'espressione regolare PCRE

L'output è testo semplice `path:line:content` senza colori.

### `reflog`

Mostra le voci del reflog, dalla più recente alla meno recente.

```bash
# HEAD reflog (default: 10 entries)
pitmaster reflog

# Another ref, a custom limit, and a format
pitmaster reflog show refs/heads/main
pitmaster reflog -n 5
pitmaster reflog --format="%h %gs"
```

Il formato predefinito è `%gd: %gs` (`HEAD@{0}: commit: Add feature`). Segnaposto supportati: `%gd` e `%gD` (selettore), `%gs` (messaggio), `%H` e `%h` (hash nuovo completo e abbreviato). I limiti accettano `-n N`, `-nN` e `--max-count N`; `-n 0` stampa tutte le voci.

I repository creati da `pitmaster init` non registrano i reflog, a meno che `core.logallrefupdates` non sia impostato su `true` in `.git/config` ([#8](https://github.com/inline0/pitmaster/issues/8)); pertanto, in questi repository `reflog` non stampa nulla finché non lo si imposta.

### `refs`

Elenca tutti i riferimenti con i rispettivi hash.

```bash
pitmaster refs
```

Output:

```
abc123def456... refs/heads/main
789012abc345... refs/heads/feature/login
def456789012... refs/tags/v1.0.0
```

Gli hash vengono stampati per intero.

### `reset`

Reimposta HEAD su un commit specifico.

```bash
# Mixed reset (HEAD + index, default)
pitmaster reset HEAD~1
pitmaster reset --mixed HEAD~1

# Soft reset (HEAD only)
pitmaster reset --soft HEAD~1

# Hard reset (HEAD + index + worktree)
pitmaster reset --hard HEAD~3
```

È necessaria una revisione. Output:

```
HEAD is now at abc1234
```

### `init`

Inizializza un nuovo repository. È l'unico comando che non richiede un repository esistente.

```bash
# Initialize in the current directory
pitmaster init

# Initialize at a specific path
pitmaster init /path/to/new-project

# Create a SHA-256 repository
pitmaster init --object-format=sha256
pitmaster init /path/to/new-project --object-format=sha256
```

Output:

```
Initialized empty Pitmaster repository in /path/to/new-project/.git/
```

`--object-format` accetta `sha1` (predefinito) e `sha256`.

## Codici di uscita

| Codice | Significato |
|------|---------|
| 0 | Operazione riuscita |
| 1 | Errore del comando: errore di utilizzo, comando sconosciuto, operazione non riuscita (`error: <message>`) o merge interrotto a causa di conflitti |
| 128 | Directory non appartenente a un repository git (`fatal: <message>`), argomento `log` non riconosciuto o `--continue` / `--abort` / `--skip` senza operazioni in corso |
