fix: robust worktree repo-path derivation and branch typing (review)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 20:28:25 -04:00
parent 61f1a07ba7
commit 0cf147ee25
2 changed files with 73 additions and 15 deletions
+35
View File
@@ -1433,3 +1433,38 @@ async def test_worktree_state_for_worktree_session_returns_state(
assert state is fake_worktree.state_result
assert fake_worktree.state_calls == [(Path("/tmp/myproj"), WT_PATH, "feature-x")]
@pytest.mark.asyncio
async def test_repo_path_fallback_slash_branch_when_project_gone(
factory, db, tmux, harnesses, fake_worktree
):
"""When the project row is gone, the repo is derived from the worktree
layout even for slash-containing branch names (feature/foo).
create_worktree builds the path as <repo>/.worktrees/<branch>, so for a
branch like 'feature/foo' the path is <repo>/.worktrees/feature/foo. The
fallback must strip '.worktrees/feature/foo' and recover <repo>, not the
wrong parent.parent result (<repo>/.worktrees).
"""
from hqt.db.models import Session
repo = Path("/tmp/myproj")
branch = "feature/foo"
# Mirror how worktree.create_worktree builds the path.
wt_path = repo / ".worktrees" / branch
sess = _seed_worktree_session(db, branch=branch, path=str(wt_path))
sess_id = sess.id
# Delete the project row so the fallback derivation is exercised.
db.query(Project).delete()
db.commit()
db.expire_all()
# Session row outlives the project (no FK cascade in this seed).
assert db.get(Session, sess_id) is not None
service = SessionService(factory=factory, tmux=tmux, harnesses=harnesses)
await service.worktree_state_for(sess_id)
# The fallback must recover the real repo, not <repo>/.worktrees.
assert fake_worktree.state_calls == [(repo, wt_path, branch)]