-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add automatic worktree namespacing by repository #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Introduces automatic namespacing of worktrees by repository name to prevent collisions when multiple projects share a parent directory. When multiple projects share a parent directory (e.g., /projects/myproject and /projects/another-project), their worktrees would collide in ../worktrees. This forced users to manually create project-specific directories like ../myproject-worktrees. Now worktrees are automatically namespaced: - Old: ../worktrees/feature/auth (collision risk) - New: ../worktrees/myproject/feature/auth (isolated) Changes: - Auto-namespace worktrees by repository directory name - Auto-detect existing layouts for backwards compatibility - Add migrate-worktrees command with --dry-run and --new-base-dir flags - Show migration warnings when legacy layout is auto-detected - Config option: namespace_by_repo (true/false/nil for auto-detect) - Comprehensive documentation in README and architecture docs Benefits: - Multiple projects can safely share ../worktrees - No manual workaround with project-specific directories - Fully backwards compatible with existing setups - Gradual migration path with helpful warnings
WalkthroughAdds namespaced-by-repo worktree layout (default), auto-detects legacy layouts, exposes a new Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant CLI as wtp CLI
participant C as Config
participant FS as Filesystem
participant Git as git
rect rgb(245,248,255)
note over U,CLI: Migrate legacy worktrees to namespaced layout
U->>CLI: wtp migrate-worktrees [--dry-run] [--new-base-dir]
CLI->>C: LoadConfig()
C-->>CLI: config (auto-detect legacy if needed)
CLI->>FS: findLegacyWorktreesForMigration(config.BaseDir)
FS-->>CLI: legacy worktree list
loop For each legacy worktree
CLI->>CLI: compute new namespaced path
alt Dry-run
CLI-->>U: print planned move source -> target
else Perform migration
CLI->>FS: mkdir -p <target parent>
CLI->>Git: git worktree move <source> <target>
Git-->>CLI: result
CLI-->>U: print moved status
end
end
alt new-base-dir or enabling namespacing
CLI->>C: set Defaults.NamespaceByRepo=true (and BaseDir?)
C-->>CLI: save config
end
CLI-->>U: summary (dry-run/performed)
end
sequenceDiagram
autonumber
participant U as User
participant CLI as wtp list
participant C as Config
U->>CLI: wtp list
CLI->>C: LoadConfig()
C-->>CLI: config (with auto-detect flags)
CLI-->>U: display worktrees
alt legacy auto-detected and warning enabled
CLI-->>U: print migration warning (GetMigrationWarning)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (5)
🧰 Additional context used📓 Path-based instructions (3)**/*.go📄 CodeRabbit inference engine (AGENTS.md)
Files:
cmd/wtp/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*_test.go📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (2)📚 Learning: 2025-10-07T15:56:11.502Z
Applied to files:
📚 Learning: 2025-10-07T15:56:11.502Z
Applied to files:
🧬 Code graph analysis (5)cmd/wtp/cd.go (1)
cmd/wtp/remove.go (1)
cmd/wtp/list.go (1)
cmd/wtp/testhelpers_test.go (1)
cmd/wtp/add_test.go (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
README.md
(5 hunks)cmd/wtp/cd.go
(1 hunks)cmd/wtp/list.go
(1 hunks)cmd/wtp/main.go
(1 hunks)cmd/wtp/migrate.go
(1 hunks)cmd/wtp/migrate_test.go
(1 hunks)docs/architecture.md
(2 hunks)internal/config/config.go
(4 hunks)internal/config/config_test.go
(2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.go
📄 CodeRabbit inference engine (AGENTS.md)
**/*.go
: Run gofmt and goimports; keep imports grouped and organized; local import prefix follows module path github.com/satococoa/wtp
Adhere to golangci-lint rules configured for the project (vet, staticcheck, gosec, mnd, lll=120, etc.)
Errors should be wrapped with context and must not be ignored
Use snake_case for Go filenames; document exported identifiers when non-trivial
Files:
internal/config/config_test.go
cmd/wtp/list.go
cmd/wtp/migrate.go
cmd/wtp/migrate_test.go
cmd/wtp/cd.go
cmd/wtp/main.go
internal/config/config.go
internal/{git,config,hooks,command,errors,io}/**
📄 CodeRabbit inference engine (AGENTS.md)
Place internal packages within internal/{git,config,hooks,command,errors,io}
Files:
internal/config/config_test.go
internal/config/config.go
**/*_test.go
📄 CodeRabbit inference engine (AGENTS.md)
**/*_test.go
: Unit tests live alongside packages and use *_test.go naming
Prefer table-driven tests and mock git operations in unit tests
Files:
internal/config/config_test.go
cmd/wtp/migrate_test.go
cmd/wtp/**
📄 CodeRabbit inference engine (AGENTS.md)
cmd/wtp/**
: CLI entrypoint and commands are implemented under cmd/wtp
Update CLI help text to reflect user-facing changes
Command behavior: wtp cd prints only the absolute worktree path with no side effects
Command behavior: wtp completion generates pure completion scripts via urfave/cli
Command behavior: wtp hook emits shell functions that intercept wtp cd; wtp shell-init combines completion and hook output
Files:
cmd/wtp/list.go
cmd/wtp/migrate.go
cmd/wtp/migrate_test.go
cmd/wtp/cd.go
cmd/wtp/main.go
README.md
📄 CodeRabbit inference engine (AGENTS.md)
Update README when user-facing behavior changes
Files:
README.md
docs/**
📄 CodeRabbit inference engine (AGENTS.md)
Maintain docs such as docs/architecture.md and docs/testing-guidelines.md alongside changes
Files:
docs/architecture.md
🧠 Learnings (2)
📚 Learning: 2025-10-07T15:56:11.502Z
Learnt from: CR
PR: satococoa/wtp#0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T15:56:11.502Z
Learning: Applies to cmd/wtp/** : Command behavior: wtp cd prints only the absolute worktree path with no side effects
Applied to files:
cmd/wtp/cd.go
📚 Learning: 2025-10-07T15:56:11.502Z
Learnt from: CR
PR: satococoa/wtp#0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T15:56:11.502Z
Learning: Applies to cmd/wtp/completion.go : Use getWorktreeNameFromPath() to resolve worktree display names consistently across completion, errors, and parsing
Applied to files:
README.md
🧬 Code graph analysis (6)
internal/config/config_test.go (1)
internal/config/config.go (2)
Config
(12-19)Defaults
(22-25)
cmd/wtp/list.go (1)
internal/config/config.go (1)
GetMigrationWarning
(256-266)
cmd/wtp/migrate.go (4)
internal/errors/errors.go (3)
DirectoryAccessFailed
(233-257)NotInGitRepository
(12-20)GitCommandFailed
(22-35)internal/git/repository.go (2)
NewRepository
(16-21)Repository
(12-14)internal/config/config.go (4)
LoadConfig
(52-101)Defaults
(22-25)SaveConfig
(147-164)Config
(12-19)internal/git/worktree.go (1)
Worktree
(14-19)
cmd/wtp/migrate_test.go (2)
cmd/wtp/migrate.go (1)
NewMigrateCommand
(18-46)internal/config/config.go (2)
Config
(12-19)Defaults
(22-25)
cmd/wtp/cd.go (1)
internal/config/config.go (2)
LoadConfig
(52-101)GetMigrationWarning
(256-266)
cmd/wtp/main.go (1)
cmd/wtp/migrate.go (1)
NewMigrateCommand
(18-46)
🪛 markdownlint-cli2 (0.18.1)
README.md
260-260: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
380-380: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
1. Remove migration warning from wtp cd (violated command contract) - wtp cd must only output the path with no side effects - Warnings are still shown in wtp list 2. Fix legacy worktree detection for nested branches - Add recursive containsGitFile() helper (depth limit 3) - Now correctly detects feature/auth/.git patterns - Critical for auto-detection accuracy 3. Add language tags to markdown fenced code blocks - Fixes MD040 linting errors - All ASCII tree diagrams now use ```text
Thanks @coderabbitai for the thorough review! All issues addressed in dd1c96b: Major fixes:
Minor fixes: The auto-detection should now work correctly for all existing installations with slashed branch names. |
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed:
Length of output: 4307 @lox Thank you for the quick turnaround! I've verified commit dd1c96b and can confirm all three issues have been properly addressed: Major fixes verified:
Minor fix verified: The commit message is also well-structured and clearly explains the rationale for each change. The auto-detection logic should now correctly handle all existing installations with slashed branch names. Great work! 🎉 If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! |
When namespace_by_repo is enabled, worktree names in list/cd/remove commands now display without the repository prefix (e.g., "docs-cleanup" instead of "zig-poker-eval/docs-cleanup"). This provides a cleaner UX while the actual paths on disk remain properly namespaced. Updated test configs to explicitly use legacy mode for backward compatibility testing.
Thank you so much for putting this PR together! After reviewing the changes, it looks like setting base_dir to ../<your_project_name> in .wtp.yml already covers the layout we’re aiming for. Please keep the feedback and suggestions coming. They’re really valuable to me. |
It does, it seems kind of gross that you need to do that on every single project you use wtp for though doesn't it? Is that what you do? |
Summary
Introduces automatic namespacing of worktrees by repository name to prevent collisions when multiple projects share a parent directory.
Problem
When multiple projects share a parent directory (e.g.,
/projects/myproject
and/projects/another-project
), their worktrees would collide in../worktrees
. This forced users to manually create project-specific directories like../myproject-worktrees
as a workaround.Solution
Worktrees are now automatically namespaced by repository directory name:
Before:
After:
Key Features
1. Auto-Detection for Backwards Compatibility
2. Migration Command
3. Configuration
4. Helpful Warnings
When legacy layout is detected, users see:
Changes
migrate-worktrees
command with--dry-run
and--new-base-dir
flagsnamespace_by_repo
(true/false/nil for auto-detect)Benefits
✅ Multiple projects can safely share
../worktrees
✅ No manual workaround with project-specific directories
✅ Fully backwards compatible with existing setups
✅ Gradual migration path with helpful warnings
✅ Optional consolidation from custom base_dir to shared directory
Test Plan
Files Changed
cmd/wtp/migrate.go
: Migration command implementationcmd/wtp/migrate_test.go
: Migration testsinternal/config/config.go
: Auto-detection logic and namespacing supportinternal/config/config_test.go
: Updated tests for namespacingcmd/wtp/list.go
: Added migration warningscmd/wtp/cd.go
: Added migration warningscmd/wtp/main.go
: Registered migrate commandREADME.md
: Documentation for namespacing and migrationdocs/architecture.md
: Architecture documentationSummary by CodeRabbit
New Features
Documentation
Tests