
# Referință pentru CLI

Pitmaster include un CLI care reproduce un subset de comenzi git. Acesta operează asupra depozitului din directorul de lucru curent.

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

Într-o instalare Composer, scriptul se află în `./vendor/bin/pitmaster`; deoarece 0.2.11, găsește acolo autoloaderul proiectului. Într-un checkout al depozitului Pitmaster propriu-zis, rulați `./bin/pitmaster` după `composer install`. Exemplele de mai jos folosesc `pitmaster` pentru oricare dintre căi. Rularea fără argumente afișează lista de comenzi.

Reviziile sunt rezolvate ca în `Repository::resolve()`: `HEAD`, nume de ramuri și etichete, nume complete de referințe, hashuri complete și expresii `~N` / `^N`. Hashurile abreviate nu sunt acceptate. Clonarea, preluarea și împingerea sunt disponibile numai prin PHP API.

## Comenzi

### `log`

Afișează istoricul commiturilor, de la cel mai nou.

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

Formele limitei git (`-n N`, `-nN`, `--max-count N`, `--max-count=N`, `-N`) au fost adăugate în 0.2.11. Un număr simplu este prescurtarea proprie a lui Pitmaster pentru limită. Primul alt argument este un filtru de cale; tot ce urmează după `--` este tratat drept cale. Orice alt argument care începe cu `-` afișează `fatal: unrecognized argument: <arg>` și iese cu 128.

Rezultatul include `commit <hash>` (galben), o linie `Merge:` pentru commiturile de îmbinare, `Author:` cu identitatea brută (nume, e-mail, marcaj temporal și fus orar), iar mesajul commitului este indentat. `--oneline` afișează `abc1234 Subject`. Filtrul de cale corespunde unei singure căi exacte de fișier și examinează cele mai recente cinci ori limita de commituri ([#7](https://github.com/inline0/pitmaster/issues/7)).

### `show`

Afișează detaliile commitului și diferențele față de primul părinte.

```bash
# Show HEAD
pitmaster show

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

Afișează metadatele commitului (cu o linie `Date:`), urmate de un diff unificat. Pentru o etichetă adnotată, antetul și mesajul etichetei apar primele. Culorile sunt folosite numai când stdout este un terminal. Commiturile de îmbinare sunt afișate fără diff.

### `cat-file`

Afișează conținutul brut al unui obiect git.

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

Primește un hash complet. Afișează conținutul stocat al obiectului: bloburile, commiturile și etichetele ca text, arborii în format binar. Spre deosebire de `git cat-file -p`, arborii nu sunt formatați pentru afișare.

### `status`

Afișează starea arborelui de lucru.

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

Rezultat:

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

Fișierele pregătite pentru commit sunt afișate cu verde, iar cele nepregătite, neîmbinate și neurmărite, cu roșu. O secțiune `Unmerged paths:` apare în timpul unei îmbinări cu conflicte. Un HEAD detașat afișează `HEAD detached`, iar un arbore curat afișează `nothing to commit, working tree clean`. `--porcelain=v2` afișează rezultatul pentru `Repository::statusPorcelainV2()`.

### `diff`

Afișează modificările dintre index și arborele de lucru (modificări nepregătite).

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

Rezultatul este un diff unificat colorat, inclusiv când stdout nu este un terminal. Pentru fișierele text modificate, corespunde lui `git diff`; fișierele noi, șterse, binare, redenumite și cu mod schimbat sunt formatate diferit (consultați [Diff](https://pitmaster.inline0.dev/ro/docs/operations/diff)). `diff --cached` nu afișează nimic înainte de primul commit ([#5](https://github.com/inline0/pitmaster/issues/5)).

### `add`

Pregătește fișierele pentru următorul commit.

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

Fiecare fișier este citit din arborele de lucru, scris ca obiect blob, iar indexul este actualizat. Argumentele sunt căi de fișiere; directoarele și `.` nu sunt extinse.

### `commit`

Creează un commit din fișierele pregătite.

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

Rezultat:

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

`-m` este obligatoriu, cu excepția finalizării unei îmbinări, a unui cherry-pick, a unei reveniri sau a unei rebazări întrerupte, caz în care se folosește mesajul pregătit. Autorul și persoana care face commitul sunt determinate din variabilele de mediu, constante și `.git/config`, conform descrierii din [Introducere](https://pitmaster.inline0.dev/ro/docs/getting-started).

### `branch`

Listează ramurile sau creează una nouă.

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

Rezultatul listării:

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

Crearea afișează `Created branch <name>`, iar ștergerea afișează `Deleted branch <name>`. `-d` și `-D` se comportă la fel: niciuna nu verifică dacă ramura a fost îmbinată, iar ambele refuză să șteargă ramura asupra căreia s-a făcut checkout.

### `tag`

Listează etichetele sau creează una nouă.

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

Crearea afișează `Created tag <name>`.

### `checkout`

Schimbă ramurile sau detașează 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
```

Actualizează HEAD-ul, indexul și arborele de lucru pentru a corespunde țintei, apoi afișează `Switched to '<target>'`. Refuză operația când modificările locale sau fișierele neurmărite se află în căi diferite între cei doi arbori. Modificările necomise din alte fișiere urmărite sunt suprascrise cu conținutul țintei, pe când git le-ar păstra ([#2](https://github.com/inline0/pitmaster/issues/2)); faceți commit sau salvați-le temporar mai întâi.

### `merge`

Îmbină una sau mai multe ramuri în HEAD-ul curent sau continuă/anulează o îmbinare cu conflicte în curs.

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

Rezultat în caz de reușită:

```
Merge successful.
```

Rezultat în caz de conflict (pe stderr, cod de ieșire 1):

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

`-s` acceptă `ours`, `ort` și `recursive`; `ort` și `recursive` folosesc ambele îmbinarea implicită. Cu `-s`, CLI afișează `Merge successful.` și iese cu 0 chiar dacă îmbinarea s-a oprit din cauza conflictelor ([#21](https://github.com/inline0/pitmaster/issues/21)), așadar verificați ulterior `status`. `merge --continue` fără o îmbinare în curs iese cu 128. Îmbinarea unei ramuri deja îmbinate creează un alt commit de îmbinare ([#6](https://github.com/inline0/pitmaster/issues/6)), iar modificările necomise din fișierele urmărite sunt suprascrise ca la `checkout`.

### `cherry-pick`

Aplică un commit peste HEAD-ul curent sau continuă/anulează un conflict în curs.

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

Nu afișează nimic în caz de reușită. `--continue` și `--abort` fără un cherry-pick în curs ies cu 128.

### `revert`

Creează un commit de revenire sau continuă/anulează un conflict în curs.

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

Nu afișează nimic în caz de reușită. `--continue` și `--abort` fără o revenire în curs ies cu 128.

### `rebase`

Rebazează ramura curentă peste o altă referință.

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

Nu afișează nimic în caz de reușită. `--continue`, `--skip` și `--abort` fără o rebazare în curs afișează `fatal: no rebase in progress` și ies cu 128.

### `bisect`

Găsește commitul care a introdus o modificare prin căutare binară.

```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` și `bad` afișează hashul complet al următorului candidat, asupra căruia se face checkout. Când rămâne un singur suspect, același hash este afișat din nou: acel commit este primul cu probleme. Spre deosebire de git, nu se afișează rezumatul „is the first bad commit”.

### `stash`

Salvează și restaurează modificările din directorul de lucru.

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

Mesajul este argumentul de după `push` sau `save`; `-m` nu este acceptat și ar fi stocat ca mesaj. `pop`, `apply` și `drop` folosesc întotdeauna `stash@{0}`. Acestea afișează `Saved working directory to stash abc1234`, `Applied and dropped stash`, `Applied stash` și `Dropped stash`.

Rezultatul listei de salvări temporare:

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

Când există mai multe intrări, `drop` și `pop` lasă momentan intrarea în listă ([#10](https://github.com/inline0/pitmaster/issues/10)), iar `apply` suprascrie modificările necomise din fișierele pe care salvarea temporară nu le atinge ([#11](https://github.com/inline0/pitmaster/issues/11)).

### `blame`

Afișează atribuirea fiecărei linii dintr-un fișier la HEAD.

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

Rezultat:

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

Fiecare linie afișează primele 8 caractere ale hashului commitului și primele 30 de caractere ale identității autorului (`Name <email> timestamp timezone`), fără completare.

### `grep`

Caută în conținutul fișierelor din arborele HEAD curent.

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

Rezultat:

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

Opțiunile trebuie să apară înaintea modelului:

- `-i`, `--ignore-case`: potrivire fără diferențiere între majuscule și minuscule
- `-E`, `--extended-regexp`, `--regex`: tratează modelul ca expresie regulată PCRE

Rezultatul este text simplu `path:line:content`, fără culori.

### `reflog`

Afișează intrările reflog, de la cea mai nouă.

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

Formatul implicit este `%gd: %gs` (`HEAD@{0}: commit: Add feature`). Substituenți acceptați: `%gd` și `%gD` (selector), `%gs` (mesaj), `%H` și `%h` (hash nou complet și scurt). Limitele acceptă `-n N`, `-nN` și `--max-count N`; `-n 0` afișează toate intrările.

Depozitele create de `pitmaster init` nu înregistrează refloguri decât dacă `core.logallrefupdates` este setat la `true` în `.git/config` ([#8](https://github.com/inline0/pitmaster/issues/8)), așadar `reflog` nu afișează nimic acolo până când nu este setat.

### `refs`

Listează toate referințele împreună cu hashurile lor.

```bash
pitmaster refs
```

Rezultat:

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

Hashurile sunt afișate integral.

### `reset`

Resetează HEAD la un anumit commit.

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

Este necesară o revizie. Rezultat:

```
HEAD is now at abc1234
```

### `init`

Inițializează un depozit nou. Aceasta este singura comandă care nu necesită un depozit existent.

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

Rezultat:

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

`--object-format` acceptă `sha1` (implicit) și `sha256`.

## Coduri de ieșire

| Cod | Semnificație |
|------|---------|
| 0 | Reușită |
| 1 | Eroare de comandă: eroare de utilizare, comandă necunoscută, operație nereușită (`error: <message>`) sau îmbinare oprită din cauza conflictelor |
| 128 | Nu este un depozit git (`fatal: <message>`), argument `log` nerecunoscut sau `--continue` / `--abort` / `--skip` fără nicio operație în curs |
