
# CLI リファレンス

Pitmasterには、gitコマンドの一部を再現するCLIが含まれます。現在の作業ディレクトリにあるリポジトリを操作します。

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

Composerでインストールした場合、スクリプトは`./vendor/bin/pitmaster`にあります。0.2.11以降は、そこにあるプロジェクトのオートローダーを検出します。Pitmasterリポジトリ自体をチェックアウトした場合は、`composer install`の後に`./bin/pitmaster`を実行します。以下の例では、どちらのパスにも`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のlimit表記（`-n N`、`-nN`、`--max-count N`、`--max-count=N`、`-N`）は0.2.11で追加されました。数値のみの指定はPitmaster独自のlimit省略形です。最初のその他の引数はパスフィルターとなり、`--`以降はすべてパスとして扱われます。`-`で始まるその他の引数を指定すると、`fatal: unrecognized argument: <arg>`を表示して終了コード128で終了します。

出力には`commit <hash>`（黄色）、マージコミットの`Merge:`行、生の識別情報（名前、メールアドレス、タイムスタンプ、タイムゾーン）を含む`Author:`、インデントされたコミットメッセージが含まれます。`--oneline`は`abc1234 Subject`を表示します。パスフィルターは完全一致する1つのファイルパスを対象とし、limitの5倍の最新コミットだけを調べます（[#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:`行を含むコミットメタデータに続けて、統合差分を表示します。注釈付きタグの場合は、タグヘッダーとメッセージが先に表示されます。色は標準出力がターミナルの場合にのみ使われます。マージコミットには差分が表示されません。

### `cat-file`

gitオブジェクトの生コンテンツを出力します。

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

完全なハッシュを受け取り、オブジェクトに保存された内容を出力します。blob、commit、tagはテキストとして、treeはバイナリ形式で出力します。`git cat-file -p`とは異なり、treeは整形表示されません。

### `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を出力します。変更されたテキストファイルについては`git diff`と同じ形式です。新規、削除、バイナリ、名前変更、モード変更のファイルは異なる形式で表示されます（[Diff](https://pitmaster.inline0.dev/ja/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`は必須です。ただし、停止したmerge、cherry-pick、revert、rebaseを完了するときは、用意済みのメッセージが使われます。authorとcommitterは、[Getting Started](https://pitmaster.inline0.dev/ja/docs/getting-started)に記載のとおり、環境変数、定数、`.git/config`から解決されます。

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

tagを一覧表示するか、新しい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>'`を出力します。2つのツリー間で異なるパスにローカル変更や未追跡ファイルがある場合は拒否されます。その他の追跡対象ファイルにある未commitの変更は、gitが保持する場合でも対象の内容で上書きされます（[#2](https://github.com/inline0/pitmaster/issues/2)）。先にcommitするかstashしてください。

### `merge`

1つ以上のブランチを現在の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で終了します。すでにマージ済みのブランチをマージすると、別のマージcommitが作成されます（[#6](https://github.com/inline0/pitmaster/issues/6)）。追跡対象ファイルの未commitの変更は、`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
```

成功時は何も出力しません。cherry-pickが進行中でないときに`--continue`または`--abort`を実行すると、終了コード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
```

成功時は何も出力しません。revertが進行中でないときに`--continue`または`--abort`を実行すると、終了コード128で終了します。

### `rebase`

現在のブランチを別のrefに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
```

成功時は何も出力しません。rebaseが進行中でないときに`--continue`、`--skip`、`--abort`を実行すると、`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`は、次の候補の完全なハッシュを出力し、そのcommitをチェックアウトします。疑わしいcommitが1つだけになると、同じハッシュが再度出力されます。そのcommitが最初の不具合commitです。gitと異なり、「is the first bad 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が触れていないファイルの未commit変更を上書きします（[#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);
```

各行にはcommitハッシュの先頭8文字と作成者情報（`Name <email> timestamp timezone`）の先頭30文字が、空白で埋めずに表示されます。

### `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`で作成されたリポジトリは、`.git/config`で`core.logallrefupdates`が`true`に設定されていない限りreflogを記録しません（[#8](https://github.com/inline0/pitmaster/issues/8)）。そのため、`reflog`は設定されるまで何も出力しません。

### `refs`

すべてのrefとそのハッシュを一覧表示します。

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