wt list

List worktrees and their status

Shows uncommitted changes, divergence from the default branch and remote, and optional CI status.

wt list demo

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. With --full, CI status fetches from the network — the table displays instantly and CI fills in as results arrive.

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…
+ fix-auth         |                ↑2  ↓1     |     b772e68b  5h    Add secure token storage

 Showing 3 worktrees, 1 with changes, 2 ahead, 1 column hidden

Include CI status and line diffs:

$ wt list --full
  Branch       Status        HEAD±    main↕     main…±  Remote⇅  CI  Commit    Age   Message
@ feature-api  +        +54   -5   ↑4  ↓1  +234  -24   ⇡3         6814f02a  30m   Add API tests
^ main             ^                                    ⇡1  ⇣1     41ee0834  4d    Merge fix-au…
+ fix-auth         |                ↑2  ↓1   +25  -11     |        b772e68b  5h    Add secure t…

 Showing 3 worktrees, 1 with changes, 2 ahead, 1 column hidden

Include branches that don't have worktrees:

$ wt list --branches --full
  Branch       Status        HEAD±    main↕     main…±  Remote⇅  CI  Commit    Age   Message
@ feature-api  +        +54   -5   ↑4  ↓1  +234  -24   ⇡3         6814f02a  30m   Add API tests
^ main             ^                                    ⇡1  ⇣1     41ee0834  4d    Merge fix-au…
+ fix-auth         |                ↑2  ↓1   +25  -11     |        b772e68b  5h    Add secure t…
  exp             /                 ↑2  ↓1  +137                    96379229  2d    Add GraphQL…
  wip             /                 ↑1  ↓1   +33                    b40716dc  3d    Start API do…

 Showing 3 worktrees, 2 branches, 1 with changes, 4 ahead, 1 column hidden

Output as JSON for scripting:

$ wt list --format=json

Columns

ColumnShows
BranchBranch name
StatusCompact 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)
PathWorktree directory
Remote⇅Commits ahead/behind tracking branch
URLDev server URL from project config (dimmed if port not listening)
CIPipeline status (--full)
CommitShort hash (8 chars)
AgeTime since last commit
MessageLast commit message (truncated)

Note: main↕ and main…± refer to the default branch (header label stays main for compactness). main…± uses a merge-base (three-dot) diff.

CI status

The CI column shows GitHub/GitLab pipeline status:

IndicatorMeaning
greenAll checks passed
blueChecks running
redChecks failed
yellowMerge conflicts with base
grayNo checks configured
yellowFetch 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 there are unpushed local changes (stale status). PRs/MRs are checked first, then branch workflows/pipelines for branches with an upstream. Local-only branches show blank. Results are cached for 30-60 seconds; use wt config state to view or clear.

Status symbols

The Status column has multiple subcolumns. Within each, only the first matching symbol is shown (listed in priority order):

SubcolumnSymbolMeaning
Working tree (1)+Staged files
Working tree (2)!Modified files (unstaged)
Working tree (3)?Untracked files
WorktreeMerge 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 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 (_ same commit with clean working tree or content integrated).


JSON output

Query structured data with --format=json:

# Current worktree path (for scripts)
wt list --format=json | jq -r '.[] | select(.is_current) | .path'

# Branches with uncommitted changes
wt list --format=json | jq '.[] | select(.working_tree.modified)'

# Worktrees with merge conflicts
wt list --format=json | jq '.[] | select(.operation_state == "conflicts")'

# Branches ahead of main (needs merging)
wt list --format=json | jq '.[] | select(.main.ahead > 0) | .branch'

# Integrated branches (safe to remove)
wt list --format=json | jq '.[] | select(.main_state == "integrated" or .main_state == "empty") | .branch'

# Branches without worktrees
wt list --format=json --branches | jq '.[] | select(.kind == "branch") | .branch'

# Worktrees ahead of remote (needs pushing)
wt list --format=json | jq '.[] | select(.remote.ahead > 0) | {branch, ahead: .remote.ahead}'

# Stale CI (local changes not reflected in CI)
wt list --format=json --full | jq '.[] | select(.ci.stale) | .branch'

Fields:

FieldTypeDescription
branchstring/nullBranch name (null for detached HEAD)
pathstringWorktree path (absent for branches without worktrees)
kindstring"worktree" or "branch"
commitobjectCommit info (see below)
working_treeobjectWorking tree state (see below)
main_statestringRelation to the default branch (see below)
integration_reasonstringWhy branch is integrated (see below)
operation_statestring"conflicts", "rebase", or "merge" (absent when clean)
mainobjectRelationship to the default branch (see below, absent when is_main)
remoteobjectTracking branch info (see below, absent when no tracking)
worktreeobjectWorktree metadata (see below)
is_mainbooleanIs the main worktree
is_currentbooleanIs the current worktree
is_previousbooleanPrevious worktree from wt switch
ciobjectCI status (see below, absent when no CI)
urlstringDev server URL from project config (absent when not configured)
url_activebooleanWhether the URL's port is listening (absent when not configured)
statuslinestringPre-formatted status with ANSI colors
symbolsstringRaw status symbols without colors (e.g., "!?↓")

Commit object

FieldTypeDescription
shastringFull commit SHA (40 chars)
short_shastringShort commit SHA (7 chars)
messagestringCommit message (first line)
timestampnumberUnix timestamp

working_tree object

FieldTypeDescription
stagedbooleanHas staged files
modifiedbooleanHas modified files (unstaged)
untrackedbooleanHas untracked files
renamedbooleanHas renamed files
deletedbooleanHas deleted files
diffobjectLines changed vs HEAD: {added, deleted}

main object

FieldTypeDescription
aheadnumberCommits ahead of the default branch
behindnumberCommits behind the default branch
diffobjectLines changed vs the default branch: {added, deleted}

remote object

FieldTypeDescription
namestringRemote name (e.g., "origin")
branchstringRemote branch name
aheadnumberCommits ahead of remote
behindnumberCommits behind remote

worktree object

FieldTypeDescription
statestring"no_worktree", "branch_worktree_mismatch", "prunable", "locked" (absent when normal)
reasonstringReason for locked/prunable state
detachedbooleanHEAD is detached

ci object

FieldTypeDescription
statusstringCI status (see below)
sourcestring"pr" (PR/MR) or "branch" (branch workflow)
stalebooleanLocal HEAD differs from remote (unpushed changes)
urlstringURL 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"

ci.status values

"passed" "running" "failed" "conflicts" "no-ci" "error"

Missing a field that would be generally useful? Open an issue.

See also

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
          Include CI status and diff analysis (slower)

      --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. 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...
          Show debug info and write diagnostic report (-vv)