fix(worktrees): unlock before remove so WebUI-created worktrees can be reaped
WebUI-created worktrees are locked at creation by the agent (cli._setup_worktree locks with --reason 'hermes pid=...'), but remove_worktree_for_session never unlocked, so git refused every removal with "use 'remove -f -f' to override or unlock first" — force=true included, since a single --force cannot override a lock. Mirror the agent's own _cleanup_worktree ordering: fail-soft 'git worktree unlock' right before the remove, after all dirty/untracked/unpushed/stream/terminal guards have passed. Those guards remain the real safety layer; force keeps meaning 'override dirty working state', never 'override a foreign lock'. Tests: locked worktree now removes cleanly without force; unlock is fail-soft when the worktree was never locked; existing mocked call-order assertions updated for the leading unlock call. Fixes #6023
This commit is contained in:
1 parent
d486394f7b
commit
c833f290a9
2 files changed
+92
-2
No files matched your search
@@ -265,6 +265,18 @@ def remove_worktree_for_session(session, *, force: bool = False) -> dict:
|
||||
repo_root = getattr(session, "worktree_repo_root", None)
|
||||
if not repo_root:
|
||||
raise ValueError("Session missing worktree_repo_root")
|
||||
|
||||
# Unlock the creation-time bookkeeping lock before removing (fail-soft).
|
||||
# The agent locks every worktree it creates (cli._setup_worktree), and git
|
||||
# refuses to remove a locked worktree with a single --force, so without
|
||||
# this every WebUI-created worktree is unremovable. The dirty/untracked/
|
||||
# unpushed/stream/terminal guards above are the real safety layer, not
|
||||
# git's lock — mirrors the agent's own _cleanup_worktree ordering.
|
||||
try:
|
||||
_run_git(["worktree", "unlock", str(worktree_path)], str(repo_root), timeout=5)
|
||||
except (OSError, subprocess.TimeoutExpired):
|
||||
pass # already unlocked / never locked — non-fatal
|
||||
|
||||
try:
|
||||
remove_args = ["worktree", "remove"]
|
||||
if force:
|
||||
|
||||
Reference in new issue
Block a user