# wt list
List worktrees and their status.
Shows uncommitted changes, divergence from the default branch and remote, and optional CI status and LLM summaries.
The table renders progressively: branch names, paths, and commit hashes appear immediately, then status, divergence, and other columns fill in as background git operations complete.
## Full mode
`--full` adds columns that require network access or LLM calls: [CI status](#ci-status) (GitHub/GitLab pipeline pass/fail), line diffs since the merge-base, and [LLM-generated summaries](#llm-summaries) of each branch's changes.
## Examples
List all worktrees:
```
$ wt list
Branch Status HEAD± main↕ Remote⇅ Commit Age Message
@ feature-api + ↕⇡ +54 -5 ↑4 ↓1 ⇡3 6814f02a 30m Add API tests
^ main ^⇅ ⇡1 ⇣1 41ee0834 4d Merge fix-auth: hardened to…
○ Showing 4 worktrees, 1 with changes, 2 ahead, 1 column hidden
```
Include CI status, line diffs, and LLM summaries:
```
$ wt list --full
Branch Status HEAD± main↕ main…± Summary Remote⇅ CI Commit
@ feature-api + ↕⇡ +54 -5 ↑4 ↓1 +234 -24 Refactor API to REST architecture with middleware ⇡3 ● 6814f02a
^ main ^⇅ ⇡1 ⇣1 ● 41ee0834
○ Showing 4 worktrees, 1 with changes, 2 ahead, 3 columns hidden
```
Include branches that don't have worktrees:
```
$ wt list --branches --full
Branch Status HEAD± main↕ main…± Summary Remote⇅ CI Commit
@ feature-api + ↕⇡ +54 -5 ↑4 ↓1 +234 -24 Refactor API to REST architecture with middleware ⇡3 ● 6814f02a
^ main ^⇅ ⇡1 ⇣1 ● 41ee0834
exp /↕ ↑2 ↓1 +137 Explore GraphQL schema and resolvers 96379229
wip /↕ ↑1 ↓1 +33 Start API documentation b40716dc
○ Showing 4 worktrees, 2 branches, 1 with changes, 4 ahead, 3 columns hidden
```
Output as JSON for scripting:
```bash
$ wt list --format=json
```
## Columns
| Branch | Branch name |
| Status | Compact symbols (see below) |
| HEAD± | Uncommitted changes: +added -deleted lines |
| main↕ | Commits ahead/behind default branch |
| main…± | Line diffs since the merge-base with the default branch; `--full` only |
| Summary | LLM-generated branch summary; requires `--full`, `summary = true`, and [`commit.generation`](https://worktrunk.dev/config/#commit) [experimental] |
| Remote⇅ | Commits ahead/behind tracking branch |
| CI | Pipeline status; `--full` only |
| Path | Worktree directory |
| URL | Dev server URL from project config; dimmed if port is not listening |
| Commit | Short hash (8 chars) |
| Age | Time since last commit |
| Message | Last commit message (truncated) |
Note: `main↕` and `main…±` refer to the default branch — the header label stays `main` for compactness. `main…±` uses a merge-base (three-dot) diff.
### CI status
The CI column shows GitHub/GitLab pipeline status:
| `●` green | All checks passed |
| `●` blue | Checks running |
| `●` red | Checks failed |
| `●` yellow | Merge conflicts with base |
| `●` gray | No checks configured |
| `⚠` yellow | Fetch error (rate limit, network) |
| (blank) | No upstream or no PR/MR |
CI indicators are clickable links to the PR or pipeline page. Any CI dot appears dimmed when unpushed local changes make the status stale. PRs/MRs are checked first, then branch workflows/pipelines for branches with an upstream. Local-only branches show blank; remote-only branches — visible with `--remotes` — get CI status detection. Results are cached for 30-60 seconds; use `wt config state` to view or clear.
### LLM summaries [experimental]
Reuses the [`commit.generation`](https://worktrunk.dev/config/#commit) command — the same LLM that generates commit messages. Enable with `summary = true` in `[list]` config; requires `--full`. Results are cached until the branch's diff changes.
## Status symbols
The Status column has multiple subcolumns. Within each, only the first matching symbol is shown (listed in priority order):
| Working tree (1) | `+` | Staged files |
| Working tree (2) | `!` | Modified files (unstaged) |
| Working tree (3) | `?` | Untracked files |
| Worktree | `✘` | Merge conflicts |
| | `⤴` | Rebase in progress |
| | `⤵` | Merge in progress |
| | `/` | Branch without worktree |
| | `⚑` | Branch-worktree mismatch (branch name doesn't match worktree path) |
| | `⊟` | Prunable (directory missing) |
| | `⊞` | Locked worktree |
| Default branch | `^` | Is the default branch |
| | `∅` | Orphan branch (no common ancestor with the default branch) |
| | `✗` | Would conflict if merged to the default branch; with `--full`, includes uncommitted changes |
| | `_` | Same commit as the default branch, clean |
| | `–` | Same commit as the default branch, uncommitted changes |
| | `⊂` | Content [integrated](https://worktrunk.dev/remove/#branch-cleanup) into the default branch or target |
| | `↕` | Diverged from the default branch |
| | `↑` | Ahead of the default branch |
| | `↓` | Behind the default branch |
| Remote | `\|` | In sync with remote |
| | `⇅` | Diverged from remote |
| | `⇡` | Ahead of remote |
| | `⇣` | Behind remote |
Rows are dimmed when [safe to delete](https://worktrunk.dev/remove/#branch-cleanup) (`_` same commit with clean working tree or `⊂` content integrated).
### Placeholder symbols
These appear across all columns while the table is loading:
| `·` | Data is loading, or collection timed out / branch too stale |
---
## JSON output
Query structured data with `--format=json`:
```bash
# Current worktree path (for scripts)
# Branches with uncommitted changes
# Worktrees with merge conflicts
# Branches ahead of main (needs merging)
# Integrated branches (safe to remove)
# Branches without worktrees
# Worktrees ahead of remote (needs pushing)
# Stale CI (local changes not reflected in CI)
**Fields:**
| `branch` | string/null | Branch name (null for detached HEAD) |
| `path` | string | Worktree path (absent for branches without worktrees) |
| `kind` | string | `"worktree"` or `"branch"` |
| `commit` | object | Commit info (see below) |
| `working_tree` | object | Working tree state (see below) |
| `main_state` | string | Relation to the default branch (see below) |
| `integration_reason` | string | Why branch is integrated (see below) |
| `operation_state` | string | `"conflicts"`, `"rebase"`, or `"merge"`; absent when clean |
| `main` | object | Relationship to the default branch (see below); absent when is_main |
| `remote` | object | Tracking branch info (see below); absent when no tracking |
| `worktree` | object | Worktree metadata (see below) |
| `is_main` | boolean | Is the main worktree |
| `is_current` | boolean | Is the current worktree |
| `is_previous` | boolean | Previous worktree from wt switch |
| `ci` | object | CI status (see below); absent when no CI |
| `url` | string | Dev server URL from project config; absent when not configured |
| `url_active` | boolean | Whether the URL's port is listening; absent when not configured |
| `summary` | string | LLM-generated branch summary; absent when not configured or no summary |
| `statusline` | string | Pre-formatted status with ANSI colors |
| `symbols` | string | Raw status symbols without colors (e.g., `"!?↓"`) |
| `vars` | object | Per-branch variables from [`wt config state vars`](https://worktrunk.dev/config/#wt-config-state-vars) (absent when empty) |
### Commit object
| `sha` | string | Full commit SHA (40 chars) |
| `short_sha` | string | Short commit SHA, abbreviated per `core.abbrev` (auto-extends for ambiguous prefixes) |
| `message` | string | Commit message (first line) |
| `timestamp` | number | Unix timestamp |
### working_tree object
| `staged` | boolean | Has staged files |
| `modified` | boolean | Has modified files (unstaged) |
| `untracked` | boolean | Has untracked files |
| `renamed` | boolean | Has renamed files |
| `deleted` | boolean | Has deleted files |
| `diff` | object | Lines changed vs HEAD: `{added, deleted}` |
### main object
| `ahead` | number | Commits ahead of the default branch |
| `behind` | number | Commits behind the default branch |
| `diff` | object | Lines changed vs the default branch: `{added, deleted}` |
### remote object
| `name` | string | Remote name (e.g., `"origin"`) |
| `branch` | string | Remote branch name |
| `ahead` | number | Commits ahead of remote |
| `behind` | number | Commits behind remote |
### worktree object
| `state` | string | `"no_worktree"`, `"branch_worktree_mismatch"`, `"prunable"`, `"locked"` (absent when normal) |
| `reason` | string | Reason for locked/prunable state |
| `detached` | boolean | HEAD is detached |
### ci object
| `status` | string | CI status (see below) |
| `source` | string | `"pr"` (PR/MR) or `"branch"` (branch workflow) |
| `stale` | boolean | Local HEAD differs from remote (unpushed changes) |
| `url` | string | URL to the PR/MR page |
### main_state values
These values describe the relation to the default branch.
`"is_main"` `"orphan"` `"would_conflict"` `"empty"` `"same_commit"` `"integrated"` `"diverged"` `"ahead"` `"behind"`
### integration_reason values
When `main_state == "integrated"`: `"ancestor"` `"trees_match"` `"no_added_changes"` `"merge_adds_nothing"` `"patch-id-match"`
### ci.status values
`"passed"` `"running"` `"failed"` `"conflicts"` `"no-ci"` `"error"`
Missing a field that would be generally useful? Open an issue at https://github.com/max-sixty/worktrunk.
## Command reference
```
wt list - List worktrees and their status
Usage: wt list [OPTIONS]
wt list <COMMAND>
Commands:
statusline Single-line status for shell prompts
Options:
--format <FORMAT>
Output format (table, json)
[default: table]
--branches
Include branches without worktrees
--remotes
Include remote branches
--full
Show CI, diff analysis, and LLM summaries
--progressive
Show fast info immediately, update with slow info
Displays local data (branches, paths, status) first, then updates with remote data (CI,
upstream) as it arrives. Use --no-progressive to force buffered rendering. Auto-enabled
for TTY.
-h, --help
Print help (see a summary with '-h')
Global Options:
-C <path>
Working directory for this command
--config <path>
User config file path
-v, --verbose...
Verbose output (-v: info logs + hook/alias template variable & output; -vv: debug logs +
diagnostic report + trace.log/output.log under .git/wt/logs/)
-y, --yes
Skip approval prompts
```