Skip to content

feat: grove new and grove rm CLI subcommands#24

Merged
rrbe merged 3 commits into
mainfrom
feat/cli-new-rm
May 20, 2026
Merged

feat: grove new and grove rm CLI subcommands#24
rrbe merged 3 commits into
mainfrom
feat/cli-new-rm

Conversation

@rrbe
Copy link
Copy Markdown
Owner

@rrbe rrbe commented May 20, 2026

Summary

补齐 P0 的 CLI 入口:

  • grove new <branch> [flags] — 创建 worktree。flag: -b/--base-p/--path-r/--remote--existing--no-hooks-q/--quiet
  • grove rm [branch] [flags] — 删除 worktree。无参时默认删 cwd 所在 worktree;TTY 下交互确认([[feedback_dangerous_ops_confirm]] 兜底),非 TTY 必须 -y。flag: -f/--force-y/--yes--dry-run--prune--no-hooks

grove new -q 让脚本可以 cd "\$(grove new feat/foo -q -b origin/main)",stdout 只输出路径,所有日志走 stderr。

实现

actions.rs 仿 run_hooks_cli 的模式:

  • 提取 plan_create_worktreecreate_worktree_cli
  • plan_remove_worktree_executionskip_hooks 参数 → remove_worktree_cli
  • 抽出 build_cli_state / read_cli_defaults 三个 CLI 入口共用

CLI 示例

```bash
grove new feat/login # 默认 base + 默认路径 + hooks
grove new feat/login -b develop -p ../scratch
grove new feat/login -r origin/feat/login # 跟踪远程
grove new feat/login --existing # 把已有分支放进 worktree
grove new feat/login --no-hooks -q # 脚本模式

grove rm feat/login # TTY 下问 [y/N]
grove rm feat/login -y --prune # 跳过确认 + 顺手 prune
grove rm # 删 cwd 所在 worktree
grove rm feat/login --dry-run # 仅打印计划
```

Test plan

  • cargo test 31/31 通过
  • cargo clippy --all-targets 干净
  • pnpm build 干净
  • CLI 烟雾测试:
    • new 普通模式 + -q quiet 模式 → stdout 只有路径
    • rm dry-run / 非 TTY 拒绝 / -y 真删 / --prune 触发 prune
    • branch 不存在 → 友好错误,exit 1
  • GUI 回归:在 GUI 里建/删 worktree 验证 actions.rs 重构没影响(plan_remove_worktree_execution 新加的 skip_hooks 参数所有 GUI 调用点都传 false)

备注

🤖 Generated with Claude Code

rrbe and others added 3 commits May 20, 2026 12:32
`grove new <branch>` creates a worktree, honouring base/path/remote/
existing/no-hooks flags. `-q` prints only the resulting path on stdout
(logs on stderr) so it composes with `cd "$(grove new feat/foo -q)"`.

`grove rm [branch]` removes a worktree — defaults to the one
containing the cwd when no branch is given. Prompts for confirmation
in a TTY, requires `-y` otherwise. `--dry-run`, `--force`, `--prune`
and `--no-hooks` cover the remaining ergonomics.

Extracts `plan_create_worktree` and adds `create_worktree_cli` /
`remove_worktree_cli` that build a transient SharedState and stream
logs to stdout, mirroring the existing `run_hooks_cli` pattern.
`plan_*_worktree_*` now takes `skip_hooks` so `--no-hooks` is a flag
rather than post-hoc step filtering. `build_cli_state` /
`read_cli_defaults` are shared by all three CLI entry points.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- grove rm --dry-run now previews dirty and main-worktree cases
  instead of exiting 1; the blocking checks only fire on real runs
- confirmation prompt names the branch and the worktree path so it's
  unambiguous which one you're about to delete
- plan output surfaces force: yes when -f is set
- cmd_rm streams git output via StderrLogWriter so stdout stays empty
  for future --json structured output
- resolve_rm_target gets unit tests for branch match / cwd inference /
  unknown branch cases

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- run_steps helper replaces five copies of \`for step in steps { step.run(sink)?; }\`
  across run_hooks_cli, create_worktree_cli, remove_worktree_cli,
  run_session_execution, and execute
- persist_recent_repo wraps the lock + push_recent + persist pattern
  that the two CLI action paths shared
- create_worktree_cli / remove_worktree_cli now accept &SharedState
  from the caller, so grove rm no longer reloads ~/.grove/store.json
  after scanning worktrees
- cmd_rm collects is_main / dirty blockers into a single list and
  applies them in one place, replacing the three-level nested
  dry-run/error conditionals

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rrbe rrbe merged commit 7eac17a into main May 20, 2026
3 checks passed
@rrbe rrbe deleted the feat/cli-new-rm branch May 20, 2026 06:55
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.

1 participant