Skip to content

refactor(switch): unify the picker and argument-path switch pipelines - #2858

Merged
max-sixty merged 3 commits into
mainfrom
consolidate-switch-pipeline
May 21, 2026
Merged

refactor(switch): unify the picker and argument-path switch pipelines#2858
max-sixty merged 3 commits into
mainfrom
consolidate-switch-pipeline

Conversation

@max-sixty

@max-sixty max-sixty commented May 21, 2026

Copy link
Copy Markdown
Owner

Summary

wt switch <branch> and the interactive picker (wt switch with 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 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_switchapprove_switch_hooksvalidate_switch_templatesexecute_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).

max-sixty and others added 2 commits May 21, 2026 09:14
`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>
…peline

# Conflicts:
#	src/commands/worktree/switch.rs
@max-sixty
max-sixty merged commit e4dd591 into main May 21, 2026
34 checks passed
@max-sixty
max-sixty deleted the consolidate-switch-pipeline branch May 21, 2026 16:47
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>
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