refactor(switch): unify the picker and argument-path switch pipelines - #2858
Merged
Conversation
`wt switch <branch>` (run_switch) and the interactive picker each ran the same switch sequence as separate code. Both now build a `SwitchPipeline` and call `.run()`, which owns the whole sequence: bare-repo path-fix, pre-switch hooks, source-identity capture, plan -> approve -> validate -> execute, output, background hooks, and `--execute`. The picker-vs-argument differences are struct field values, not divergent code. This also fixes a bug the duplication hid: the picker passed `yes=true` to `run_pre_switch_hooks`, auto-approving project `pre-switch` hooks without the approval prompt every other picker hook goes through. There is now one `run_pre_switch_hooks` call gated by the pipeline's single `verify`/`yes` pair, so the picker (no `--yes`) prompts for project `pre-switch` hooks like `wt switch <branch>` does. Adds `test_switch_picker_pre_switch_hook_requires_approval` covering the fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
worktrunk-bot
approved these changes
May 21, 2026
…peline # Conflicts: # src/commands/worktree/switch.rs
max-sixty
added a commit
that referenced
this pull request
May 23, 2026
…#2858) ## Summary `wt switch <branch>` and the interactive picker (`wt switch` with no argument) each ran the same switch sequence as separate, parallel code. [#2845](#2845) made the two paths *behave* identically; this makes the *code* identical too — a single `SwitchPipeline` that both entry points build and `.run()`. `SwitchPipeline::run` (in `src/commands/worktree/switch.rs`) owns the whole sequence: the bare-repo worktree-path fix-up, pre-switch hooks, source-identity capture, `plan_switch` → `approve_switch_hooks` → `validate_switch_templates` → `execute_switch`, output, background hooks, and `--execute`. Each caller now only resolves a branch identifier and loads config. The picker-vs-argument differences (`--execute`, the shell-integration offer, source-identity capture) are struct field values, not divergent branches. ## Bug fixed The duplication hid a real bug: the picker passed `yes = true` to `run_pre_switch_hooks`, **auto-approving project `pre-switch` hooks without a prompt** — unapproved code from a freshly cloned `.config/wt.toml` running silently. Every other hook the picker runs (`post-switch`, `pre-create`, `post-create`) already went through the approval prompt. With one shared `run_pre_switch_hooks` call gated by the pipeline's single `verify`/`yes` pair, the picker (which has no `--yes`) now prompts for project `pre-switch` hooks like `wt switch <branch>` does — and the two paths can't drift on hook approval again. ## Reviewer notes - One intentional reorder on the argument path: `offer_bare_repo_worktree_path_fix` now runs before `run_pre_switch_hooks` (the picker already used this order). The fix only mutates `worktree-path` config, which pre-switch hooks never read — behavior-neutral. - `capture_switch_source` runs inside `run()` after pre-switch hooks — the same relative position as the old `run_switch`. - Eight now-internal helpers were narrowed from `pub`/`pub(crate)` to private; `worktree/mod.rs` re-exports trimmed accordingly. ## Testing Pure refactor — the existing `test_switch_*`, `test_switch_format_json_*`, and `test_switch_picker_*` suites cover behavior preservation. `test_switch_picker_pre_switch_hook_requires_approval` is a new regression test for the bug fix (verified to fail under the bug). --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Jul 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
wt switch <branch>and the interactive picker (wt switchwith no argument) each ran the same switch sequence as separate, parallel code. #2845 made the two paths behave identically; this makes the code identical too — a singleSwitchPipelinethat both entry points build and.run().SwitchPipeline::run(insrc/commands/worktree/switch.rs) owns the whole sequence: the bare-repo worktree-path fix-up, pre-switch hooks, source-identity capture,plan_switch→approve_switch_hooks→validate_switch_templates→execute_switch, output, background hooks, and--execute. Each caller now only resolves a branch identifier and loads config. The picker-vs-argument differences (--execute, the shell-integration offer, source-identity capture) are struct field values, not divergent branches.Bug fixed
The duplication hid a real bug: the picker passed
yes = truetorun_pre_switch_hooks, auto-approving projectpre-switchhooks without a prompt — unapproved code from a freshly cloned.config/wt.tomlrunning silently. Every other hook the picker runs (post-switch,pre-create,post-create) already went through the approval prompt. With one sharedrun_pre_switch_hookscall gated by the pipeline's singleverify/yespair, the picker (which has no--yes) now prompts for projectpre-switchhooks likewt switch <branch>does — and the two paths can't drift on hook approval again.Reviewer notes
offer_bare_repo_worktree_path_fixnow runs beforerun_pre_switch_hooks(the picker already used this order). The fix only mutatesworktree-pathconfig, which pre-switch hooks never read — behavior-neutral.capture_switch_sourceruns insiderun()after pre-switch hooks — the same relative position as the oldrun_switch.pub/pub(crate)to private;worktree/mod.rsre-exports trimmed accordingly.Testing
Pure refactor — the existing
test_switch_*,test_switch_format_json_*, andtest_switch_picker_*suites cover behavior preservation.test_switch_picker_pre_switch_hook_requires_approvalis a new regression test for the bug fix (verified to fail under the bug).