
# Dokumentacja CLI

Pitmaster zawiera CLI, który odwzorowuje wybrany podzbiór poleceń git. Działa na repozytorium w bieżącym katalogu roboczym.

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

W instalacji z Composer skrypt znajduje się w `./vendor/bin/pitmaster`; od 0.2.11 znajduje tam autoloader projektu. W kopii repozytorium Pitmaster uruchom `./bin/pitmaster` po `composer install`. W poniższych przykładach użyto `pitmaster` dla obu ścieżek. Uruchomienie bez argumentów wyświetla listę poleceń.

Rewizje są rozwiązywane tak jak w `Repository::resolve()`: `HEAD`, nazwy gałęzi i tagów, pełne nazwy referencji, pełne skróty oraz wyrażenia `~N` / `^N`. Skrócone skróty nie są akceptowane. Clone, fetch i push są dostępne wyłącznie przez PHP API.

## Polecenia

### `log`

Wyświetla historię commitów, od najnowszego.

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

Zapisy limitu git (`-n N`, `-nN`, `--max-count N`, `--max-count=N`, `-N`) dodano w 0.2.11. Sama liczba to skrót Pitmaster oznaczający limit. Pierwszy inny argument jest filtrem ścieżki; wszystko po `--` jest traktowane jako ścieżka. Każdy inny argument zaczynający się od `-` wyświetla `fatal: unrecognized argument: <arg>` i kończy działanie kodem 128.

Dane wyjściowe zawierają `commit <hash>` (żółty), wiersz `Merge:` dla commitów scalających, `Author:` z surowymi danymi identyfikacyjnymi (nazwą, adresem e-mail, znacznikiem czasu i strefą czasową) oraz wciętą treść commita. `--oneline` wyświetla `abc1234 Subject`. Filtr ścieżki dopasowuje dokładną ścieżkę pliku i sprawdza tylko pięć najnowszych commitów objętych limitem ([#7](https://github.com/inline0/pitmaster/issues/7)).

### `show`

Wyświetla szczegóły commita i różnice względem pierwszego rodzica.

```bash
# Show HEAD
pitmaster show

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

Wyświetla metadane commita (z wierszem `Date:`), a następnie ujednolicony diff. W przypadku adnotowanego tagu najpierw wyświetlany jest nagłówek tagu i jego wiadomość. Kolory są używane tylko wtedy, gdy stdout jest terminalem. Commity scalające są wyświetlane bez diffu.

### `cat-file`

Wyświetla surową zawartość obiektu git.

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

Przyjmuje pełny skrót. Wyświetla zapisaną zawartość obiektu: bloby, commity i tagi jako tekst, a drzewa w postaci binarnej. W odróżnieniu od `git cat-file -p` drzewa nie są formatowane dla czytelności.

### `status`

Wyświetla stan drzewa roboczego.

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

Wynik:

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

Pliki w obszarze indeksu są wyświetlane na zielono, a niezatwierdzone, nierozwiązane i nieśledzone — na czerwono. Podczas scalania z konfliktami pojawia się sekcja `Unmerged paths:`. Odłączony HEAD wyświetla `HEAD detached`, a czyste drzewo — `nothing to commit, working tree clean`. `--porcelain=v2` wyświetla wynik `Repository::statusPorcelainV2()`.

### `diff`

Wyświetla zmiany między indeksem a drzewem roboczym (niezindeksowane zmiany).

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

Dane wyjściowe to kolorowy ujednolicony diff, również wtedy, gdy stdout nie jest terminalem. Dla zmodyfikowanych plików tekstowych odpowiada `git diff`; nowe, usunięte, binarne, przemianowane i zmienione pod względem trybu pliki są formatowane inaczej (zob. [Różnice](https://pitmaster.inline0.dev/pl/docs/operations/diff)). `diff --cached` nie wyświetla nic przed pierwszym commitem ([#5](https://github.com/inline0/pitmaster/issues/5)).

### `add`

Dodaje pliki do indeksu na potrzeby następnego commita.

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

Każdy plik jest odczytywany z drzewa roboczego, zapisywany jako obiekt blob, a indeks jest aktualizowany. Argumentami są ścieżki plików; katalogi i `.` nie są rozwijane.

### `commit`

Tworzy commit z plików dodanych do indeksu.

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

Wynik:

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

`-m` jest wymagane, z wyjątkiem kończenia przerwanego scalania, cherry-pick, revert lub rebase, gdy używana jest przygotowana wiadomość. Autor i osoba zatwierdzająca są ustalani na podstawie zmiennych środowiskowych, stałych i `.git/config`, zgodnie z opisem w [Pierwsze kroki](https://pitmaster.inline0.dev/pl/docs/getting-started).

### `branch`

Wyświetla gałęzie lub tworzy nową.

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

Dane wyjściowe listowania:

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

Tworzenie wyświetla `Created branch <name>`, a usuwanie — `Deleted branch <name>`. `-d` i `-D` działają tak samo: żadne nie sprawdza, czy gałąź została scalona, i oba odmawiają usunięcia aktualnie używanej gałęzi.

### `tag`

Wyświetla tagi lub tworzy nowy.

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

Tworzenie wyświetla `Created tag <name>`.

### `checkout`

Przełącza gałęzie lub odłącza 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
```

Aktualizuje HEAD, indeks i drzewo robocze tak, aby odpowiadały celowi, a następnie wyświetla `Switched to '<target>'`. Odmawia działania, gdy lokalne zmiany lub nieśledzone pliki znajdują się w ścieżkach różniących się między tymi drzewami. Niezatwierdzone zmiany w innych śledzonych plikach są nadpisywane zawartością celu, tak jak zrobiłby to git ([#2](https://github.com/inline0/pitmaster/issues/2)); najpierw zatwierdź je lub odłóż.

### `merge`

Scala jedną lub więcej gałęzi z bieżącym HEAD albo kontynuuje lub przerywa trwające scalanie z konfliktami.

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

Dane wyjściowe po pomyślnym zakończeniu:

```
Merge successful.
```

Dane wyjściowe w przypadku konfliktu (na stderr, kod zakończenia 1):

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

`-s` obsługuje `ours`, `ort` i `recursive`; `ort` i `recursive` korzystają z domyślnego scalania. Z opcją `-s` program CLI wyświetla `Merge successful.` i kończy działanie kodem 0, nawet jeśli scalanie przerwano z powodu konfliktów ([#21](https://github.com/inline0/pitmaster/issues/21)), dlatego później sprawdź `status`. `merge --continue` bez trwającego scalania kończy działanie kodem 128. Scalenie gałęzi, która jest już scalona, tworzy kolejny commit scalający ([#6](https://github.com/inline0/pitmaster/issues/6)), a niezatwierdzone zmiany w śledzonych plikach są nadpisywane tak jak przy `checkout`.

### `cherry-pick`

Nakłada commit na bieżący HEAD albo kontynuuje lub przerywa trwającą operację z konfliktem.

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

Po pomyślnym zakończeniu niczego nie wyświetla. `--continue` i `--abort` bez trwającego cherry-pick kończą działanie kodem 128.

### `revert`

Tworzy commit cofający zmiany albo kontynuuje lub przerywa trwającą operację z konfliktem.

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

Po pomyślnym zakończeniu niczego nie wyświetla. `--continue` i `--abort` bez trwającego revert kończą działanie kodem 128.

### `rebase`

Przenosi bieżącą gałąź na inną referencję za pomocą rebase.

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

Po pomyślnym zakończeniu niczego nie wyświetla. `--continue`, `--skip` i `--abort` bez trwającego rebase wyświetlają `fatal: no rebase in progress` i kończą działanie kodem 128.

### `bisect`

Znajduje commit, który wprowadził zmianę, za pomocą wyszukiwania binarnego.

```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` wyświetlają pełny skrót następnego kandydata, na który następuje przełączenie. Gdy pozostaje jeden podejrzany commit, ten sam skrót jest wyświetlany ponownie: to pierwszy błędny commit. W odróżnieniu od git nie jest wyświetlane podsumowanie „is the first bad commit”.

### `stash`

Zapisuje i przywraca zmiany w katalogu roboczym.

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

Wiadomością jest argument po `push` lub `save`; `-m` nie jest obsługiwane i zostałoby zapisane jako wiadomość. `pop`, `apply` i `drop` zawsze używają `stash@{0}`. Wyświetlają `Saved working directory to stash abc1234`, `Applied and dropped stash`, `Applied stash` i `Dropped stash`.

Dane wyjściowe listy schowków:

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

Gdy istnieje więcej niż jeden wpis, `drop` i `pop` obecnie pozostawiają wpis na liście ([#10](https://github.com/inline0/pitmaster/issues/10)), a `apply` nadpisuje niezatwierdzone zmiany w plikach, których schowek nie dotyczy ([#11](https://github.com/inline0/pitmaster/issues/11)).

### `blame`

Wyświetla autorstwo poszczególnych wierszy pliku w HEAD.

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

Wynik:

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

Każdy wiersz zawiera pierwsze 8 znaków skrótu commita i pierwsze 30 znaków danych identyfikacyjnych autora (`Name <email> timestamp timezone`), bez dopełnienia.

### `grep`

Przeszukuje zawartość plików w drzewie bieżącego HEAD.

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

Wynik:

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

Opcje muszą poprzedzać wzorzec:

- `-i`, `--ignore-case`: dopasowywanie bez rozróżniania wielkości liter
- `-E`, `--extended-regexp`, `--regex`: traktowanie wzorca jako wyrażenia regularnego PCRE

Dane wyjściowe to zwykły `path:line:content` bez kolorów.

### `reflog`

Wyświetla wpisy refloga, od najnowszego.

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

Domyślny format to `%gd: %gs` (`HEAD@{0}: commit: Add feature`). Obsługiwane symbole zastępcze: `%gd` i `%gD` (selektor), `%gs` (wiadomość), `%H` i `%h` (pełny i krótki nowy skrót). Limity przyjmują wartości `-n N`, `-nN` i `--max-count N`; `-n 0` wyświetla wszystkie wpisy.

Repozytoria utworzone przez `pitmaster init` nie zapisują reflogów, chyba że w `.git/config` ustawiono `core.logallrefupdates` na `true` ([#8](https://github.com/inline0/pitmaster/issues/8)). Dlatego `reflog` nic tam nie wyświetla, dopóki reflogi nie zostaną włączone.

### `refs`

Wyświetla wszystkie referencje wraz z ich skrótami.

```bash
pitmaster refs
```

Wynik:

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

Skróty są wyświetlane w całości.

### `reset`

Ustawia HEAD na określony 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
```

Wymagana jest rewizja. Dane wyjściowe:

```
HEAD is now at abc1234
```

### `init`

Inicjuje nowe repozytorium. To jedyne polecenie, które nie wymaga istniejącego repozytorium.

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

Wynik:

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

`--object-format` obsługuje `sha1` (domyślnie) i `sha256`.

## Kody wyjścia

| Kod | Znaczenie |
|------|---------|
| 0 | Powodzenie |
| 1 | Błąd polecenia: błędne użycie, nieznane polecenie, nieudana operacja (`error: <message>`) lub scalanie przerwane z powodu konfliktów |
| 128 | To nie jest repozytorium git (`fatal: <message>`), nierozpoznany argument `log` albo `--continue` / `--abort` / `--skip` bez trwającej operacji |
