feat: repeatable -b flag for multi-branch clone#324
Merged
Conversation
Covers repeatable -b flag, BranchSource abstraction, shared OperationTable TUI component, gitoxide integration, and layout-dependent behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Clarify cd target fallback to base worktree for non-bare layouts - Add BranchSource::All fallback when default branch missing on remote - Derive failures from FinalStatus instead of separate accumulation - Add OperationPhase::Setup match site update list - Map new TaskMessage variants to FinalStatus - Specify --no-checkout and --remote interaction with multiple -b - Note BareCloneParams.branch remains Option<String> internally - Fix gitoxide: new local-ref functions, not existing network-based ones - Fix config_snapshot_mut reference to use CLI config writes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Define cd target for BranchSource::All (base worktree) - Specify TaskId::Setup(String) variant and concrete match sites Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 tasks covering BranchSource types, DAG event extensions, gitoxide local ref validation, OperationTable extraction, sync/prune refactor, CLI changes, TUI wiring, completions, and YAML test scenarios. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix TableConfig to use verbosity: u8 (not show_hook_sub_rows bool) - Map Created/BaseCreated to FinalStatus::Updated per spec (no new variant) - Add check_phase_completion() to OperationPhase match update list - Fix OperationTable to accept Vec<OperationPhase> and Vec<WorktreeInfo> - Clarify Phase 2/3 execution order (layout before branch resolution) - Add missing unit tests: empty repo, All with absent default branch - Add --remote + multiple -b conflict YAML scenario - Add Task 12: audit --all-branches hook firing - Add Task 13: partial failure summary output - Add Task 14: docs/cli reference page update Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends TaskId, OperationPhase, and TaskMessage enums with new variants needed by the clone command's TUI table, and adds unreachable arms in sync/prune to keep all matches exhaustive. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduce `OperationTable`, `TableConfig`, and `CompletedTable` in `src/output/tui/operation_table.rs` as a reusable wrapper around `TuiState` + `TuiRenderer`. sync, prune, and clone can consume this component without each reimplementing the wiring. `TableConfig.verbosity` (u8) replaces the old `show_hook_sub_rows` bool, computed as `verbosity >= 1` inside `OperationTable::run()`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace manual TuiState::new() + TuiRenderer::new() + renderer.run() wiring in the sync command with the OperationTable abstraction. Update check_tui_failures() to accept &[WorktreeRow] so both sync and prune can use it with their respective result types. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace manual TuiState::new() + TuiRenderer::new() wiring in the prune TUI path with OperationTable + TableConfig, following the same pattern established in the sync refactor (Task 5). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Change the clone command's -b/--branch flag from Option<String> to Vec<String> with clap::ArgAction::Append, allowing users to specify multiple branches (e.g. -b main -b feat-x). Construct BranchSource from the args immediately after validation. Add a --remote + multiple -b conflict check. Update man pages and CLI docs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After layout resolution, resolve branches against the remote using BranchPlan. For multi-branch clones (BranchSource::Multiple), Phase 4 creates the base worktree, then Phase 5 creates satellite worktrees sequentially with spinner-based output. The cd_target is resolved from the branch plan's preference, falling back to the base worktree. Single-branch and default cases are entirely unchanged - the new code path only activates for Multiple branch sources. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Canonicalize parent_dir from git_dir (already absolute) instead of using the relative path that Phase 4 may have cd'd away from - Fix set_upstream to pass explicit branch name so it works regardless of cwd (git branch --set-upstream-to=origin/b b) - Remove duplicate inline satellite loop in commands/clone.rs, delegate to clone::create_satellite_worktree() from core Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When cloning with multiple -b flags on an interactive terminal, the satellite worktree creation phase now uses an OperationTable TUI that shows per-worktree status and hook execution (worktree-pre-create / worktree-post-create) in real time, matching the sync/prune pattern. The TUI path activates when stderr is a TTY and --verbose is not set. Non-TTY and verbose modes fall back to the existing sequential spinner path. Two operation phases are shown: a pre-completed Fetch phase (bare clone already ran) and an active Setup phase for worktree creation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace silent `if let Ok` patterns for `HookExecutor::new()` in `create_satellite_worktrees_tui()` with explicit `match` blocks that send failure events through the DAG channel when initialization fails, preventing worktrees from being silently created as if hooks passed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add HEAD and @ as static completion values for the -b/--branch flag in the git-worktree-clone command across bash, zsh, and fish shells. Regenerate CLI docs to reflect the updated clone command reference. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Six scenarios covering the -b flag with multiple values: - contained layout (bare repo, multiple worktrees) - sibling layout (default branch injected as base) - HEAD/@ token resolution to default branch - nonexistent branch warning with partial success - post-clone hook fires for the cd_target worktree - --remote conflicts with multiple -b (exit 1) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After the TUI completes, print a summary of failed satellite worktrees (e.g. "Created 3 of 5 worktrees (2 failed)") with per-branch error reasons. Failure reasons are now stored on WorktreeRow.failure_reason and populated from TaskMessage::Failed in TuiState::apply_event. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…licate Three bugs fixed in the multi-branch clone feature: 1. Base worktree now appears as a pre-completed row in the TUI table (sends TaskStarted + TaskCompleted with BaseCreated immediately). 2. worktree-post-create hook no longer fires twice — the CliPresenter banner after the TUI is skipped when the TUI path already ran per-satellite hooks. 3. Bare layout no longer attempts to create a duplicate worktree for the branch that Phase 4 already set up (filtered from satellites before passing to both TUI and sequential creation paths). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- (none): TUI table with hooks hidden - -v: TUI table with hook sub-rows visible - -vv: sequential mode, full output (no TUI) Matches the sync/prune verbosity pattern. Passes verbosity through to OperationTable's TableConfig for hook sub-row control. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the layout.needs_bare() guard that prevented worktree-post-create from firing for contained/bare layouts during single-branch clone. Add worktree-post-create hook execution for the base worktree in the TUI multi-branch path. Add pre-create and post-create hook execution for satellite worktrees in the sequential multi-branch path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clone TUI table defaults to showing Branch, Base, Age, and Commit columns. Users can override with --columns (same syntax as sync/prune). Adds CommandKind::Clone and ListColumn::clone_defaults() to the column selection system. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…aths Two fixes for the multi-branch clone TUI table: 1. Base, Age, and Commit columns now show actual data instead of being empty. After each worktree is created (both base and satellites), commit metadata is fetched via gitoxide and sent as updated_info in the TaskCompleted event. 2. Path column for bare layouts now shows repo-relative paths (e.g., "repo/branch") instead of just the branch name, by using repo_path.join(branch) instead of PathBuf::from(branch). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Default clone columns: Branch, Path, Base, Age, Commit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use parent of repo_path as display_root so paths render as "tax-analyzer/feature" instead of just "feature". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
relative_display_path resolves paths relative to cwd first. Since cwd was repo_path, paths like repo_path/feature rendered as just "feature". Setting cwd to repo_path.parent() makes them render as "repo/feature". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The base worktree path was computed from layout templates, which gave wrong results for non-contained layouts (nested, sibling). Now uses base_result.worktree_dir — the real path Phase 4 created. This also fixes hooks not firing for the base worktree in nested layout since the hook context was receiving the wrong path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
For contained-classic layout, git_dir moves into a branch subdirectory (e.g., repo/master/.git), so git_dir.parent() gave repo/master instead of repo. This caused satellites to be created under repo/master/feature instead of repo/feature. Use base_result.parent_dir (the repo root) which is correct for all layouts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 4 (setup_wrapped_nonbare) moves .git into a branch subdirectory and changes cwd. The relative parent_dir becomes unreachable after that. Canonicalize it before Phase 4 runs and propagate the absolute path to satellite creation functions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After clone_bare_phase, cwd is inside the repo directory. Using canonicalize on the relative parent_dir looked for repo/repo which doesn't exist. current_dir() gives the correct absolute path since we're already inside the repo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
For contained-classic, .git lives inside the base worktree (e.g., repo/master/.git). The repo root has no .git, so git worktree add fails when run from there. Now cds to the base worktree directory where git can discover the repo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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
-brepeatable so users can clone multiple branches at once:git worktree clone <url> -b feat-a -b feat-bHEADand@as-bvalues meaning "the remote's default branch"-b/--all-branchesunder aBranchSourceabstraction withDefault,Single,Multiple,AllvariantsOperationTableTUI component from sync/prune — all three commands now share the same table infrastructureworktree-pre-create/worktree-post-createhook presentation--columnsflag to clone with defaults: Branch, Path, Base, Age, Commit-vfrom bool to u8 count (no flag = TUI,-v= TUI with hooks,-vv= sequential)worktree-post-createfor every worktree created during clone (previously skipped for bare layouts)Test plan
mise run cipasses (fmt, clippy, unit tests, man page verification)git worktree clone <url> -b @ -b feat --layout containedgit worktree clone <url> -b @ -b feat --layout siblinggit worktree clone <url> -b @ -b feat --layout nestedgit worktree clone <url> -b @ -b feat --layout contained-classic-bbackward compatibility--all-branchesunchanged behavior-vshows hook sub-rows,-vvshows sequential outputFixes #321
🤖 Generated with Claude Code