Skip to content

feat(clone): add wt clone with category-based placement - #122

Open
brosu wants to merge 2 commits into
timvw:mainfrom
brosu:feat/clone
Open

feat(clone): add wt clone with category-based placement#122
brosu wants to merge 2 commits into
timvw:mainfrom
brosu:feat/clone

Conversation

@brosu

@brosu brosu commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Motivation

Every wt command assumes you are already inside a repo. There is no way to acquire the main repository in the first place.
wt clone fills that gap.

What this adds

wt clone <owner/repo|url> [dest] — clones a repository into its canonical location for a category, left on its
default branch, ready to inspect. A worktree can be added later with the usual wt commands.

wt clone oss timvw/wt # -> ~/dev/repos/oss/timvw/wt/main
wt clone work owner/repo # -> ~/dev/repos/work/owner/repo/main
wt clone personal git@…/x.git # full URL, same layout
wt clone personal git@…/x.git ~/src/x # explicit dest, bypasses layout

Categories

A category is an organizational context: where repos live (repo_root) plus the auth profile used to reach them (gh_auth,
git_protocol, glab_host). Three builtins ship: work, personal, oss.

repo_root = "~/dev/repos" # base; category root = <repo_root>/

[categories.work]
gh_auth = "work"
git_protocol = "ssh"

[categories.personal]
gh_auth = "personal"

[categories.client]
repo_root = "~/clients/acme/src" # explicit override
glab_host = "gitlab.acme.com"

Placement pattern

Default: {.category.RepoRoot}/{.repo.Owner}/{.repo.Name}/{.branch}

{.branch} is the remote's default branch, resolved via git ls-remote --symref before cloning (fallback "main"). This makes
the clone directory a valid main-worktree slot for sibling-worktree strategies. Override with repo_pattern.

Other details

  • owner/repo shorthand resolved via gh (or glab), honouring git_protocol
  • gh auth switch --user <gh_auth> before resolve/clone (best-effort, warns on failure)
  • pre_clone / post_clone hooks (pre aborts on failure, post warns only)
  • --format json output with navigate_to
  • Shell completions for bash/zsh/fish/PowerShell (category arg completes work personal oss)
  • wt info and wt examples clone updated
  • Extracts shared template rendering into internal/tmpl (used by worktree_path.go and category.go)

Tests

  • Unit: cmd/clone_test.go — placement path, URL passthrough, category resolution, owner/repo detection
  • e2e: e2e/scenarios/clone.yaml — local-repo clone, unknown category, explicit dest, hooks

Introduce `wt clone <category> <owner/repo|url> [dest]`: acquire a repo's
canonical checkout under a category's repo_root in a host/owner/repo layout,
left on its default branch and ready to inspect. Fills wt's missing front
half — every other command assumes the repo already exists locally.

Adds the `categories` config concept (repo_root + gh_auth / git_protocol /
glab_host) that drives placement and auth. owner/repo is resolved to a clone
URL via gh/glab honoring git_protocol; a full URL is used as-is.

- cmd/clone.go: command, URL resolution, gh auth switch, placement, hooks
- cmd/category.go: Category type, builtins, resolve/merge, repoPlacementPath
- cmd/config.go: [categories.*], default_category, repo_pattern, clone hooks
- README/llms.txt/examples + unit tests + e2e scenarios

Default repo_pattern now places clones at owner/repo/<branch> where
<branch> is the remote's default branch, resolved via git ls-remote
--symref before cloning. This makes the clone directory a valid
main-worktree slot for sibling worktree strategies.

Falls back to "main" when the remote is unreachable.
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 43.76731% with 203 lines in your changes missing coverage. Please review.
✅ Project coverage is 37.85%. Comparing base (b29508f) to head (dddf5a6).

Files with missing lines Patch % Lines
cmd/clone.go 7.69% 120 Missing ⚠️
internal/tmpl/tmpl.go 0.00% 23 Missing ⚠️
cmd/category.go 75.00% 14 Missing and 6 partials ⚠️
cmd/info.go 0.00% 17 Missing ⚠️
cmd/config.go 60.97% 10 Missing and 6 partials ⚠️
cmd/shellenv.go 78.26% 5 Missing ⚠️
cmd/config_cmd.go 94.73% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #122      +/-   ##
==========================================
+ Coverage   37.62%   37.85%   +0.23%     
==========================================
  Files          28       31       +3     
  Lines        3216     3545     +329     
==========================================
+ Hits         1210     1342     +132     
- Misses       1917     2101     +184     
- Partials       89      102      +13     
Files with missing lines Coverage Δ
cmd/examples.go 67.74% <ø> (ø)
cmd/hooks.go 89.74% <100.00%> (+0.55%) ⬆️
cmd/root.go 70.78% <100.00%> (+0.33%) ⬆️
cmd/worktree_path.go 56.00% <100.00%> (-2.54%) ⬇️
cmd/config_cmd.go 71.08% <94.73%> (+12.59%) ⬆️
cmd/shellenv.go 78.82% <78.26%> (+0.12%) ⬆️
cmd/config.go 67.81% <60.97%> (-2.99%) ⬇️
cmd/info.go 0.00% <0.00%> (ø)
cmd/category.go 75.00% <75.00%> (ø)
internal/tmpl/tmpl.go 0.00% <0.00%> (ø)
... and 1 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@timvw

timvw commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Let me think about this (Original thinking was to focus on worktrees (only)... replicating git clone/init was intentionally not considered...)

@brosu

brosu commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Sure, take your time; I would see workspace management as a future enhancement as well.
The examples for one feature multiple repos gave me some ideas.
Of course, all that would extend the tool's responsibilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants