Skip to content

[fix] Protect worktree operands with separator#256

Open
loopassembly wants to merge 1 commit into
lugassawan:mainfrom
loopassembly:codex/worktree-separator-hardening
Open

[fix] Protect worktree operands with separator#256
loopassembly wants to merge 1 commit into
lugassawan:mainfrom
loopassembly:codex/worktree-separator-hardening

Conversation

@loopassembly

Copy link
Copy Markdown

Closes #252.

What changed

  • Pass AddWorktree path/source operands after --, matching the existing AddWorktreeFromBranch hardening.
  • Build MoveWorktree args with force flags first, then --, then the old/new path operands.
  • Add focused mock-runner tests for the exact git argv shape.

Why

This keeps dash-leading sources or paths from being parsed as git options, while preserving the existing double---force behavior for locked worktree moves.

Validation

  • go test ./internal/git
  • go test ./...

Pass AddWorktree and MoveWorktree positional operands after -- so dash-leading sources or paths stay data instead of being parsed as git options.

Keep MoveWorktree force flags before the separator, and cover the exact argv shape with focused mock runner tests.
Copilot AI review requested due to automatic review settings June 4, 2026 08:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR strengthens Git worktree command invocation by inserting -- to terminate option parsing, preventing paths/refs that begin with - from being misinterpreted as flags.

Changes:

  • Inserted -- into git worktree add argument list before positional args.
  • Refactored git worktree move argument construction to place -- after options.
  • Added/updated tests to assert the exact argument sequences passed to the runner.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
internal/git/worktree.go Inserts -- into worktree add/move commands to safely separate options from positional arguments.
internal/git/mock_runner_test.go Adds tests asserting -- insertion and updates force-move test to compare full expected args.

@loopassembly loopassembly changed the title fix(git): protect worktree operands with separator [fix] Protect worktree operands with separator Jun 4, 2026
Comment thread internal/git/worktree.go
if force {
args = append(args, flagForce, flagForce)
}
args = append(args, "--", oldPath, newPath)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

High — git worktree move may not support -- as end-of-options separator

git worktree add explicitly lists -- in its synopsis; git worktree move does not. The generated invocation is now:

git worktree move --force --force -- /old /new

If move does not recognise -- as end-of-options, git reads -- as <worktree> and /old as <new-path>, silently moving the wrong worktree (or erroring). Verify empirically in a temp repo:

git worktree move -- /some/path /other/path

If git rejects it, the -- must be omitted for move (or conditioned on the operands actually starting with -). A targeted integration test would catch this definitively.

}
}

func TestMoveWorktreeInsertsDashDash(t *testing.T) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Medium — TestMoveWorktreeNoForce is now fully subsumed by this test

TestMoveWorktreeNoForce (line 335) calls MoveWorktree(r, "/old/path", "/new/path", false) and asserts !slices.Contains(captured, flagForce). This new test makes the same call and asserts slices.Equal(captured, want) — which already guarantees no --force (since want excludes it). The older test adds zero additional coverage.

Suggested: delete TestMoveWorktreeNoForce (or collapse both no-force tests into a table-driven test alongside TestMoveWorktreeForce to keep all three cases in one place).

@lugassawan lugassawan left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Review Decision: COMMENT


Reviewed by reviewer (swe-workbench). Posted 2 inline comments, deduped 0.

Informational (out-of-diff)

Medium — RemoveWorktree (worktree.go:42) still passes path as a bare positional (not in this diff)

RemoveWorktree was not in the #229 hardening sweep and was not touched in this PR either. A path beginning with - is passed directly to git and parsed as a flag. Suggested: restructure to ["worktree", "remove", "--force"?, "--", path], mirroring the pattern established by this PR — and empirically verify that git worktree remove honours -- (same check recommended for move).

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.

[bug] AddWorktree missing -- separator (option injection, #229 regression)

3 participants