mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
[bug] push_branch: push the named task branch, not the clone root's current checkout
push_branch(branch_name) resolved the workspace from the branch then called self.push(workspace) with no branch arg, so push() defaulted to get_current_branch(workspace) — the clone root's current checkout. In the F123 per-task-worktree model the clone root is parked on the default branch while the task branch lives in a worktree, so open_pr's push_branch pushed the wrong ref, the dev's commit stayed local-only, and gh pr create 422'd with 'No commits between' — forcing the dev into i_am_blocked. be-pm's unblock can't repair git state, so the PM respawn-looped and the loop-breaker gated it (observed: spawn_attempts 42-56, threshold 3). Pass branch_name through to push() so the named task branch is pushed; the dev's commit then reaches origin and open_pr succeeds. TDD: test_push_branch_pushes_named_branch_not_current_checkout.
This commit is contained in:
+10
-1
@@ -3363,7 +3363,16 @@ class GitService(BaseService):
|
|||||||
workspace = await self._workspace_for_branch(
|
workspace = await self._workspace_for_branch(
|
||||||
branch_name, actor_agent_id=actor_agent_id
|
branch_name, actor_agent_id=actor_agent_id
|
||||||
)
|
)
|
||||||
return await self.push(workspace)
|
# Push the NAMED branch, not the workspace's current checkout. The
|
||||||
|
# clone root is shared across a dev's tasks and (F123) parked on the
|
||||||
|
# default branch while the task branch lives in a per-task worktree;
|
||||||
|
# push() with branch=None defaults to get_current_branch(workspace),
|
||||||
|
# which pushed the wrong ref. The dev's commit then never reached
|
||||||
|
# origin, so create_pr 422'd with "No commits between" and the dev was
|
||||||
|
# forced into i_am_blocked — stranded work the PM's unblock can't fix
|
||||||
|
# (it only flips status, not git state). Push-by-name also survives a
|
||||||
|
# clone parked on a LATER task's branch.
|
||||||
|
return await self.push(workspace, branch=branch_name)
|
||||||
|
|
||||||
async def _ensure_base_on_remote(
|
async def _ensure_base_on_remote(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@@ -160,6 +160,35 @@ async def test_push_task_branch_pushes_task_branch_by_name() -> None:
|
|||||||
assert_branch.assert_not_awaited()
|
assert_branch.assert_not_awaited()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_push_branch_pushes_named_branch_not_current_checkout() -> None:
|
||||||
|
"""push_branch (open_pr's push side effect) pushes the NAMED branch.
|
||||||
|
|
||||||
|
The clone root is shared across a dev's tasks and (F123) parked on the
|
||||||
|
default branch while the task branch lives in a per-task worktree.
|
||||||
|
push_branch used to call push(workspace) with no ``branch`` arg, so
|
||||||
|
push() fell back to get_current_branch(workspace) and pushed the wrong
|
||||||
|
ref (the clone root's checkout, e.g. the default branch). The dev's
|
||||||
|
commit then never reached origin, create_pr 422'd with "No commits
|
||||||
|
between", and the dev was forced into i_am_blocked — stranded work the
|
||||||
|
PM's unblock cannot repair (it flips status, not git state). The named
|
||||||
|
branch must be passed through to push().
|
||||||
|
"""
|
||||||
|
branch_name = "feature/backend/fb836f80--03f80432--d3dab0fc--b04afcb5"
|
||||||
|
svc = _service()
|
||||||
|
_bind(svc, "_workspace_for_branch", AsyncMock(return_value=Path("/tmp/ws")))
|
||||||
|
push_mock = AsyncMock(return_value=(branch_name, _PUSHED_COMMIT_COUNT))
|
||||||
|
_bind(svc, "push", push_mock)
|
||||||
|
|
||||||
|
result_branch, pushed = await svc.push_branch(branch_name)
|
||||||
|
|
||||||
|
assert result_branch == branch_name
|
||||||
|
assert pushed == _PUSHED_COMMIT_COUNT
|
||||||
|
# The named branch is forwarded to push() — NOT push(workspace) which
|
||||||
|
# would default to the clone root's current checkout.
|
||||||
|
push_mock.assert_awaited_once_with(Path("/tmp/ws"), branch=branch_name)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_push_targets_explicit_branch_not_current_checkout() -> None:
|
async def test_push_targets_explicit_branch_not_current_checkout() -> None:
|
||||||
"""push(branch=X) pushes X by ref even when the workspace is on Y."""
|
"""push(branch=X) pushes X by ref even when the workspace is on Y."""
|
||||||
|
|||||||
Reference in New Issue
Block a user