Suppress Git Credential Manager OAuth popup on git clone (fixes #7652)

Orca's git runner disables the interactive credential prompt on every git
call that goes through gitExecFileAsync/gitStreamStdout, but the two raw
'git clone' spawns (desktop repos:clone and the runtime clone path) passed
no env, so they inherited process.env with no guard. On Windows a clone
that needs GitHub auth then makes Git Credential Manager pop its
'Connect to GitHub' OAuth window, and in a network-restricted intranet the
browser/device flow never completes while git's credential retry re-pops it.

Apply nonInteractiveGitEnv() to both clone spawns so the prompt is
suppressed (GCM_INTERACTIVE=never, credential.interactive=false,
GIT_TERMINAL_PROMPT=0). The credential *helper* is kept, so cached-token
clones for private repos still work; only the interactive fallback popup is
disabled and the clone fails fast with a clear error instead.
This commit is contained in:
Brennan Benson
2026-07-09 16:19:05 -07:00
parent 1b0febc4cc
commit 7674f8baba
3 changed files with 45 additions and 3 deletions
+30 -1
View File
@@ -103,7 +103,14 @@ vi.mock('../git/repo', async () => {
vi.mock('../git/runner', () => ({
gitExecFileAsync: vi.fn(),
gitSpawn: gitSpawnMock
gitSpawn: gitSpawnMock,
// Mirrors the real guard's credential-prompt markers so the clone regression
// test (#7652) can assert Git Credential Manager's OAuth popup is disabled.
nonInteractiveGitEnv: (env: NodeJS.ProcessEnv = process.env) => ({
...env,
GIT_TERMINAL_PROMPT: '0',
GCM_INTERACTIVE: 'never'
})
}))
vi.mock('../git/worktree', () => ({
@@ -2067,6 +2074,28 @@ describe('repos:add + repos:clone', () => {
expect(result).toHaveProperty('path', join(destination, 'orca'))
})
it('clones with the non-interactive credential guard so Git Credential Manager cannot pop its OAuth window (#7652)', async () => {
const destination = await createTempRoot()
await handlers.get('repos:clone')!(null, {
url: 'https://example.com/orca.git',
destination
})
// Without this env, a clone that needs GitHub auth makes Git Credential
// Manager pop its "Connect to GitHub" OAuth window on Windows and loop it
// when the network cannot complete the flow.
expect(gitSpawnMock).toHaveBeenCalledWith(
['clone', '--progress', '--', 'https://example.com/orca.git', join(destination, 'orca')],
expect.objectContaining({
env: expect.objectContaining({
GIT_TERMINAL_PROMPT: '0',
GCM_INTERACTIVE: 'never'
})
})
)
})
it('treats cloneAbort with no active clone as a no-op', async () => {
await expect(handlers.get('repos:cloneAbort')!(null, undefined)).resolves.toBeUndefined()
})
+8 -1
View File
@@ -42,7 +42,7 @@ import { isTuiAgent } from '../../shared/tui-agent-config'
import { invalidateAuthorizedRootsCache } from './filesystem-auth'
import type { ChildProcess } from 'node:child_process'
import { access, mkdir, readdir, rm } from 'node:fs/promises'
import { gitExecFileAsync, gitSpawn } from '../git/runner'
import { gitExecFileAsync, gitSpawn, nonInteractiveGitEnv } from '../git/runner'
import { isAbsolute, join, posix } from 'node:path'
import {
cleanupClaimedCloneTarget,
@@ -2253,6 +2253,13 @@ export function registerRepoHandlers(mainWindow: BrowserWindow, store: Store): v
try {
proc = gitSpawn(['clone', '--progress', '--', args.url, clonePath], {
cwd: args.destination,
// Why: without the non-interactive guard, a clone that needs
// GitHub auth makes Git Credential Manager pop its "Connect to
// GitHub" OAuth window on Windows; in a network-restricted env the
// browser/device flow can never complete and git's credential
// retry re-pops it (issue #7652). Fail fast with a clear error and
// let Orca's non-intrusive GitHub state stand instead.
env: nonInteractiveGitEnv(),
stdio: ['ignore', 'ignore', 'pipe']
})
} catch (err) {
+7 -1
View File
@@ -41,7 +41,7 @@ import {
AGENT_PROMPT_SUBMIT_DELAY_MS,
buildAgentPromptPasteBytes
} from '../../shared/agent-prompt-injection'
import { gitExecFileAsync, wslAwareSpawn } from '../git/runner'
import { gitExecFileAsync, wslAwareSpawn, nonInteractiveGitEnv } from '../git/runner'
import {
cleanupClaimedCloneTarget,
claimCloneTarget,
@@ -10666,6 +10666,12 @@ export class OrcaRuntimeService {
try {
proc = wslAwareSpawn('git', ['clone', '--progress', '--', trimmedUrl, clonePath], {
cwd: trimmedDestination,
// Why: without the non-interactive guard, a clone that needs GitHub
// auth makes Git Credential Manager pop its "Connect to GitHub" OAuth
// window on Windows; in a network-restricted env the browser/device
// flow can never complete and git's credential retry re-pops it
// (issue #7652). Fail fast with a clear error instead.
env: nonInteractiveGitEnv(),
stdio: ['ignore', 'ignore', 'pipe']
})
} catch (err) {