perf(hooks): batch pre-commit staged-lock auto-claim into one call - #695
Conversation
The pre-commit auto-claim ran one `gx locks claim` process per staged path. Each spawn is node -> python and rescans every worktree's lock file, so the loop cost ~150ms per file — 15s of pure lock churn on a 30-file commit here, which is the "waiting for the locks" an agent hits on every single commit. Claim the whole staged set in one call, as the staged-deletes branch below already does. `locks claim` is atomic, so one foreign-owned path would reject the whole batch and leave `locks validate --staged` reporting every staged file as unclaimed. Fall back to the per-file loop on batch failure to keep the conflict diagnostics pointing at the one path that conflicts. Measured on this repo (30 staged files, 12 worktrees): 15012ms -> 1327ms. Conflict path verified identical to pre-change behavior. `npm test` failing set byte-identical to main (41 = 41, baseline-red). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Decision: APPROVE — 0 CRITICAL, 0 HIGH, 0 MEDIUM, 2 LOW. Collapses the pre-commit staged-lock auto-claim from one The fallback is the part worth calling out: Paths exercised during review:
LOW-1: conflict case now costs N+1 spawns (only on a path that ends in a blocked commit anyway — correct trade). LOW-2 (pre-existing, not introduced here): Tests: 41 failing on branch, 41 on |
…eanup (#697) `gx branch finish` could merge the PR and still exit 1. After the merge, cleanup runs `git branch -d` on the source branch, which requires an ancestor link to HEAD or full upstream coverage. A squash merge — the default here (`gh pr merge --squash`) — leaves neither once the remote branch is gone, so the refusal is the NORMAL post-merge outcome. It was fatal, while every other cleanup step only warns. Seen on #695: merge landed, branch had been rebased during finish, `branch -d` said "not fully merged", run ended "branchFinish command failed with status 1" and never said the merge had succeeded. That output invites a force-push to fix a merge that already landed. - announce `MERGED <source> -> <base>` + PR URL the moment the merge is confirmed, before any cleanup can bury it - downgrade a refused local-branch delete to a warning - when `branch -d` refuses, ask GitHub whether that exact head landed in a merged PR; force the delete only then, else keep the branch - when a branch is kept, drop --delete-branches/--delete-remote-branches from the follow-up prune, which uses `git branch -D` and would destroy exactly what was protected - report "kept source branch" vs the two existing "cleaned ..." wordings, both preserved verbatim Test suite failing set md5-identical to main (41 = 41); new regression test covers merge-lands-but-delete-refused. Co-authored-by: NagyVikt <nagy.viktordp@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
Test plan