fix(git): reset the dev workspace before a fresh-claim branch checkout

A developer's persistent per-dev clone is shared across tasks, so a finished or
abandoned prior task can leave it dirty and on a sibling branch. create_branch's
checkouts then fail on the dirty tree — and because this git work runs as a
side-effect AFTER the claim's DB transition commits, the task is left marked
assigned while the workspace stays on the wrong branch, so the dev's next commit
is rejected BRANCH_MISMATCH (stalling then blocking the task).

reset --hard the tree before the base/feature checkouts. This runs only on a
fresh claim (resume short-circuits in _dev_reentry), so discarded changes are
abandoned cruft from a finished task — never commits (reset --hard keeps HEAD),
never the gitignored .venv. The branch-preservation test invariant is refined to
its real intent: a work-carrying branch must never be RE-POINTED
(reset --hard <base>); a bare tree-clean reset is allowed.
This commit is contained in:
Renn F
2026-06-24 03:49:24 +02:00
parent 855e4aea54
commit a92501a3ac
3 changed files with 24 additions and 2 deletions
+9 -2
View File
@@ -629,8 +629,15 @@ async def test_create_branch_keeps_existing_branch_that_has_work() -> None:
calls = await _run_create_branch_with_existing_branch(
svc, "feature/frontend/abc12345--def67890", unique_commits="3"
)
assert not any(c[:2] == ["reset", "--hard"] for c in calls), (
"a branch with real work must never be reset"
# The fresh-claim tree-clean (a BARE `reset --hard`) is expected — it discards
# only uncommitted cruft from a prior task in the shared clone, never commits.
assert ["reset", "--hard"] in calls
# But the RE-POINT reset (`reset --hard <base>`, which throws commits away)
# must NEVER fire for a branch carrying its own work.
# `c[2:]` truthy == there is a ref arg after "reset --hard" → it re-points.
repoint_resets = [c for c in calls if c[:2] == ["reset", "--hard"] and c[2:]]
assert not repoint_resets, (
"a branch with real work must never be re-pointed onto base"
)