feat(FN-4476): complete Step 2 — add patch-id unique commit helper

Fusion-Task-Id: FN-4476
Fusion-Task-Lineage: 8673c1d9-f47e-4d02-89e6-646040b9be32
This commit is contained in:
Fusion
2026-05-14 08:13:26 -07:00
committed by gsxdsm
parent ebd79d21bc
commit 69d35585cb
2 changed files with 145 additions and 0 deletions

View File

@@ -104,6 +104,12 @@ export type BranchConflictInspectionResult =
| { kind: "reclaimable"; livePath: string; tipSha: string; taskAttributedCommitCount: number; strandedCommits: BranchConflictCommit[] }
| { kind: "live-foreign"; livePath: string; error: BranchConflictError };
interface UniqueBranchCommitListResult {
commits: BranchConflictCommit[];
mainRef: string;
degraded: boolean;
}
export interface ListBranchRecoveryCandidatesInput {
repoDir: string;
branchName: string;
@@ -148,6 +154,58 @@ async function listStrandedCommits(repoDir: string, startPoint: string, branchNa
}
}
async function resolveBranchComparisonRef(repoDir: string, startPoint: string, branchName: string): Promise<string> {
try {
await revParse(repoDir, startPoint);
await runGit(repoDir, `git merge-base ${quoteShellArg(startPoint)} ${quoteShellArg(branchName)}`);
return startPoint;
} catch {
return "main";
}
}
export async function listUniqueBranchCommits(
repoDir: string,
startPoint: string,
branchName: string,
): Promise<UniqueBranchCommitListResult> {
const mainRef = await resolveBranchComparisonRef(repoDir, startPoint, branchName);
try {
const comparisonBase = await runGit(repoDir, `git merge-base ${quoteShellArg(mainRef)} ${quoteShellArg(branchName)}`);
const cherryOutput = await runGit(
repoDir,
`git cherry ${quoteShellArg(mainRef)} ${quoteShellArg(branchName)} ${quoteShellArg(comparisonBase)}`,
);
const plusTokens = cherryOutput
.split("\n")
.map((line) => line.trim())
.filter((line) => line.startsWith("+ "))
.map((line) => line.slice(2).trim())
.filter(Boolean);
const commits: BranchConflictCommit[] = [];
for (const token of plusTokens) {
const [sha, subject] = await Promise.all([
runGit(repoDir, `git rev-parse --verify ${quoteShellArg(`${token}^{commit}`)}`).catch(() => token),
runGit(repoDir, `git log -1 --format=%s ${quoteShellArg(token)}`).catch(() => ""),
]);
commits.push({ sha, subject });
}
return {
commits,
mainRef,
degraded: false,
};
} catch {
return {
commits: await listStrandedCommits(repoDir, mainRef, branchName),
mainRef,
degraded: true,
};
}
}
async function getWorktreeBranchMap(repoDir: string): Promise<Map<string, string>> {
const output = await runGit(repoDir, "git worktree list --porcelain");
const map = new Map<string, string>();