Conversation
When a user deletes a worktree they're currently in (via `wt delete` or `wt cleanup`), the shell wrapper now automatically changes to the repository root instead of leaving them in a deleted directory. - delete.go: Output repo root to stdout when user is in deleted worktree - cleanup.go: Track if current directory is in any deleted worktree - shell.go: Add delete/cleanup to commands that handle directory changes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThese changes enhance the worktree deletion and cleanup flow by detecting when users are operating from within a worktree being deleted, then outputting the repository root path to enable automatic directory navigation via the shell wrapper. Changes
Sequence DiagramsequenceDiagram
actor User
participant Shell as Shell Wrapper
participant Cmd as Command Handler
participant FS as File System
User->>Shell: wt delete [worktree]
Shell->>Cmd: Execute delete command
Note over Cmd: Check if cwd inside worktree
Cmd->>FS: Verify current directory location
FS-->>Cmd: inDeletedWorktree status
Cmd->>Cmd: Perform deletion
Cmd->>FS: Remove worktree
alt User was in deleted worktree
Cmd-->>Shell: Output repo root (last line)
Shell->>FS: Evaluate last line as directory
Shell->>Shell: cd to repo root
else User not affected
Cmd-->>Shell: Output status message
Shell->>User: Display output
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
internal/commands/cleanup.go (1)
193-201: Path prefix check may produce false positives for sibling directories.Using
strings.HasPrefix(cwd, c.path)can incorrectly match if a worktree path is a prefix of another directory name (e.g.,/repo/worktrees/foowould match/repo/worktrees/foobar). Consider appending a path separator or usingfilepath.Relfor a more robust check.Additionally, the error from
os.Getwd()is silently ignored. IfGetwdfails,cwdwill be empty and the prefix check will always be false, which is a reasonable fallback, but worth noting.♻️ Suggested fix using path separator
// Check if user is in any of the worktrees being deleted cwd, _ := os.Getwd() inDeletedWorktree := false for _, c := range candidates { - if strings.HasPrefix(cwd, c.path) { + if cwd == c.path || strings.HasPrefix(cwd, c.path+string(filepath.Separator)) { inDeletedWorktree = true break } }internal/commands/delete.go (1)
126-128: Same path prefix false-positive concern and potential code duplication.
The
strings.HasPrefix(cwd, worktreePath)check has the same issue as incleanup.go- it could match sibling directories with similar prefixes.Note that
cwdis retrieved viaos.Getwd()twice: once at line 67 (in the auto-detect branch) and again at line 127. Whenargsis provided (explicit worktree name), the first retrieval is skipped, so this second call is necessary. The current structure is correct.♻️ Suggested fix for path comparison
// Check if user is in the worktree being deleted cwd, _ := os.Getwd() - inDeletedWorktree := strings.HasPrefix(cwd, worktreePath) + inDeletedWorktree := cwd == worktreePath || strings.HasPrefix(cwd, worktreePath+string(filepath.Separator))
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
internal/commands/cleanup.gointernal/commands/delete.gointernal/shell/shell.go
🧰 Additional context used
📓 Path-based instructions (3)
internal/shell/**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
Place shell integration function generation in internal/shell/ package
Files:
internal/shell/shell.go
internal/commands/**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
internal/commands/**/*.go: Usego test -v -run TestName ./internal/commands/to run a single test
Place Cobra command implementations in internal/commands/ package
Usecmd.Println()for stderr output andfmt.Fprintln(cmd.OutOrStdout(), ...)for stdout output (paths, listings) in Cobra commands
Files:
internal/commands/cleanup.gointernal/commands/delete.go
internal/{git,commands}/**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
Detect if running in main repo vs worktree by checking if
.gitis a file (worktree) or directory (main repo)
Files:
internal/commands/cleanup.gointernal/commands/delete.go
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: `wt` is a Git worktree manager CLI built with Go and Cobra that manages worktree lifecycle with hooks
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Use shell wrapper function (`wt()`) generated by `wt init <shell>` to handle the actual `cd`, solving the subprocess directory change limitation
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Applies to internal/{git,hooks}/**/*.go : Store worktree numeric index in `.git/worktrees/<name>/wt-index` for use in port offsets and resource isolation
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Applies to internal/{git,commands}/**/*.go : Detect if running in main repo vs worktree by checking if `.git` is a file (worktree) or directory (main repo)
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Applies to internal/git/**/*.go : Place Git worktree command wrappers and porcelain output parsing in internal/git/ package
📚 Learning: 2026-01-12T02:19:51.920Z
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Use shell wrapper function (`wt()`) generated by `wt init <shell>` to handle the actual `cd`, solving the subprocess directory change limitation
Applied to files:
internal/shell/shell.go
📚 Learning: 2026-01-12T02:19:51.920Z
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Applies to internal/shell/**/*.go : Place shell integration function generation in internal/shell/ package
Applied to files:
internal/shell/shell.go
📚 Learning: 2026-01-12T02:19:51.920Z
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: `wt` is a Git worktree manager CLI built with Go and Cobra that manages worktree lifecycle with hooks
Applied to files:
internal/shell/shell.gointernal/commands/cleanup.gointernal/commands/delete.go
📚 Learning: 2026-01-12T02:19:51.920Z
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Applies to internal/git/**/*.go : Place Git worktree command wrappers and porcelain output parsing in internal/git/ package
Applied to files:
internal/shell/shell.gointernal/commands/cleanup.gointernal/commands/delete.go
📚 Learning: 2026-01-12T02:19:51.920Z
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Applies to cmd/wt/main.go : Entry point should be cmd/wt/main.go and delegate to `commands.Execute()`
Applied to files:
internal/shell/shell.go
📚 Learning: 2026-01-12T02:19:51.920Z
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Applies to internal/{git,hooks}/**/*.go : Store worktree numeric index in `.git/worktrees/<name>/wt-index` for use in port offsets and resource isolation
Applied to files:
internal/shell/shell.gointernal/commands/cleanup.gointernal/commands/delete.go
📚 Learning: 2026-01-12T02:19:51.920Z
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Applies to internal/{git,commands}/**/*.go : Detect if running in main repo vs worktree by checking if `.git` is a file (worktree) or directory (main repo)
Applied to files:
internal/commands/cleanup.gointernal/commands/delete.go
📚 Learning: 2026-01-12T02:19:51.920Z
Learnt from: CR
Repo: agarcher/wt PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-12T02:19:51.920Z
Learning: Applies to internal/hooks/**/*.go : Pass standardized hook environment variables: `WT_NAME`, `WT_PATH`, `WT_BRANCH`, `WT_REPO_ROOT`, `WT_WORKTREE_DIR`, `WT_INDEX`
Applied to files:
internal/commands/delete.go
🔇 Additional comments (5)
internal/commands/cleanup.go (1)
248-252: Output follows the correct pattern for shell wrapper integration.The repo root is printed to stdout using
fmt.Fprintln(cmd.OutOrStdout(), repoRoot), which aligns with the coding guidelines for path output. The shell wrapper will read the last line andcdinto it if it's a directory.One minor note: the condition
deleted > 0correctly ensures we only output the path when at least one worktree was actually deleted, preventing the shell wrapper from attempting acdwhen nothing changed.internal/commands/delete.go (1)
158-162: Output correctly uses stdout for shell wrapper integration.The implementation follows the coding guidelines:
fmt.Fprintln(cmd.OutOrStdout(), repoRoot)outputs the path to stdout for the shell wrapper to consume. Unlikecleanup.go, there's nodeleted > 0check needed here since reaching this point means the deletion succeeded.internal/shell/shell.go (3)
162-181: Shell wrapper logic correctly extended for delete and cleanup commands.The change properly extends the
createhandling to also coverdeleteandcleanup. The logic:
- Prints all but the last line via
sed '$d'- Checks if the last line is a directory and
cds into it- Otherwise prints the last line
This handles both scenarios:
create: last line is the new worktree path → cd into itdelete/cleanup: last line is repo root (if in deleted worktree) → cd into it; otherwise command output is printed normallyThe
return $exit_codecorrectly propagates the exit status.
351-367: Bash wrapper matches zsh implementation.The bash implementation mirrors the zsh logic correctly, maintaining consistency across shells.
501-516: Fish wrapper correctly updated.The fish implementation follows the same pattern as bash and zsh, using fish-specific syntax (
test,switch/case). The logic is consistent across all three shells.
Summary
wt deleteorwt cleanup), automatically change to the repository rootwt exitorcdTest plan
wt create test-delete && wt delete- should return to repo rootwt cleanupfrom within it - should return to repo root🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.