Files
orca/src/shared/git-upstream-status.ts
T
Jinjing daf22f0720 Make Create PR handle sync by fast-forwarding behind-only branches (#9481)
- Create PR now fast-forwards behind-only branches before committing, using
  git pull --ff-only. This prevents the dirty-then-ahead+behind stall that
  occurred after commit without prior sync.
- Refactor runRemoteAction to return explicit status ('ok', 'failed',
  'superseded', 'skipped') instead of boolean ok + nullable error. Allows
  callers to distinguish real failures from action supersession or skips
  without stale-cache issues.
- Remove isCreatePrIntentSyncConflictError function and sync-conflict-specific
  copy since --ff-only fails cleanly if branch diverged; no merge conflicts
  to resolve.
- Extract isBehindOnlyUpstream predicate to shared module so eligibility
  checks and the one-click flow always agree.
2026-07-19 17:13:19 -07:00

57 lines
1.6 KiB
TypeScript

import type { GitUpstreamStatus } from './git-status-types'
export function upstreamOnlyCommitsArePatchEquivalent(cherryMarkOutput: string): boolean {
let hasCommit = false
for (const rawLine of iterateGitOutputLines(cherryMarkOutput)) {
const line = rawLine.trim()
if (!line) {
continue
}
hasCommit = true
if (!line.startsWith('=')) {
return false
}
}
return hasCommit
}
function* iterateGitOutputLines(output: string): Generator<string> {
let lineStart = 0
for (let index = 0; index < output.length; index++) {
const code = output.charCodeAt(index)
if (code !== 10 && code !== 13) {
continue
}
yield output.slice(lineStart, index)
if (code === 13 && output.charCodeAt(index + 1) === 10) {
index++
}
lineStart = index + 1
}
if (lineStart <= output.length) {
yield output.slice(lineStart)
}
}
export function shouldForcePushWithLeaseForUpstream(
status: GitUpstreamStatus | undefined
): boolean {
return (
status?.hasUpstream === true &&
status.ahead > 0 &&
status.behind > 0 &&
status.behindCommitsArePatchEquivalent === true
)
}
// Why: behind-only is the only auto-prepare case Create PR can safely handle
// with a pure fast-forward (no local unique commits to reconcile). Eligibility
// and the intent remote-step resolver must share this predicate so the button
// and the one-click flow never disagree on what "behind-only" means.
export function isBehindOnlyUpstream(status: GitUpstreamStatus | undefined): boolean {
return status?.hasUpstream === true && status.ahead === 0 && status.behind > 0
}