feat: wt list --porcelain + [unadopted] indicator#35
feat: wt list --porcelain + [unadopted] indicator#35bezhermoso wants to merge 7 commits intoblock:mainfrom
wt list --porcelain + [unadopted] indicator#35Conversation
Adds a new library function that wraps `git worktree list --porcelain` and appends wt-specific metadata lines per entry: - wt.active — worktree is the WT_ACTIVE_WORKTREE symlink target - wt.adopted — adoption marker exists - wt.dirty, wt.ahead, wt.behind — with --verbose flag Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Code <noreply@anthropic.com> Ai-assisted: true
Exposes the augmented porcelain output via `wt list --porcelain`. Combinable with -v for verbose metadata (dirty, ahead/behind). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Code <noreply@anthropic.com> Ai-assisted: true
Unit tests for wt_list_porcelain() covering wt.active, wt.adopted, wt.dirty, wt.ahead indicators and verbose/non-verbose modes. Integration tests for wt-list --porcelain flag including color code absence check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Code <noreply@anthropic.com> Ai-assisted: true
Non-adopted worktrees now show a yellow ? prefix and [unadopted] badge. If the worktree is both linked and unadopted, the badge escalates to red to signal that the active worktree is missing metadata/symlinks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Code <noreply@anthropic.com> Ai-assisted: true
Applies the same ? prefix and [unadopted] badge (yellow/red) to the interactive worktree selection menu used by wt switch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Code <noreply@anthropic.com> Ai-assisted: true
Add missing guard on cd failure when iterating worktrees, matching the existing pattern in wt-list. Stale worktree registrations (directory removed but still in git's list) are now silently skipped instead of producing a warning and a blank entry in the picker. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Code <noreply@anthropic.com> Ai-assisted: true
Only the * prefix for active/linked worktrees remains. The [unadopted] badge is sufficient on its own. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Code <noreply@anthropic.com> Ai-assisted: true
wt list --porcelain + [unadopted] indicator
guodong-sq
left a comment
There was a problem hiding this comment.
this adds a new public --porcelain flag to wt list, but the bash/zsh completion definitions do not appear to advertise it yet. It would be good to update completions so the new flag is discoverable from both wt-list and unified wt list completion paths.
(same with the help text)
|
|
||
| # Get absolute path of main repo | ||
| local main_repo_abs | ||
| main_repo_abs="$(cd "$WT_MAIN_REPO_ROOT" && pwd)" |
There was a problem hiding this comment.
main_repo_abs is still normalized with pwd, but worktree entries below now use pwd -P. If WT_MAIN_REPO_ROOT contains symlink components, the main repo won’t compare equal to its own entry, which can break exclude_main and show the main repo as [unadopted]. I think this line should use pwd -P as well so both sides are compared in physical-path form.
There was a problem hiding this comment.
I added two convenience helpers to lib/wt-common that standardize all the cd && pwd -P patterns across the codebase:
_wt_realpath PATH— Resolves the entire path including following symlinks (equivalent to readlink -f but portable). Uses awhile [[ -L ]]loop +cd -P && pwd -P._wt_resolve_parent PATH— Resolves only the parent directory to its physical path, preserving the basename as-is. Useful when you need a canonical parent path but must not dereference the final component (e.g., before a-Lcheck).
| else | ||
| wt_list_porcelain | ||
| fi | ||
| exit $? |
There was a problem hiding this comment.
This exit is before the validations and checks. if WT_MAIN_REPO_ROOT exists but is not actually a git repo, regular wt list still errors, while porcelain mode can return success with no records because the git failure gets swallowed inside wt_list_porcelain.
There was a problem hiding this comment.
I think porcelain mode should preserve the same non-git validation/error behavior as the normal listing path.
| # Source wt-adopt for adoption status checks | ||
| if [[ -f "$LIB_DIR/wt-adopt" ]]; then | ||
| . "$LIB_DIR/wt-adopt" | ||
| elif [[ -f "$HOME/.wt/lib/wt-adopt" ]]; then | ||
| . "$HOME/.wt/lib/wt-adopt" | ||
| fi | ||
|
|
wt list --porcelain: machine-readable worktree metadata + new indicatorsSummary
wt list --porcelain— augmentedgit worktree list --porcelainwith wt-specific metadata lines[unadopted]indicator — surfaces unadopted worktrees inwt listandwt switchpicker--porcelainoutputPasses through native git porcelain verbatim and appends
wt.*lines per entry:With
-v, adds status metadata (slower — runsgit statusper worktree):wt.activeWT_ACTIVE_WORKTREEsymlinkwt.adoptedwt.dirty-vwt.ahead N-vwt.behind N-vWhat
--porcelainunlocksThe structured output makes wt data composable with unix tools and custom scripts. Examples:
Custom fzf worktree picker:
Shell completions that show adoption status:
Scripted batch adoption:
[unadopted]indicator in nice outputWorktrees not managed by wt now show
[unadopted]inwt listand thewt switchpicker. Color escalates based on severity:[unadopted]— informational: worktree exists but isn't wt-managed[unadopted]— when combined with[linked]: you're actively working in an unmanaged worktreeFixes
cd: No such file or directorywarnings or blank entries in thewt switchpicker. They are silently skipped, matching the existing behavior inwt list.Test plan
wt_list_porcelain()(wt.active, wt.adopted, wt.dirty, wt.ahead, verbose/non-verbose modes)wt list --porcelain(output format, color absence, flag combinations)[unadopted]indicator (adopted/unadopted/main/linked+unadopted)wt list --porcelainon a real repo with multiple worktreeswt listand verify[unadopted]appears on correct entrieswt switchand verify picker shows[unadopted]badges🤖 Generated with Claude Code