mirror of
https://github.com/stablyai/orca.git
synced 2026-10-27 00:02:48 +00:00
* perf(git): bound ref and worktree scans * fix(repo-search): clamp oversized ref limits * fix(worktree): keep strict worktree listing unshared The shared-scan re-export flipped every `listWorktreesStrict` caller from an isolated subprocess to the coalesced scan. `git worktree prune` in the removal recovery path does not bump the scan generation, so a post-prune verification could join a pre-prune scan, see the stale row, and report a successful removal as a stale registration. The same gap defeats the post-archive-hook rechecks that exist to catch an external Git client locking the row. Restore the unshared export and make coalescing opt-in via `listWorktreesSharedStrict`, which existing callers already use deliberately. * fix(git): separate a proven absent ref from a failed probe `show-ref --verify --quiet` exits 1 for a missing ref, but so does `wsl.exe` when its own launch fails, so reading any exit 1 as absence collapsed `unverifiable` into `exited`. A genuine miss prints nothing while a wrapper failure always explains itself, so require empty stderr alongside the exit code; a runner that reports no stderr at all keeps its exit-code contract. That same signal removes a spawn regression: `show-ref` is a direct-git read under WSL, and the runner retried any numeric exit through the user's interactive login shell. The replaced `for-each-ref` exited 0 on a miss, so absence never retried; every absent probe now would. Treat a quiet exit 1 as Git control flow and skip the fallback. Also narrow the hosted-review suffix fallback: the replaced `refs/remotes/*/<base>` could not cross a slash, but `show-ref -- <base>` matches at any depth, so `origin/feature/main` answered a query for `main` and submitted a review against a base the provider rejects. Refresh the real-binary compatibility contract to the shipped excludes, and assert exact probe concurrency rather than an upper bound so a regression to serial probing fails.
132 lines
4.6 KiB
TypeScript
132 lines
4.6 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import { isShowRefNoMatchError, probeAnyExactRef, probeExactRefs } from './exact-ref-probe'
|
|
|
|
describe('isShowRefNoMatchError', () => {
|
|
it('accepts only the numeric Git no-match exit status', () => {
|
|
expect(isShowRefNoMatchError({ code: 1 })).toBe(true)
|
|
expect(isShowRefNoMatchError({ code: '1' })).toBe(false)
|
|
expect(isShowRefNoMatchError({ code: 'CONNECTION_LOST' })).toBe(false)
|
|
expect(isShowRefNoMatchError({ code: -32000 })).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('probeExactRefs', () => {
|
|
it('preserves present, absent, and unknown states while deduplicating refs', async () => {
|
|
const present = 'refs/remotes/origin/main'
|
|
const absent = 'refs/remotes/upstream/main'
|
|
const unknown = 'refs/remotes/fork/main'
|
|
const invalid = 'refs/remotes/origin/bad*'
|
|
const runGit = vi.fn(async (argv: string[]) => {
|
|
if (argv.at(-1) === absent) {
|
|
throw Object.assign(new Error('no match'), { code: 1 })
|
|
}
|
|
if (argv.at(-1) === unknown) {
|
|
throw Object.assign(new Error('transport failed'), { code: 128 })
|
|
}
|
|
return { stdout: '' }
|
|
})
|
|
|
|
await expect(
|
|
probeExactRefs(runGit, [present, absent, unknown, invalid, '', present])
|
|
).resolves.toEqual({
|
|
presentRefs: [present],
|
|
absentRefs: [absent],
|
|
unknownRefs: [unknown, invalid, '']
|
|
})
|
|
expect(runGit).toHaveBeenCalledTimes(3)
|
|
expect(
|
|
runGit.mock.calls.every(
|
|
([argv]) => argv.slice(0, 4).join(' ') === 'show-ref --verify --quiet --'
|
|
)
|
|
).toBe(true)
|
|
})
|
|
|
|
it('forwards max-buffer and timeout options', async () => {
|
|
const runGit = vi.fn(async () => ({ stdout: '' }))
|
|
const ref = 'refs/remotes/origin/main'
|
|
|
|
await probeExactRefs(runGit, [ref], { maxBuffer: 4096, timeoutMs: 30_000 })
|
|
|
|
expect(runGit).toHaveBeenCalledWith(['show-ref', '--verify', '--quiet', '--', ref], {
|
|
maxBuffer: 4096,
|
|
timeoutMs: 30_000
|
|
})
|
|
})
|
|
|
|
it('bounds concurrent exact lookups', async () => {
|
|
const refs = Array.from({ length: 20 }, (_, index) => `refs/remotes/remote-${index}/main`)
|
|
let active = 0
|
|
let maxActive = 0
|
|
const runGit = vi.fn(async () => {
|
|
active += 1
|
|
maxActive = Math.max(maxActive, active)
|
|
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
active -= 1
|
|
throw Object.assign(new Error('no match'), { code: 1 })
|
|
})
|
|
|
|
await probeExactRefs(runGit, refs)
|
|
|
|
expect(runGit).toHaveBeenCalledTimes(20)
|
|
// Equality, not a ceiling: 20 refs saturate the pool, so a regression to
|
|
// serial probing has to fail here.
|
|
expect(maxActive).toBe(8)
|
|
})
|
|
})
|
|
|
|
describe('probeAnyExactRef', () => {
|
|
it('stops scheduling once a ref is present', async () => {
|
|
const refs = Array.from({ length: 20 }, (_, index) => `refs/remotes/remote-${index}/main`)
|
|
const runGit = vi.fn(async (argv: string[]) => {
|
|
if (argv.at(-1) === refs[0]) {
|
|
return { stdout: '' }
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
throw Object.assign(new Error('no match'), { code: 1 })
|
|
})
|
|
|
|
await expect(probeAnyExactRef(runGit, refs)).resolves.toEqual({
|
|
found: true,
|
|
unknown: false
|
|
})
|
|
expect(runGit.mock.calls.length).toBeLessThanOrEqual(8)
|
|
})
|
|
it('treats exit 1 with stderr as an inconclusive probe, not an absent ref', async () => {
|
|
// Why: `wsl.exe` exits 1 for its own launch failures. Reading that as
|
|
// absence would collapse `unverifiable` into `exited`.
|
|
const runGit = vi.fn(async () => {
|
|
throw Object.assign(new Error('wsl fail'), {
|
|
code: 1,
|
|
stderr: 'There is no distribution with the supplied name.'
|
|
})
|
|
})
|
|
|
|
const result = await probeExactRefs(runGit, ['refs/remotes/origin/main'])
|
|
|
|
expect(result.unknownRefs).toEqual(['refs/remotes/origin/main'])
|
|
expect(result.absentRefs).toEqual([])
|
|
})
|
|
|
|
it('still reads a quiet exit 1 as an absent ref', async () => {
|
|
const runGit = vi.fn(async () => {
|
|
throw Object.assign(new Error('missing'), { code: 1, stderr: '' })
|
|
})
|
|
|
|
const result = await probeExactRefs(runGit, ['refs/remotes/origin/main'])
|
|
|
|
expect(result.absentRefs).toEqual(['refs/remotes/origin/main'])
|
|
expect(result.unknownRefs).toEqual([])
|
|
})
|
|
|
|
it('keeps the exit-code contract for a runner that reports no stderr', async () => {
|
|
// The SSH provider rejects without a stderr field; absence must still resolve.
|
|
const runGit = vi.fn(async () => {
|
|
throw Object.assign(new Error('missing'), { code: 1 })
|
|
})
|
|
|
|
const result = await probeExactRefs(runGit, ['refs/remotes/origin/main'])
|
|
|
|
expect(result.absentRefs).toEqual(['refs/remotes/origin/main'])
|
|
})
|
|
})
|