
# Справочник за CLI

Pitmaster включва CLI, който отразява подмножество от командите на git. Работи с хранилището в текущата работна директория.

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

При инсталация чрез Composer скриптът е `./vendor/bin/pitmaster`; от 0.2.11 той намира autoloader-а на проекта там. В checkout на самото хранилище Pitmaster изпълнете `./bin/pitmaster` след `composer install`. В примерите по-долу `pitmaster` обозначава и двата пътя. Изпълнението без аргументи показва списъка с команди.

Ревизиите се разрешават като при `Repository::resolve()`: `HEAD`, имена на клонове и тагове, пълни имена на refs, пълни хешове и изрази `~N` / `^N`. Съкратени хешове не се приемат. Clone, fetch и push са достъпни само чрез PHP API.

## Команди

### `log`

Показва историята на commit-ите, започвайки от най-новия.

```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:` за merge commit-и, `Author:` със суровата идентичност (име, имейл, времеви печат и часова зона) и съобщението за commit с отстъп. `--oneline` показва `abc1234 Subject`. Филтърът по път съвпада с точно един път до файл и проверява само най-новите пет пъти лимита commit-и ([#7](https://github.com/inline0/pitmaster/issues/7)).

### `show`

Показва подробности за commit и разликите спрямо първия родител.

```bash
# Show HEAD
pitmaster show

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

Показва метаданните на commit-а (с ред `Date:`), последвани от унифициран diff. При анотиран таг първо се показват заглавката и съобщението на тага. Използват се цветове само когато stdout е терминал. Merge commit-ите се показват без diff.

### `cat-file`

Извежда суровото съдържание на git обект.

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

Приема пълен хеш. Извежда съхраненото съдържание на обекта: blob-ове, commit-и и тагове като текст, а дърветата — в двоичен вид. За разлика от `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
```

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

### `add`

Индексира файлове за следващия commit.

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

Всеки файл се чете от работното дърво, записва се като blob обект и индексът се обновява. Аргументите са пътища до файлове; директориите и `.` не се разгръщат.

### `commit`

Създава commit от индексираните файлове.

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

Изход:

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

`-m` е задължителен, освен при приключване на спряло сливане, cherry-pick, revert или rebase, когато се използва подготвеното съобщение. Авторът и committer-ът се определят от променливи на средата, константи и `.git/config`, както е описано в [Първи стъпки](https://pitmaster.inline0.dev/bg/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` работят еднакво: нито една от командите не проверява дали клонът е слят и и двете отказват да изтрият клона, към който е направен checkout.

### `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)); първо ги потвърдете или запазете в stash.

### `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. Сливането на клон, който вече е слят, създава още един merge commit ([#6](https://github.com/inline0/pitmaster/issues/6)), а непотвърдените промени в проследяваните файлове се презаписват както при `checkout`.

### `cherry-pick`

Прилага commit върху текущия 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
```

При успех не извежда нищо. `--continue` и `--abort` без текущ cherry-pick приключват с код 128.

### `revert`

Създава revert commit или продължава/прекратява конфликт по време на операция.

```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` без текущ revert приключват с код 128.

### `rebase`

Извършва rebase на текущия клон върху друг ref.

```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` без текущ rebase показват `fatal: no rebase in progress` и приключват с код 128.

### `bisect`

Намира commit-а, въвел дадена промяна, чрез двоично търсене.

```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` показват пълния хеш на следващия кандидат и правят checkout на него. Когато остане само един заподозрян, същият хеш се показва отново: този commit е първият лош. За разлика от git, не се извежда обобщението „това е първият лош commit“.

### `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 записи:

```
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` презаписва незаписани промени във файлове, които не са засегнати от stash-а ([#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 знака от хеша на commit-а и първите 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 до конкретен 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
```

Изисква се ревизия. Изход:

```
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` без операция в ход |
