Skip to content

feat: orbit remove — drop a repo's worktree from a workspace - #44

Merged
zheng-weihao merged 6 commits into
orbcli:mainfrom
BUPT-wxq:main
Sep 21, 2026
Merged

zheng-weihao merged 6 commits into
orbcli:mainfrom
BUPT-wxq:main

Conversation

@BUPT-wxq

Copy link
Copy Markdown
Contributor

Inverse of orbit add: removes the worktree from the current workspace and (by default) deletes the scoped local branch add created. Pool repo is never touched.

  • Defaults mirror prune: refuses uncommitted changes / unmerged branches; --force overrides. --keep-branch leaves the branch behind.
  • Reuses orbit_branch_verdict (PR-merged / upstream-merged / content- upstream) for the branch decision so an unmerged branch is kept with a review hint instead of silently vanishing.
  • Order: compute verdict → remove worktree → delete branch. git refuses to delete a branch while a worktree has it checked out, mirroring the stale-worktree retry path in orbit_branch_delete.
  • Foreign repos (.git directory, not file) refuse without --force since their history lives only in the worktree.
  • --json output for tooling: workspace, repo, worktreeRemoved, branch, branchAction.

USAGE.md documents the command and its safety defaults. 16 new bats cases cover basic removal, --keep-branch / --force / --json, dirty / unmerged / foreign guards, error paths, and add→remove→add round-trip.

Verified against the full suite (411/412 pass; the single failure, prune: unregistered worktree warns and leaves it to directory removal, is pre-existing on main and unrelated).

What changed

Checklist

  • shellcheck orbit.sh install.sh passes
  • bats tests/ passes
  • New features include tests
  • Documentation updated (if user-facing behavior changed)

Inverse of `orbit add`: removes the worktree from the current workspace and
(by default) deletes the scoped local branch add created. Pool repo is
never touched.

- Defaults mirror prune: refuses uncommitted changes / unmerged branches;
  --force overrides. --keep-branch leaves the branch behind.
- Reuses orbit_branch_verdict (PR-merged / upstream-merged / content-
  upstream) for the branch decision so an unmerged branch is kept with a
  review hint instead of silently vanishing.
- Order: compute verdict → remove worktree → delete branch. git refuses
  to delete a branch while a worktree has it checked out, mirroring the
  stale-worktree retry path in orbit_branch_delete.
- Foreign repos (.git directory, not file) refuse without --force since
  their history lives only in the worktree.
- --json output for tooling: workspace, repo, worktreeRemoved, branch,
  branchAction.

USAGE.md documents the command and its safety defaults. 16 new bats
cases cover basic removal, --keep-branch / --force / --json, dirty /
unmerged / foreign guards, error paths, and add→remove→add round-trip.

Verified against the full suite (411/412 pass; the single failure,
`prune: unregistered worktree warns and leaves it to directory removal`,
is pre-existing on main and unrelated).
The branch-verdict bookkeeping tracked a label string (`merged`, `PR
merged`, `content upstream`, `force`) for symmetry with orbit_prune,
but it was never read in either the JSON output or the human report.
Drop the dead local; the verdict flag (-d / -D) still drives the actual
git branch command.

make lint now passes; bats tests/30_remove.bats still 16/16.
Comment thread USAGE.md Outdated

Options:

- `--keep-branch` — remove only the worktree; leave the scoped branch behind.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we need keep the branch, we can rebuilt the branch easily with orbit add

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call — orbit add rebuilds the scoped branch, so --keep-branch was paying complexity for nothing.

Per PR review feedback, the flag was redundant: orbit add rebuilds a
fresh scoped branch from origin when none exists locally, and the
default "delete the scoped branch" already matches the round-trip a
user actually wants when they re-add the repo. Removing the flag
shrinks the surface (default-refuses-dirty + --force to override is
the only safety knob) and avoids the asymmetric style where remove
had a flag prune does not.

Verified:
- 30_remove.bats: 15/15 green (the --keep-branch test was removed)
- orbit.sh --help shows the new usage line

Full bats suite still in flight; will report if anything regresses.
Comment thread USAGE.md Outdated
# Workspace lifecycle
orbit new "<goal>" [--name <name>] [--no-goal] [--exec "<cmd>"]
orbit add <repo> [--ref <tag/branch>] [-s|--silent]
orbit remove <repo> [--force] [--keep-branch] [--json]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remember to update skill for new command

Mirror the user-level ~/.qoder/skills/orbit/SKILL.md update:
- description trigger-words: add repo → add/remove repo
- command map: orbit remove <repo> [--force] [--json]
- safe-to-run-freely: classify remove as destructive but workspace-scoped
  (refuses dirty/unmerged work without --force), same call pattern as prune
  for one repo in your own workspace
Cover the two spots the previous skill-only commit missed:
the Work step's "drop a repo mid-work" path, and the
sub-agent briefing's Do NOT run list.
@zheng-weihao

Copy link
Copy Markdown
Member

Merging! The implementation cleanly reuses the existing helper chain (orbit_require_root to orbit_infer_workspace to orbit_branch_verdict), the safety model mirrors prune (dirty-refuse / unmerged-keep / foreign-guard with --force override), and the verdict then worktree then branch ordering is correct. Tests, docs, completion, and skill are all updated in lockstep. Solid work.

One non-blocking nit for the future: the rm -rf fallback in the worktree-removal path could add a shell parameter guard to match prune defensive style against empty variables. No rush.

First external contribution to orbit — huge thanks @BUPT-wxq for jumping in with a feature that fills a real gap. The add/remove round-trip is now complete. Looking forward to more!

@zheng-weihao
zheng-weihao merged commit 4673a1e into orbcli:main Sep 21, 2026
2 checks passed
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