fix(FN-706): add branch conflict recovery and pool fallthrough in executor

- Add branch conflict recovery to worktree-pool prepareForTask when checkout fails
- Add fallthrough in executor to create fresh worktree when pool preparation fails
- Add tests for branch conflict recovery in worktree-pool
- Add tests for executor fallthrough on pool preparation failure
This commit is contained in:
gsxdsm
2026-04-02 13:48:08 -07:00
parent 281fd206ba
commit c1ff739a87
4 changed files with 180 additions and 10 deletions

View File

@@ -127,10 +127,31 @@ export class WorktreePool {
// Create or force-reset the branch from the start point (or main)
const base = startPoint || "main";
execSync(`git checkout -B "${branchName}" ${base}`, {
cwd: worktreePath,
stdio: "pipe",
});
const checkoutCmd = `git checkout -B "${branchName}" ${base}`;
try {
execSync(checkoutCmd, {
cwd: worktreePath,
stdio: "pipe",
});
} catch (err: any) {
const stderr = err?.stderr?.toString() ?? err?.message ?? "";
const match = stderr.match(/already used by worktree at '([^']+)'/);
if (!match) {
throw err;
}
// The branch is checked out in a different worktree — detach it there,
// delete the stale branch, then retry.
const conflictingPath = match[1];
try {
execSync("git checkout --detach", { cwd: conflictingPath, stdio: "pipe" });
} catch {
// Conflicting worktree may no longer exist on disk — try pruning instead
execSync("git worktree prune", { cwd: worktreePath, stdio: "pipe" });
}
execSync(`git branch -D "${branchName}"`, { cwd: worktreePath, stdio: "pipe" });
execSync(checkoutCmd, { cwd: worktreePath, stdio: "pipe" });
}
}
}