mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-20 10:11:58 +00:00
feat(cli): lock hermes worktrees so concurrent processes can't clobber them
git worktree lock at creation and unlock before removal. A locked worktree refuses 'git worktree remove' (and prune), so a second hermes process or a stray cleanup can't silently delete an in-use isolated worktree. Fail-soft on both paths — a lock/unlock error never blocks the session or cleanup. Salvaged from #47029 (Issue #46303). Unlock moved to the actual-removal path so a preserved (unpushed-commits) worktree stays locked while in use.
This commit is contained in:
parent
62c71ebd8f
commit
e48554a3e0
1 changed files with 21 additions and 0 deletions
21
cli.py
21
cli.py
|
|
@ -1340,6 +1340,17 @@ def _setup_worktree(repo_root: str = None) -> Optional[Dict[str, str]]:
|
|||
except Exception as e:
|
||||
logger.debug("Error copying .worktreeinclude entries: %s", e)
|
||||
|
||||
# Lock the worktree so other processes (and `git worktree remove`) can see
|
||||
# it is actively in use. Fail-soft: a lock failure never blocks the session.
|
||||
try:
|
||||
subprocess.run(
|
||||
["git", "worktree", "lock", "--reason", f"hermes pid={os.getpid()}", str(wt_path)],
|
||||
capture_output=True, text=True, timeout=10, cwd=repo_root,
|
||||
)
|
||||
logger.debug("Worktree locked: %s (pid=%s)", wt_path, os.getpid())
|
||||
except Exception as e:
|
||||
logger.debug("git worktree lock failed (non-fatal): %s", e)
|
||||
|
||||
info = {
|
||||
"path": str(wt_path),
|
||||
"branch": branch_name,
|
||||
|
|
@ -1415,6 +1426,16 @@ def _cleanup_worktree(info: Dict[str, str] = None) -> None:
|
|||
|
||||
# Remove worktree (even if working tree is dirty — uncommitted
|
||||
# changes without unpushed commits are just artifacts)
|
||||
# Unlock first so `git worktree remove` isn't blocked by the lock we
|
||||
# placed at creation time. Fail-soft — never block cleanup.
|
||||
try:
|
||||
subprocess.run(
|
||||
["git", "worktree", "unlock", wt_path],
|
||||
capture_output=True, text=True, timeout=10, cwd=repo_root,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.debug("git worktree unlock failed (non-fatal): %s", e)
|
||||
|
||||
try:
|
||||
subprocess.run(
|
||||
["git", "worktree", "remove", wt_path, "--force"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue