feat(FN-4499): complete Step 3 — add reanchor primitive

Fusion-Task-Id: FN-4499
Fusion-Task-Lineage: 3e9fee75-5c3d-4ce5-aa8b-3f2bb94e48eb
This commit is contained in:
Fusion
2026-05-14 13:15:44 -07:00
committed by gsxdsm
parent ec13b2b3a9
commit 311bee43a0
2 changed files with 69 additions and 0 deletions

View File

@@ -507,6 +507,52 @@ export async function classifyForeignCommits(
}
}
export interface ReanchorBranchToBaseInput {
repoDir: string;
worktreePath: string;
branchName: string;
baseSha: string;
taskId: string;
}
export interface ReanchorBranchToBaseResult {
previousTipSha: string;
newTipSha: string;
}
export async function reanchorBranchToBase(
input: ReanchorBranchToBaseInput,
): Promise<ReanchorBranchToBaseResult> {
const { repoDir, worktreePath, branchName, baseSha, taskId } = input;
const previousTipSha = await revParse(repoDir, branchName);
try {
await execAsync("git checkout -- .", {
cwd: worktreePath,
encoding: "utf-8",
timeout: GIT_TIMEOUT_MS,
maxBuffer: GIT_MAX_BUFFER,
});
} catch {
// best-effort: worktree may already be clean
}
await execAsync("git clean -fd", {
cwd: worktreePath,
encoding: "utf-8",
timeout: GIT_TIMEOUT_MS,
maxBuffer: GIT_MAX_BUFFER,
});
await runGit(worktreePath, `git checkout --detach ${quoteShellArg(baseSha)}`);
await runGit(worktreePath, `git checkout -B ${quoteShellArg(branchName)} ${quoteShellArg(baseSha)}`);
await assertCleanBranchAtBase(repoDir, branchName, baseSha, taskId);
return {
previousTipSha,
newTipSha: await revParse(repoDir, branchName),
};
}
export interface AutoRecoverCrossContaminationInput {
repoDir: string;
branchName: string;