fix: address review findings (#2377)

This commit is contained in:
Jinjing
2026-05-19 17:50:04 -07:00
committed by GitHub
parent 4eddaf901b
commit 8321ea2e03
3 changed files with 172 additions and 3 deletions
+61
View File
@@ -6,6 +6,7 @@ import type {
IssueSourcePreference,
ListWorkItemsResult,
PRInfo,
PRConflictSummary,
PRRefreshOutcome,
PRMergeableState,
PRCheckDetail,
@@ -74,6 +75,8 @@ import {
type RateLimitBucketKind
} from './rate-limit'
type GhExecOptions = ReturnType<typeof ghRepoExecOptions>
const ORCA_REPO = 'stablyai/orca'
async function assertRateLimitBudget(bucket: RateLimitBucketKind): Promise<void> {
@@ -2706,6 +2709,17 @@ export async function mergePR(
const ownerRepo = prRepo ?? (await getOwnerRepo(repoPath, connectionId))
await acquire()
try {
const mergeBlocker = await getPRMergeBlocker(
repoPath,
prNumber,
ownerRepo,
ghOptions,
connectionId
)
if (mergeBlocker) {
return { ok: false, error: mergeBlocker }
}
// Don't use --delete-branch: it tries to delete the local branch which
// fails when the user's worktree is checked out on it. Branch cleanup
// is handled by worktree deletion (local) and GitHub's auto-delete setting (remote).
@@ -2727,6 +2741,53 @@ export async function mergePR(
}
}
async function getPRMergeBlocker(
repoPath: string,
prNumber: number,
ownerRepo: OwnerRepo | null,
ghOptions: GhExecOptions,
connectionId?: string | null
): Promise<string | null> {
// Why: conflict summaries shell out to local git; SSH repo paths are remote-only
// until that helper is routed through the SSH git provider.
if (!ownerRepo || connectionId) {
return null
}
try {
const pr = await getPRByNumber(ownerRepo, prNumber, ghOptions)
if (pr?.mergeable !== 'CONFLICTING' || !pr.baseRefName || !pr.baseRefOid || !pr.headRefOid) {
return null
}
const summary = await getPRConflictSummary(
repoPath,
pr.baseRefName,
pr.baseRefOid,
pr.headRefOid
)
return formatMergeConflictBlocker(pr.baseRefName, summary)
} catch {
// Why: conflict preflight should improve stale UI diagnostics, not make
// merge impossible when the lookup endpoint has a transient failure.
return null
}
}
function formatMergeConflictBlocker(
baseRefName: string,
summary: PRConflictSummary | undefined
): string {
const heading = 'This pull request has merge conflicts and cannot be merged yet.'
if (!summary || summary.files.length === 0) {
return `${heading}\nUpdate the branch with ${baseRefName} and resolve the conflicts before merging.`
}
const files = summary.files.map((file) => `- ${file}`).join('\n')
const behind = `${summary.commitsBehind} commit${summary.commitsBehind === 1 ? '' : 's'} behind ${baseRefName}`
return `${heading}\n${behind} (base commit: ${summary.baseCommit}).\n\nConflicting files:\n${files}`
}
export async function updatePRState(
repoPath: string,
prNumber: number,