Skip to content

fix(up): track remote-only branches; refuse slug collisions with a different branch#22

Merged
hefgi merged 1 commit into
mainfrom
claude/magical-einstein-7m4g40-branches
Jun 11, 2026
Merged

fix(up): track remote-only branches; refuse slug collisions with a different branch#22
hefgi merged 1 commit into
mainfrom
claude/magical-einstein-7m4g40-branches

Conversation

@hefgi

@hefgi hefgi commented Jun 11, 2026

Copy link
Copy Markdown
Owner

Fixes #6

Remote-only branches are now tracked, not forked (worktree.rs)

WorktreeManager::create decided between "reuse branch" and "create new branch from HEAD" using git branch --listlocal branches only. A branch existing only on origin (the typical "resume this PR branch" agent workflow) took the -b path: a brand-new branch forked from the current HEAD under the same name, silently on the wrong base.

create() now has three cases:

  1. local branch exists → worktree add <path> <branch> (unchanged)
  2. refs/remotes/origin/<branch> exists (checked via rev-parse --verify, no network) → worktree add --track -b <branch> <path> origin/<branch>
  3. neither → new branch from HEAD (unchanged)

Slug collisions no longer silently resume the wrong branch (main.rs)

Slugs are sanitized branch names (feat/foofeat-foo), so two different branches can collide on one slug. The resume path matched by slug only: ecluse up feat/foo against a session created from branch feat-foo silently resumed the other branch.

New rule, preserving normal resume ergonomics:

  • up <slug> (exact slug match) → resumes, as before
  • up <branch> where the branch matches the session's branch → resumes, as before
  • explicit argument that sanitizes to an existing slug but is a different branch → error naming the session's actual branch, with ecluse down <slug> as the next step

Tests

  • create_tracks_remote_only_branch — upstream + clone fixture; asserts the worktree's branch tracks origin/feat-remote and starts at the remote tip, not at HEAD (fails on the old fork-from-HEAD behavior)
  • integration up_with_colliding_branch_name_errorsup feat-foo, then up feat/foo errors, then up feat-foo still resumes
  • test fixtures now pass -c commit.gpgsign=false so the suite runs in environments with commit signing configured globally

cargo fmt --check, cargo clippy -- -D warnings, cargo test (370 + 19) green.

https://claude.ai/code/session_017UcuvzMKHVfyBCcq8ipAko


Generated by Claude Code

…fferent branch

Two branch-resolution gaps:

WorktreeManager::create only checked local branches, so a branch that
exists on origin but not locally (the resume-a-PR-branch workflow) was
forked fresh from HEAD under the same name — silently the wrong base.
create() now checks refs/remotes/origin/<branch> (no network) and uses
'worktree add --track -b <branch> origin/<branch>' for remote-only
branches.

The resume path matched sessions by slug only. Slugs are sanitized
branch names (feat/foo -> feat-foo), so 'ecluse up feat/foo' silently
resumed a session created from branch 'feat-foo' — wrong branch, no
signal. An explicit argument now resumes only when it matches the
session's slug or exact branch; a colliding branch errors with the
session's actual branch and a next step.

Test fixtures additionally disable commit signing so they work in
environments with commit.gpgsign=true.

Fixes #6

https://claude.ai/code/session_017UcuvzMKHVfyBCcq8ipAko
@hefgi hefgi merged commit b6980f5 into main Jun 11, 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.

up branch resolution: slug collision silently resumes a different branch; remote-only branches are forked from HEAD instead of tracked

2 participants