Coverage for src/workstack/cli/commands/down.py: 92%
25 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-19 09:31 -0400
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-19 09:31 -0400
1from pathlib import Path
3import click
5from workstack.cli.commands.switch import (
6 _activate_root_repo,
7 _activate_worktree,
8 _ensure_graphite_enabled,
9 _resolve_down_navigation,
10)
11from workstack.cli.core import discover_repo_context
12from workstack.cli.graphite import find_worktree_for_branch
13from workstack.core.context import WorkstackContext
16@click.command("down")
17@click.option(
18 "--script", is_flag=True, help="Print only the activation script without usage instructions."
19)
20@click.pass_obj
21def down_cmd(ctx: WorkstackContext, script: bool) -> None:
22 """Move to parent branch in Graphite stack.
24 With shell integration (recommended):
25 workstack down
27 The shell wrapper function automatically activates the worktree.
28 Run 'workstack init --shell' to set up shell integration.
30 Without shell integration:
31 source <(workstack down --script)
33 This will cd to the parent branch's worktree (or root repo if parent is trunk),
34 create/activate .venv, and load .env variables.
35 Requires Graphite to be enabled: 'workstack config set use_graphite true'
36 """
37 _ensure_graphite_enabled(ctx)
38 repo = discover_repo_context(ctx, Path.cwd())
40 # Get current branch
41 current_branch = ctx.git_ops.get_current_branch(Path.cwd())
42 if current_branch is None:
43 click.echo("Error: Not currently on a branch (detached HEAD)", err=True)
44 raise SystemExit(1)
46 # Get all worktrees for checking if target has a worktree
47 worktrees = ctx.git_ops.list_worktrees(repo.root)
49 # Resolve navigation to get target branch or 'root'
50 target_name = _resolve_down_navigation(ctx, repo, current_branch, worktrees)
52 # Check if target_name refers to 'root' which means root repo
53 if target_name == "root":
54 _activate_root_repo(repo, script, "down")
56 # Resolve target branch to actual worktree path
57 target_wt_path = find_worktree_for_branch(worktrees, target_name)
58 if target_wt_path is None:
59 # This should not happen because _resolve_down_navigation already checks
60 # But include defensive error handling
61 click.echo(
62 f"Error: Branch '{target_name}' has no worktree. This should not happen.",
63 err=True,
64 )
65 raise SystemExit(1)
67 _activate_worktree(repo, target_wt_path, script, "down")