Skip to content

feat: add -b/--use-branch to reuse an existing branch (+ cloud.useCurrentBranch)#13

Merged
madarco merged 2 commits into
mainfrom
agentbox/use-branch
May 28, 2026
Merged

feat: add -b/--use-branch to reuse an existing branch (+ cloud.useCurrentBranch)#13
madarco merged 2 commits into
mainfrom
agentbox/use-branch

Conversation

@madarco
Copy link
Copy Markdown
Owner

@madarco madarco commented May 28, 2026

Summary

  • Adds -b, --use-branch <name> to create / claude / codex / opencode: the box checks out an existing branch directly instead of forking a per-box agentbox/<box-name> branch, so commits and git push flow straight to it. Mutually exclusive with --from-branch.
  • Adds a cloud.useCurrentBranch config key: on cloud providers (daytona/hetzner) only, default new boxes onto the host's current branch. Cloud-only because docker would collide in git's worktree registry.
  • Rebinds -b from --no-attach to --use-branch everywhere; --no-attach is now -d.

Behavior

  • docker: git worktree add <wt> <branch> (no -b, no base ref, no host stash/untracked carry-over — the box gets the branch's committed tip). If the host already has <name> checked out, git fails with fatal: '<name>' is already used by worktree at '...'; the box and any worktree registration are then torn down (autoclean) so a retry isn't blocked. Other seed failures keep the existing inspect-on-failure behavior.
  • cloud (daytona/hetzner): the host clone pins --branch <name> and the in-sandbox checkout drops the -B reset, via the shared createCloudProvider + seedCloudWorkspace path. Applies to the root repo only; nested repos keep their per-box branches.
  • Destroying a --use-branch box leaves the branch ref intact (only the worktree registration is removed).

Test plan

  • pnpm build, pnpm lint, pnpm test green (330+ tests; no test relied on the old -b/--no-attach mapping)
  • --help shows -b, --use-branch and -d, --no-attach across all four commands; cloud.useCurrentBranch registers in agentbox config
  • Mutex (--from-branch + --use-branch) and unknown-branch both exit 2 before any provider work
  • docker e2e: created a box with --use-branch foo (foo not checked out) → box HEAD = foo, tip matched host; destroy preserved foo, pruned the worktree registry
  • docker collision e2e: with foo checked out on the host → fatal: '...' is already used by worktree, exit 1, autoclean removed the container + left no orphan worktree
  • hetzner live VPS smoke: not run from the sandbox (no HCLOUD_TOKEN there); the code path is identical to the validated daytona path by construction (createCloudProvider + seedCloudWorkspace)

Note

Medium Risk
Changes default git/CLI behavior (-b flag remap) and worktree collision handling; mistakes could affect where commits land or leave failed creates cleaned up aggressively on Docker.

Overview
Adds -b, --use-branch so boxes can work on an existing branch (commits/push go to that branch) instead of always forking agentbox/<box-name>. --from-branch still only picks the base for a new fork; the two flags are mutually exclusive, validated up front via shared resolveBranchSelection.

CLI: Wired on create, claude, codex, and opencode. -b is repurposed from --no-attach to --use-branch; --no-attach is now -d. New config cloud.useCurrentBranch (default off): on non-Docker providers, new boxes default to the host’s current branch when no branch flags are set (Docker skipped to avoid worktree collisions).

Docker: Root repo uses git worktree add <wt> <branch> (no -b), skips host stash/untracked carry-over, and on --use-branch seed failure removes the container and worktree instead of leaving a debuggable half-created box.

Cloud: Box branch becomes useBranch ?? agentbox/<name>; clone pins the branch and in-sandbox checkout avoids checkout -B reset when reusing.

Reviewed by Cursor Bugbot for commit 23e8b13. Configure here.

…loud.useCurrentBranch

Boxes always forked a per-box `agentbox/<box-name>` branch. `-b/--use-branch
<name>` instead checks out an existing branch directly so commits and pushes
flow straight to it. Mutually exclusive with --from-branch.

- docker: `git worktree add <wt> <branch>` (no -b/base, no stash carry-over);
  on a collision with a branch the host already has checked out, the box and
  any worktree registration are torn down instead of left for inspection.
- cloud (daytona/hetzner): the clone pins `--branch <name>` and the in-sandbox
  checkout drops the `-B` reset, via the shared createCloudProvider +
  seedCloudWorkspace path.
- cloud.useCurrentBranch config: default cloud boxes onto the host's current
  branch (cloud-only; docker would collide in the worktree registry).
- rebinds -b from --no-attach to --use-branch across claude/codex/opencode;
  --no-attach is now -d.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 23e8b13. Configure here.

? 'clone: depth=full (configured)'
: `clone: depth=${String(initialDepth)} (configured)`,
);
await runShallowClone(args.hostRepo, cloneDir, initialDepth, stashRefCreated, args.fromBranch);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cloud --use-branch applies stash from wrong branch

Medium Severity

When useBranch is set in the cloud path, seedFromGitClone still unconditionally captures and applies the host's uncommitted state via safeStashCreate and maybeBuildUntrackedTar. The Docker path explicitly skips carry-over for --use-branch (setting stashSha: null, untrackedNul: ''). In the cloud path, if the user runs --use-branch feature-xyz while their host is on main with uncommitted changes, those irrelevant main-branch changes get applied onto feature-xyz's tip, potentially corrupting the working tree.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 23e8b13. Configure here.

The cloud `--use-branch` path still captured the host's stash + untracked
files and applied them onto the reused branch, so uncommitted changes from a
different branch could land on (and corrupt) the target branch's tip. Gate
the carry-over on `!useBranch`, matching the docker reuse path which already
builds its RepoCarryOver with a null stash / empty untracked set.

Found by Cursor Bugbot on #13.
@madarco madarco merged commit eebb268 into main May 28, 2026
1 check 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.

1 participant