mirror of
https://github.com/stablyai/orca.git
synced 2026-09-26 16:02:43 +00:00
* fix(worktrees): stop a failed worktree scan from pruning as an authoritative empty listing A `git worktree list` that could not run at all — a WSL distro that stopped resolving, a hung mount, a git binary that errored — was softened to `[]` by the lenient listing path, so the detected scan published it as `authoritative: true, worktrees: []`. That disables the #1158 retention guard, drops every persisted tab for the repo, and the pruned session is written back to disk on the next launch. The loss is permanent, not a transient glitch. Route the detected scan through a strict listing that still reports the two genuinely empty states (repo path gone, not a Git repo) as `[]`. Everything else rejects, so the existing catch answers `authoritative: false` and the destructive halves (`rememberLocalWorktreeRoots`, `pruneLineageForMissingRepoWorktrees`) never see a failed scan. Also make the failure readable: wsl.exe reports its own launch failures as exit 0xFFFFFFFF with an EMPTY stderr and the `Wsl/Service/WSL_E_*` line on stdout as UTF-16LE, which is why the field bundle carried a git error with no text. Set WSL_UTF8 for WSL-routed git (matching the wsl runner, #9010) and attach that stdout diagnostic to the error so `git.exec` spans name the cause. * fix(worktrees): surface a failed worktree scan's cause on the repo header with a retry A failed scan now travels with its reason (optional unavailableReason on DetectedWorktreeListResult), the repo header shows it with click-to-retry, and the WSL deleted-guest-directory shape measured on a real Windows host is pinned as retained-not-pruned.
80 lines
2.9 KiB
TypeScript
80 lines
2.9 KiB
TypeScript
import { addWslEnvKeys } from '../../wsl-env'
|
|
import {
|
|
appendGitConfigEnv,
|
|
gitCredentialPromptGuardEnv
|
|
} from '../../../shared/git-credential-prompt-env'
|
|
import { UNTRANSLATED_GIT_OUTPUT_ENV } from '../../../shared/git-output-locale'
|
|
|
|
export function gitOptionalLocksDisabledEnv(
|
|
env: NodeJS.ProcessEnv = process.env
|
|
): NodeJS.ProcessEnv {
|
|
return {
|
|
...env,
|
|
GIT_OPTIONAL_LOCKS: '0'
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Append git config via the GIT_CONFIG_COUNT/KEY_n/VALUE_n env protocol (git >= 2.31),
|
|
* composing with any count already in `env` so we never clobber a caller's config.
|
|
*/
|
|
export { appendGitConfigEnv }
|
|
|
|
/**
|
|
* Pin Orca-spawned git to untranslated English output so stderr/progress parsers
|
|
* work under any user locale (issue #7808). Terminal git is untouched.
|
|
*/
|
|
export function untranslatedGitOutputEnv(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {
|
|
return { ...env, ...UNTRANSLATED_GIT_OUTPUT_ENV }
|
|
}
|
|
|
|
export function promptGuardGitEnv(
|
|
env: NodeJS.ProcessEnv = process.env,
|
|
platform: NodeJS.Platform = process.platform
|
|
): NodeJS.ProcessEnv {
|
|
return gitCredentialPromptGuardEnv(untranslatedGitOutputEnv(env), platform)
|
|
}
|
|
|
|
/**
|
|
* Credential-prompt guard for a general-purpose shell (PTYs, hook scripts):
|
|
* like promptGuardGitEnv but without the issue-7808 locale pins, which would
|
|
* change the locale of every child process, not just git's.
|
|
*/
|
|
export function promptGuardShellEnv(
|
|
env: NodeJS.ProcessEnv = process.env,
|
|
platform: NodeJS.Platform = process.platform
|
|
): NodeJS.ProcessEnv {
|
|
return gitCredentialPromptGuardEnv(env, platform)
|
|
}
|
|
|
|
/**
|
|
* Force git non-interactive so it fails fast instead of hanging on a prompt with
|
|
* no terminal to answer it; on headless `serve` those stuck calls wedge every
|
|
* client (issue #5308).
|
|
*
|
|
* - GIT_TERMINAL_PROMPT=0: git errors instead of prompting for credentials.
|
|
* - GIT_ASKPASS / SSH_ASKPASS: emptied when unset so no GUI helper blocks; a
|
|
* caller-provided askpass is preserved (custom setups serve creds non-interactively).
|
|
* - GIT_SSH_COMMAND BatchMode=yes: SSH errors instead of prompting (doesn't change
|
|
* host trust); only added when the caller hasn't set its own.
|
|
*/
|
|
export function nonInteractiveGitEnv(
|
|
env: NodeJS.ProcessEnv = process.env,
|
|
platform: NodeJS.Platform = process.platform
|
|
): NodeJS.ProcessEnv {
|
|
const next = promptGuardGitEnv(env, platform)
|
|
if (platform === 'win32') {
|
|
// Why: without it wsl.exe writes its OWN failures ("no distribution with the supplied name") as
|
|
// UTF-16LE (#9010), which is how a dead distro reached telemetry as an error with no text.
|
|
next.WSL_UTF8 = '1'
|
|
}
|
|
if (!next.GIT_SSH_COMMAND) {
|
|
next.GIT_SSH_COMMAND = 'ssh -o BatchMode=yes'
|
|
if (platform === 'win32') {
|
|
// Why: forward GIT_SSH_COMMAND to WSL only when we set it — a caller's Windows-specific value must not leak into Linux git.
|
|
addWslEnvKeys(next, ['GIT_SSH_COMMAND'])
|
|
}
|
|
}
|
|
return next
|
|
}
|