vibe list
listコマンドは、現在のリポジトリの全Worktreeを整列された1つのテーブルで表示します。各Worktreeのベースとなるブランチ、tipコミットからの経過時間、未コミットの変更の有無も同時に確認できます。
vibe list [オプション]| オプション | 説明 |
|---|---|
--json |
一覧をJSON配列として出力する |
--dirty |
未コミットの変更があるWorktreeのみ |
--clean |
未コミットの変更が無いWorktreeのみ |
--base <branch> |
<branch>をベースとするWorktreeのみ |
--recent <dur> |
<dur>以内にコミットされたWorktreeのみ |
--stale <dur> |
<dur>の間コミットされていないWorktreeのみ |
--sort <key> |
age・name・statusのいずれかで並べ替える |
--reverse |
最終的な表示順を反転する |
--limit <n> |
最大<n>件のみ表示する(<n>は1以上) |
-V, --verbose |
詳細な出力を表示する |
-q, --quiet |
必須ではない出力を抑制する |
--dirtyと--cleanは同時に指定できません。--recentと--staleも同様で、いずれの組み合わせも終了コード2になります。
--quietは一覧そのものは抑制しません。テーブルこそがこのコマンドの成果物であり、抑制してしまうとvibe list --quietが何も出力せずに終了コード0で終わってしまうためです。抑制されるのは周辺の診断メッセージのみです。
$ vibe list* feat/login develop 2h M 3 /path/to/repo-feat-login fix/crash develop 3d clean /path/to/repo-fix-crash (detached) - 1w clean /path/to/repo-detached scratch/2026… develop 12m clean /path/to/scratch-20260101 (scratch)| 列 | 意味 |
|---|---|
| (マーカー) | *は現在自分がいるWorktreeを示す |
| BRANCH | チェックアウト中のブランチ。detached HEADのWorktreeは(detached) |
| BASE | このブランチのベースとなるブランチ — 後述のBASEを参照 |
| AGE | tipコミットからの経過時間(now、12m、2h、3d、1w、5mo、2y) |
| STATUS | clean、またはM <n> — 変更の数え方を参照 |
| SUMMARY | [summary]が設定されている場合のみ — 後述のSUMMARYを参照 |
| PATH | Worktreeのディレクトリ |
vibe scratchで作成されたWorktreeには(scratch)ラベルが付きます。
変更の数え方
Section titled “変更の数え方”M <n>の数値(およびdirty_filesフィールド)はgit statusが報告したエントリ数であり、変更されたファイル数とは限りません。gitは全体が未追跡のディレクトリを1エントリにまとめるため、5ファイルを含む新規ディレクトリは5ではなく1と数えられます。追跡ファイルの変更、ステージ済みの変更、個別の未追跡ファイルはそれぞれ1エントリとして数えられ、リネームは2回ではなく1回として数えられます。
これはgitの既定の報告方法(-unormal)です。vibeは意図的に-uallを渡しません。-uallは全ての未追跡ディレクトリを展開しますが、そのために一覧の各行でgitが未追跡ツリーを完全に走査することになります。これは、まさにそのコストが最も望ましくないリポジトリ(古いnode_modules、肥大したビルド成果物など)において無制限の処理となるうえ、「何かがある」ことを伝えるだけの数値を精密化するにすぎません。
値を特定できなかったセルは-で表示されます。gitが読み取れないWorktree(削除済みチェックアウトが残した壊れたWorktreeなど)も行としては必ず表示され、影響を受けたセルだけが縮退します。
WorktreeのSTATUSの読み取りに失敗した場合は、その理由がstderrに警告として報告されます。AGEやBASEの解決に失敗した場合(detachedなWorktreeのHEADをgit logが読み取れない場合など)は、警告なしで静かに-へ縮退します。これは十分に頻繁に起こりうるため、警告するとノイズになるからです。
BASEは次の順で解決されます。
- ブランチに設定されたupstreamからリモート接頭辞を除いたもの(
origin/develop→develop) - それが無ければリポジトリのデフォルトブランチ(
refs/remotes/origin/HEAD、次にinit.defaultBranch)
ブランチが自分自身をベースとして表示されることはありません。したがってメインWorktree、およびupstreamが自分自身のリモート追跡refであるブランチは-になります。detached HEADも-です。ベースとなるブランチを正確に述べる方法が存在しないためです。
vibe listはWorktreeごとのgit merge-baseを意図的に実行しません。1行につき1回のgit呼び出しが増えるうえ、その答えはブランチではなくコミットです。そのコミットからブランチ名への逆引きは、複数のブランチがマージ地点を共有する場合(分岐直後の一般的なケース)に曖昧になります。upstreamはユーザーが設定した事実であり、デフォルトブランチは文書化されたフォールバックなので、どちらも説明可能です。
AGEはtipコミットのcommitter dateからの経過時間で、切り捨て(切り上げなし)されるため、実際に経過した時間より長く表示されることはありません。moとyの単位は表示専用の近似値です(それぞれ30日と365日)。--jsonでは代わりにlast_commit_atとして厳密なタイムスタンプが出力されます。
まだコミットが無いブランチ(unbornブランチ)にはtipが無いため、AGEは-、last_commit_atはnullになります。
SUMMARY
Section titled “SUMMARY”SUMMARY列は、リポジトリの.vibe.tomlに[summary] commandが設定されている場合のみ表示されます。vibeはvibe listごとにそのコマンドを1回実行し、対象Worktreeのバッチをstdinで渡して、返ってきた内容を表示します。
[summary]command = "./examples/summary/last-commit.sh"timeout_seconds = 30$ vibe list* feat/login develop 2h M 3 ログインフォームを追加 /path/to/repo-feat-login fix/crash develop 3d clean 起動時のpanicを修正 /path/to/repo-fix-crash結果はWorktreeごとにキャッシュされるため、変更のないリポジトリで2回目のvibe listを実行してもコマンドは一切実行されません。コマンドが失敗またはタイムアウトした場合、vibe listは警告を出したうえで、失敗させる代わりに以前キャッシュされたサマリーを表示します。
この列の有無は設定に従い、コマンドの成否には従いません。コマンドが回答しなかったWorktreeは空欄になるため、空の列を「機能がオフなのかもしれない」と読む必要はありません。
コマンドは自分のシェルと権限で実行されるため、トラスト機構の対象となります。[summary] commandを編集すると.vibe.tomlのハッシュが無効になり、vibe trustを再実行するまでvibe listは失敗します。
契約仕様の全体、コマンド出力に課される制限、キャッシュの無効化条件については.vibe.toml → サマリー設定を参照してください。すぐ使えるスクリプトはexamples/summary/にあります。
フィルタ・ソート・件数制限
Section titled “フィルタ・ソート・件数制限”これらのフラグは、決まった順序のパイプラインとして適用されます。
フィルタ(AND) → ソート → 反転 → 件数制限各段階は完全に解決済みの行に対して動作するため、フィルタと--jsonがWorktreeのベース・経過時間・状態について食い違うことはありません。同じフラグは、どちらの出力モードでも同じWorktreeを選択します。
# 今週触って、やりかけのままのものは?vibe list --recent 1w --dirty
# 1か月放置されているものは?vibe list --stale 30d
# 最も古い5件vibe list --sort age --reverse --limit 5
# developから分岐したもの全てを、散らかっている順にvibe list --base develop --sort status
# 直近3件をJSONでvibe list --json --sort age --limit 3 2>&1 | jq .フィルタはANDで結合されます。各フラグは結果を絞り込むため、フラグを増やして行数が増えることはありません。
| フラグ | 残す対象 |
|---|---|
--dirty |
STATUSがdirtyのWorktree |
--clean |
STATUSがcleanのWorktree |
--base <branch> |
BASEが<branch>と完全に一致するWorktree |
--recent <dur> |
tipコミットの経過時間が<dur>以下のWorktree |
--stale <dur> |
tipコミットの経過時間が<dur>を超えるWorktree |
状態を読み取れなかったWorktree(STATUS -)は--dirtyからも--cleanからも除外されます。したがってこの2つのフラグは一覧を分割しません。gitが答えられなかったWorktreeはどちらの答えにも属さず、どちらかに含めることは根拠のない推測になるためです。フィルタ無しの一覧には-付きで表示され、警告も出ます。
--baseは解決済みのBASE列と比較します。比較は前方一致ではなく完全一致であり、--base developはdevelop-2にはマッチしません。ベースを持たないWorktree(メインWorktreeやdetached HEAD)が--baseにマッチすることはありません。
引数はそのままの形、またはリモート名を1つ取り除いた形のどちらでも受け付けます。したがって、ユーザーが自然に入力しうる書き方はいずれも機能します。
| 引数 | マッチするベース |
|---|---|
develop |
develop |
origin/develop |
origin/develop、develop |
release/next |
release/next |
origin/release/next |
origin/release/next、release/next |
両方の解釈を試すのは、引数だけからは両者を判別できないためです。origin/developはリモート修飾されたdevelopですが、release/nextはたまたま名前にスラッシュを含む単なるブランチであり、どちらも<語>/<語>という綴りです。除去した解釈だけを試すと--base release/nextが--base nextに化けてしまい、何にもマッチしなくなります。
両方を受け付ける代償として、ローカルに文字どおりorigin/developという名前のブランチがある場合、--base origin/developはそれにもマッチします。黙って0件を返すよりは、余分な行が出るほうがましだという意図的な取捨選択です。
--recentと--staleは、正の整数1つと単位1つからなる期間を受け取ります。
| 単位 | 意味 |
|---|---|
s |
秒 |
m |
分 |
h |
時間 |
d |
日 |
w |
週 |
例: 90s、30m、12h、2d、1w。
これ以外は説明付きで終了コード2になります。空の値、単位の無い数値(30)、複合形式(1h30m)、小数(1.5d)、ゼロ(0d)、オーバーフローするほど大きな値がこれにあたります。
境界は厳密で、経過時間が判明している全Worktreeについてこの2つは互いの補集合になります。
--recent <dur>はnow − commit ≤ durの行を残します(以下)--stale <dur>はnow − commit > durの行を残します(超過)
したがってvibe list --recent 1dとvibe list --stale 1dは、tipコミット日時が判明している全Worktreeを重複なく分け合います。
未来の日時を持つコミット(コミットを作成したマシンとこのマシンの時刻のずれで日常的に起こります)は--recent扱いになります。これはAGE列がすでにnowと表示していることと一致します。
tipコミットが無いWorktree(unbornブランチ、あるいはログを読み取れなかったもの)は--recentにも--staleにもマッチしません。どちらもその行が持たないコミット日時についての問いだからです。
--sortは次の3つのキーのいずれかを取ります。
| キー | 並び順 |
|---|---|
age |
tipコミットが新しい順。同着は名前順 |
name |
名前の辞書順 |
status |
dirtyを先頭に、次に変更エントリ数が多い順、最後に名前順 |
--sortを指定すると、現在のWorktreeを先頭に置く規則を含め、既定の並び順が完全に置き換わります。--sort ageは最も新しい行が先頭に来ることを約束するものであり、1行だけ例外にすると、たまたま自分がいるWorktreeが動いてしまうためです。
--sort nameでは、detached HEADのWorktreeもディレクトリのbasename(--jsonがnameとして出力するのと同じ値)で参加します。
いずれのソートも最終的なタイブレークとしてWorktreeのパスを用いるため、出力は完全に決定的です。兄弟ディレクトリにある2つのdetached Worktreeはbasenameが一致しうるので、これが無いと両者の順序は「どちらに最近jumpしたか」に依存してしまいます。
経過時間が不明な行は--sort ageで常に末尾に置かれ、--reverseを付けても末尾のままです。「最も古いWorktree」は経過時間を持つWorktreeについての問いなので、--sort age --reverse --limit 5は問いの対象外の行に枠を使わず、実際の答えを5件返します。
--reverseと--limit
Section titled “--reverseと--limit”--reverseは、その時点で最終的な表示順になるはずだったものを反転します。したがって単独でも意味を持ち(既定の「現在のWorktree優先+MRU」順を反転します)、--sortの後にも使えます。
--limit <n>はソートと反転の後に切り詰めます。この順序こそが「最も古い5件」を--sort age --reverse --limit 5で書けるようにしています。先に切り詰めると、最も新しい5件を逆順に表示するだけになり、別の集合になってしまいます。--limit 0は(終了コード2で)拒否されます。何も表示しない一覧は、Worktreeが1つも無いリポジトリと区別がつかないためです。
フィルタが何にもマッチしなかった場合、vibe listはNo worktrees found.ではなくNo worktrees matched the given filters.と明示します。この2つは次に取るべき行動が異なるためです。--jsonモードでは単に[]になります。
JSON出力
Section titled “JSON出力”vibe list --json 2>&1 | jq .2>&1が必要です。vibeはJSONペイロードをstderrに書き込みます。stdoutはシェルのevalチャンネルだからです。シェルラッパーはeval "$(command vibe "$@")"を実行するため、stdoutに書かれたものはシェルコードとして実行されてしまいます。--jsonモードでは、list自身がstderrに書き込むのはペイロードだけであり、ドキュメントがパース可能なままであるよう--verboseの診断メッセージやコマンド自身の警告も抑止されます。
1つだけこのコマンドの制御外の例外があります。グローバルフラグの競合に関する警告(vibe --verbose --quiet list --jsonはWarning: Both --verbose and --quiet specified.を出力します)はサブコマンドの実行前に出力されるため、ペイロードより先に現れます。出力をパースする場合は競合するグローバルフラグを併用しないでください。
配列の各要素は次のフィールドを持つオブジェクトです。
| フィールド | 型 | 説明 |
|---|---|---|
branch |
string | null | チェックアウト中のブランチ。detached HEADではnull |
path |
string | Worktreeの絶対パス |
current |
boolean | コマンドを実行したWorktreeかどうか |
scratch |
boolean | 自動生成されたscratch/<timestamp>のWorktreeかどうか |
name |
string | 常に存在する名前。ブランチ名、detached HEADではディレクトリのbasename |
base |
string | null | BASE列の値。該当しない場合や読み取れなかった場合はnull |
head |
string | null | HEADが指すコミットのsha。unbornブランチ(コミットなし)ではnull |
last_commit_at |
string | null | tipのcommitter dateのISO 8601表記。unbornブランチではnull |
status |
string | null | "clean"または"dirty"。gitに問い合わせられなかった場合はnull |
dirty_files |
number | null | git statusが報告したエントリ数。statusがnullのときは常にnull |
summary |
string | [summary]が設定されている場合のみ存在。未回答の場合は"" |
branch・path・current・scratchはv3.1.0で出荷されたフィールドであり、名前・型・位置が維持されます。新しいフィールドは末尾に追加されるだけです。
headは常にgit showに渡せるshaかnullのいずれかです。まだコミットが無いブランチのWorktreeでは、gitが出力する全てゼロのプレースホルダOIDではなくnullを報告するため、このフィールドに解決できないsha形式の値が入ることはありません。
summaryは[summary]が未設定の場合には完全に省略されるため、この機能を使っていないリポジトリでは、機能が存在しなかった頃とまったく同じドキュメントが出力されます。
AGEの相対表記は出力されません。「3日前」が欲しい利用側は、厳密なlast_commit_atから自分で計算するほうが適切です。
# 変更のある全Worktree — 選択はフィルタが行い、jqは射影のみvibe list --json --dirty 2>&1 | jq -r '.[] | .path'
# ブランチとベースをテーブルでvibe list --json 2>&1 | jq -r '.[] | "\(.name)\t\(.base // "-")"'
# 現在自分がいるWorktreevibe list --json 2>&1 | jq -r '.[] | select(.current) | .path'
# 最も長く触っていないWorktree 3件vibe list --json --sort age --reverse --limit 3 2>&1 | jq -r '.[] | .name'フィルタ・ソート・件数制限のフラグはテーブルと全く同じように--jsonにも適用されます。したがってスクリプト側はjqで選択ロジックを再実装せず、vibeに押し込めます。何にもマッチしなかったフィルタ結果は[]になります。
行の並びは、まず現在のWorktree、次に残りのWorktreeを最近jumpした順(vibe jumpの選択プロンプトと同じMRU順)、最後に一度も訪れていないWorktreeをgit自身の順序で並べます。
MRUストアが存在しない、あるいは壊れている場合はgitの順序に縮退します。一覧が失敗することはありません。
これは既定の並び順です。--sortがこれを置き換え、--reverseはその時点で有効な順序を反転します。
| コード | 条件 |
|---|---|
0 |
一覧を出力した(フィルタが何にもマッチしなかった場合を含む) |
1 |
gitリポジトリ内ではない |
2 |
引数が不正: 排他フラグの同時指定、期間の書式誤り、--limit 0、未知のソートキー |