Files
orca/src/main/git/upstream.ts
T
OrcaWinandOrcaWin 4687e90a16 [comment audit] Continue main-process comment cleanup (#32946)
* [comment audit] Shorten daemon, hook, and emulator comments [skip ci]

* [comment audit] Shorten VM, conversation, SQLite, and theme-import comments [skip ci]

* [comment audit] Tighten Git execution and source-control comment contracts [skip ci]

* [comment audit] Clarify repository probes and maintenance comments [skip ci]

* [comment audit] Shorten status, diff-cache, and checkout comments [skip ci]

* [comment audit] Clarify worktree lifecycle and WSL routing comments [skip ci]

* [comment audit] Shorten forge identity and review-refresh comments [skip ci]

* [comment audit] Tighten hosted-review client comment contracts [skip ci]

* [comment audit] Clarify GitLab compatibility and review comments [skip ci]

* [comment audit] Tighten hook ownership and watchdog rationale [skip ci]

* [comment audit] Condense host and integration compatibility comments [skip ci]

* [comment audit] Clarify IPC authority and remote-routing rationale [skip ci]

* [comment audit] Finalize file-import and containment comment cleanup

* [comment audit] Fix stale Jira type imports blocking full CI

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-23 16:27:37 -07:00

105 lines
3.5 KiB
TypeScript

import type { GitUpstreamStatus } from '../../shared/git-status-types'
import type { GitPushTarget } from '../../shared/worktree/types'
import { upstreamOnlyCommitsArePatchEquivalent } from '../../shared/git-upstream-status'
import { isNoUpstreamError, normalizeGitErrorMessage } from '../../shared/git-remote-error'
import { getEffectiveGitUpstreamStatus } from '../../shared/git-effective-upstream'
import { getPublishTargetStatus } from '../../shared/git-publish-target-status'
import { gitExecFileAsync } from './runner'
import { validateGitPushTarget } from './push-target-validation'
import { nativeAndWslGitUpstreamStatusReadOwner } from './git-upstream-status-read-owner'
import type { GitAdmissionTier } from './command-runner/git-exec-options'
type GitExecOptions = {
wslDistro?: string
admissionTier?: GitAdmissionTier
}
export function invalidateGitUpstreamStatusReads(): void {
nativeAndWslGitUpstreamStatusReadOwner.invalidate()
}
function gitExecOptions(
cwd: string,
options: GitExecOptions = {}
): { cwd: string; wslDistro?: string; admissionTier?: GitAdmissionTier } {
return {
cwd,
...(options.wslDistro ? { wslDistro: options.wslDistro } : {}),
...(options.admissionTier ? { admissionTier: options.admissionTier } : {})
}
}
async function getBehindCommitsArePatchEquivalent(
worktreePath: string,
upstreamName: string,
options: GitExecOptions = {}
): Promise<boolean> {
try {
const { stdout } = await gitExecFileAsync(
[
'log',
'--no-show-signature',
'--no-color',
'--oneline',
'--cherry-mark',
'--right-only',
`HEAD...${upstreamName}`,
'--'
],
gitExecOptions(worktreePath, options)
)
return upstreamOnlyCommitsArePatchEquivalent(stdout)
} catch {
// Failed patch-equivalence probes retain the conservative pull-first behavior.
return false
}
}
async function readUpstreamStatus(
worktreePath: string,
pushTarget?: GitPushTarget,
options: GitExecOptions = {}
): Promise<GitUpstreamStatus> {
try {
if (pushTarget) {
const target = await validateGitPushTarget(worktreePath, pushTarget, options)
return await getPublishTargetStatus(
(args) => gitExecFileAsync(args, gitExecOptions(worktreePath, options)),
target,
(upstreamName) => getBehindCommitsArePatchEquivalent(worktreePath, upstreamName, options)
)
}
return await getEffectiveGitUpstreamStatus(
(args) => gitExecFileAsync(args, gitExecOptions(worktreePath, options)),
(upstreamName) => getBehindCommitsArePatchEquivalent(worktreePath, upstreamName, options)
)
} catch (error) {
// Suppress only proven no-upstream errors; auth, corruption and unavailable repos must surface.
if (isNoUpstreamError(error)) {
return {
hasUpstream: false,
ahead: 0,
behind: 0
}
}
// Normalize before IPC so renderer errors omit subprocess preambles and local paths.
throw new Error(normalizeGitErrorMessage(error, 'upstream'))
}
}
export function getUpstreamStatus(
worktreePath: string,
pushTarget?: GitPushTarget,
options: GitExecOptions = {}
): Promise<GitUpstreamStatus> {
const executionIdentity = options.wslDistro
? ({ kind: 'wsl', distro: options.wslDistro } as const)
: ({ kind: 'native' } as const)
return nativeAndWslGitUpstreamStatusReadOwner.read(
executionIdentity,
worktreePath,
pushTarget,
() => readUpstreamStatus(worktreePath, pushTarget, options)
)
}