
# Довідник CLI

Pitmaster містить CLI, що відтворює частину команд git. Він працює з репозиторієм у поточному робочому каталозі.

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

Після встановлення Composer скрипт розташований у `./vendor/bin/pitmaster`; починаючи з 0.2.11, він знаходить там автозавантажувач проєкту. У робочій копії самого репозиторію Pitmaster запустіть `./bin/pitmaster` після `composer install`. У прикладах нижче для обох шляхів використовується `pitmaster`. Запуск без аргументів виводить список команд.

Ревізії визначаються так само, як у `Repository::resolve()`: `HEAD`, назви гілок і тегів, повні назви посилань, повні хеші та вирази `~N` / `^N`. Скорочені хеші не приймаються. Клонування, отримання та надсилання даних доступні лише через PHP API.

## Команди

### `log`

Показує історію комітів, від найновішого.

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

Варіанти ліміту git (`-n N`, `-nN`, `--max-count N`, `--max-count=N`, `-N`) додано в 0.2.11. Голий номер — це власне скорочення Pitmaster для ліміту. Перший інший аргумент фільтрує за шляхом; усе після `--` вважається шляхом. Будь-який інший аргумент, що починається з `-`, виводить `fatal: unrecognized argument: <arg>` і завершує роботу з кодом 128.

Вивід містить `commit <hash>` (жовтим), рядок `Merge:` для комітів злиття, `Author:` із необробленими даними ідентифікації (ім’я, електронна адреса, мітка часу й часовий пояс), а також повідомлення коміту з відступом. `--oneline` виводить `abc1234 Subject`. Фільтр шляху відповідає одному точному шляху до файлу й перевіряє коміти в кількості, що дорівнює ліміту, помноженому на п’ять, починаючи з найновіших ([#7](https://github.com/inline0/pitmaster/issues/7)).

### `show`

Показує дані коміту та різницю з першим батьківським комітом.

```bash
# Show HEAD
pitmaster show

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

Відображає метадані коміту (з рядком `Date:`), а потім уніфіковану різницю. Для анотованого тегу спочатку відображаються заголовок і повідомлення тегу. Кольори використовуються, лише якщо stdout є терміналом. Коміти злиття показуються без різниці.

### `cat-file`

Виводить необроблений вміст об’єкта git.

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

Приймає повний хеш. Виводить збережений вміст об’єкта: blob-об’єкти, коміти й теги як текст, дерева — у двійковому форматі. На відміну від `git cat-file -p`, дерева не форматуються для читання.

### `status`

Показує стан робочого дерева.

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

Вивід:

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

Проіндексовані файли показуються зеленим, а непроіндексовані, нерозлиті та невідстежувані — червоним. Під час злиття з конфліктами з’являється розділ `Unmerged paths:`. Для від’єднаного HEAD виводиться `HEAD detached`, а для чистого дерева — `nothing to commit, working tree clean`. `--porcelain=v2` виводить результат `Repository::statusPorcelainV2()`.

### `diff`

Показує зміни між індексом і робочим деревом (непроіндексовані зміни).

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

Вивід — це кольорова уніфікована різниця, навіть якщо stdout не є терміналом. Для змінених текстових файлів вона відповідає `git diff`; нові, видалені, двійкові, перейменовані файли та файли зі зміненим режимом форматуються інакше (див. [Різниця](https://pitmaster.inline0.dev/uk/docs/operations/diff)). `diff --cached` нічого не виводить до першого коміту ([#5](https://github.com/inline0/pitmaster/issues/5)).

### `add`

Додає файли до індексу для наступного коміту.

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

Кожен файл читається з робочого дерева, записується як blob-об’єкт, а індекс оновлюється. Аргументи — це шляхи до файлів; каталоги та `.` не розгортаються.

### `commit`

Створює коміт із проіндексованих файлів.

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

Вивід:

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

Параметр `-m` обов’язковий, крім завершення злиття, cherry-pick, скасування коміту або перебазування, зупинених через конфлікт; у такому разі використовується підготовлене повідомлення. Дані автора та комітера визначаються зі змінних середовища, констант і `.git/config`, як описано в розділі [Початок роботи](https://pitmaster.inline0.dev/uk/docs/getting-started).

### `branch`

Перелічує гілки або створює нову.

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

Вивід списку:

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

Під час створення виводиться `Created branch <name>`, а під час видалення — `Deleted branch <name>`. `-d` і `-D` працюють однаково: жоден не перевіряє, чи злито гілку, і обидва відмовляються видаляти гілку, на яку перемкнутося.

### `tag`

Перелічує теги або створює новий.

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

Під час створення виводиться `Created tag <name>`.

### `checkout`

Перемикає гілки або від’єднує 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
```

Оновлює HEAD, індекс і робоче дерево відповідно до цільового стану та виводить `Switched to '<target>'`. Відмовляється виконувати дію, якщо локальні зміни або невідстежувані файли є за шляхами, що відрізняються у двох деревах. Незакомічені зміни в інших відстежуваних файлах перезаписуються вмістом цільового дерева; git зберіг би їх ([#2](https://github.com/inline0/pitmaster/issues/2)). Спочатку створіть коміт або сховайте зміни.

### `merge`

Зливає одну або кілька гілок у поточний HEAD або продовжує чи перериває злиття з конфліктами, що триває.

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

Вивід у разі успіху:

```
Merge successful.
```

Вивід у разі конфлікту (у stderr, код завершення 1):

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

`-s` приймає `ours`, `ort` і `recursive`; `ort` та `recursive` використовують стандартне злиття. З `-s` CLI виводить `Merge successful.` і завершує роботу з кодом 0, навіть якщо злиття зупинилося через конфлікти ([#21](https://github.com/inline0/pitmaster/issues/21)), тому після цього перевірте `status`. Виклик `merge --continue` без активного злиття завершується з кодом 128. Злиття вже злитоï гілки створює ще один коміт злиття ([#6](https://github.com/inline0/pitmaster/issues/6)), а незакомічені зміни у відстежуваних файлах перезаписуються так само, як у `checkout`.

### `cherry-pick`

Застосовує коміт поверх поточного HEAD або продовжує чи перериває конфлікт, що триває.

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

У разі успіху нічого не виводить. Якщо cherry-pick не виконується, `--continue` і `--abort` завершуються з кодом 128.

### `revert`

Створює коміт скасування або продовжує чи перериває конфлікт, що триває.

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

У разі успіху нічого не виводить. Якщо скасування коміту не виконується, `--continue` і `--abort` завершуються з кодом 128.

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

У разі успіху нічого не виводить. Якщо перебазування не виконується, `--continue`, `--skip` і `--abort` виводять `fatal: no rebase in progress` та завершуються з кодом 128.

### `bisect`

Знаходить коміт, у якому з’явилася зміна, за допомогою бінарного пошуку.

```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` і `bad` виводять повний хеш наступного кандидата, на який перемикається робоче дерево. Коли залишається один підозрюваний коміт, той самий хеш виводиться знову: цей коміт є першим поганим комітом. На відміну від git, підсумок «це перший поганий коміт» не виводиться.

### `stash`

Зберігає та відновлює зміни робочого каталогу.

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

Повідомлення — це аргумент після `push` або `save`; `-m` не підтримується й буде збережено як повідомлення. `pop`, `apply` і `drop` завжди використовують `stash@{0}`. Вони виводять `Saved working directory to stash abc1234`, `Applied and dropped stash`, `Applied stash` і `Dropped stash`.

Вивід списку схованих змін:

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

Якщо є кілька записів, `drop` і `pop` наразі залишають запис у списку ([#10](https://github.com/inline0/pitmaster/issues/10)), а `apply` перезаписує незакомічені зміни у файлах, яких не стосується схованка ([#11](https://github.com/inline0/pitmaster/issues/11)).

### `blame`

Показує авторство кожного рядка файлу в HEAD.

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

Вивід:

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

Кожен рядок показує перші 8 символів хешу коміту та перші 30 символів ідентифікатора автора (`Name <email> timestamp timezone`) без доповнення.

### `grep`

Шукати вміст файлів у поточному дереві HEAD.

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

Вивід:

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

Параметри мають передувати шаблону:

- `-i`, `--ignore-case`: пошук без урахування регістру
- `-E`, `--extended-regexp`, `--regex`: трактувати шаблон як регулярний вираз PCRE

Вивід — звичайний `path:line:content` без кольорів.

### `reflog`

Показати записи reflog, від найновіших.

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

Формат за замовчуванням — `%gd: %gs` (`HEAD@{0}: commit: Add feature`). Підтримувані заповнювачі: `%gd` і `%gD` (селектор), `%gs` (повідомлення), `%H` і `%h` (повний і короткий новий хеш). Для обмежень приймаються `-n N`, `-nN` і `--max-count N`; `-n 0` виводить усі записи.

Репозиторії, створені за допомогою `pitmaster init`, не записують reflog, якщо `core.logallrefupdates` не має значення `true` у `.git/config` ([#8](https://github.com/inline0/pitmaster/issues/8)), тому `reflog` нічого там не виводить, доки це не налаштовано.

### `refs`

Перелічити всі refs із їхніми хешами.

```bash
pitmaster refs
```

Вивід:

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

Хеші виводяться повністю.

### `reset`

Скинути HEAD до вказаного коміту.

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

Потрібна ревізія. Вивід:

```
HEAD is now at abc1234
```

### `init`

Ініціалізувати новий репозиторій. Це єдина команда, якій не потрібен наявний репозиторій.

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

Вивід:

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

`--object-format` приймає `sha1` (за замовчуванням) і `sha256`.

## Коди завершення

| Код | Значення |
|------|---------|
| 0 | Успіх |
| 1 | Помилка команди: помилка використання, невідома команда, невдала операція (`error: <message>`) або злиття, зупинене через конфлікти |
| 128 | Не репозиторій git (`fatal: <message>`), нерозпізнаний аргумент `log` або `--continue` / `--abort` / `--skip` без операції, що виконується |
