Skip to content

feat(worktree): let slot worktrees be collected under a configured root - #64

Open
msabel-lang wants to merge 1 commit into
Himmelschmidt:mainfrom
msabel-lang:feat/configurable-worktree-root
Open

feat(worktree): let slot worktrees be collected under a configured root#64
msabel-lang wants to merge 1 commit into
Himmelschmidt:mainfrom
msabel-lang:feat/configurable-worktree-root

Conversation

@msabel-lang

Copy link
Copy Markdown

Optional, and off by default — unlike #62 and #63, this is a feature request rather than a bug, so ignore it freely if the sibling layout is a deliberate call.

Slot worktrees are cut as siblings of the repo, ../<repo>-spar-<run>-<slot>. That keeps them next to the thing they belong to, which is a reasonable default. But on a box that keeps all its repos in one directory, every run scatters directories into the folder the user reads every day — and in my case one that already held 22 unrelated git worktrees.

worktree.root makes that a choice:

[worktree]
# unset (default) → ../<repo>-spar-<run>-<slot>, exactly as today
root = "~/projects/spar/worktrees"   # → <root>/<repo>/<run>-<slot>

Unset, nothing changes — the sibling path is still the default and the existing path_shape test still pins it. Set, every worktree spar owns has one place to be inspected and one place to be swept, and rm -rf on it is never dangerous.

Design note

worktree_path takes the root as an argument rather than reading config itself.

My first cut resolved it inside the function via Config::for_run. That was wrong: it made a path helper depend on ambient user config, so path_shape would pass or fail based on whether the machine running it happened to have the setting — the exact trap #62 is about. The two production call sites already hold the run's config, so the caller resolves it via worktree_root and the helper stays a pure function of its arguments. Costs a few more edits; keeps the tests hermetic.

It's read through the run's config snapshot, so a run keeps the root it was created with. Moving the setting mid-run would otherwise strand worktrees already on disk and the recovery path in prepare_isolation wouldn't find them.

Dry-run is unaffected — it never calls create_worktree, it makes ephemeral cwds under .spar/runs/<id>/.

Verified

Three new unit tests (configured root, unset default, ~ expansion), plus a live run on a real project: worktrees landed at <root>/<repo>/<run>-<slot> with nothing beside the repo. Full suite 463 passed, 0 failed.

Slot worktrees are cut as siblings of the repo, `../<repo>-spar-<run>-<slot>`.
That keeps them next to the thing they belong to, but it also means every run
scatters directories into whatever holds the project — which for a machine that
keeps its repos in one place is the same directory the user reads every day, and
already shares with unrelated worktrees.

Add `worktree.root`. Unset, nothing changes: the sibling path is still the
default and the existing `path_shape` test still pins it. Set, runs are collected
at `<root>/<repo>/<run>-<slot>`, so a project's parent stays clean and every
worktree spar owns has one place to be inspected, and one place to be swept.

`worktree_path` takes the root as an argument rather than reading config itself.
Resolving it inside would make a path helper depend on ambient user config, and
its own tests would then pass or fail based on whether the machine running them
happens to have the setting — which is exactly the trap `path_shape` would fall
into. The two production call sites already hold the run's config, so the caller
resolves it via `worktree_root` and the helper stays a pure function of its
arguments.

Read through the run's config snapshot, so a run keeps the root it was created
with. Moving the setting mid-run would otherwise strand worktrees already on
disk, and the recovery path in `prepare_isolation` would not find them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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