mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 16:02:03 +00:00
Two small changes to the Git metadata read path. Neither has a user-visible
effect on any platform except for a malformed `.git` gitfile, described below.
1. resolveGitMetadataPath's third parameter becomes an options object
`{ platform?, wslDistro? }`. A caller that knows which distro wrote a pointer
can now say so, where previously only a WSL UNC base path could. The distro
encoded in the base path still outranks the caller's, and translation only
happens when the reading host is win32, so a caller-named distro cannot make
a POSIX host fabricate a Windows path. The UNC-base branch is exempt from
that gate because that spelling only exists on Windows. Main's other
contracts are verbatim: never null for a non-empty pointer, and a drvfs
pointer keeps its drive spelling even when a distro is named. Both production
call sites (repo-git-marker-scan.ts) pass no options, so they are unchanged.
2. The `.git` gitfile marker parse moves into one shared function,
parseGitdirMarkerPayload: `gitdir:` at the start of the file, payload
trimmed, empty payload rejected — git's own read_gitfile_gently rule.
resolve-git-dir.ts and repo-git-marker-scan.ts both call it; the latter had a
near-identical private copy and is behaviorally identical after the swap
(verified across twelve marker spellings; the only divergence, a
whitespace-only payload, already resolved to null one call further down).
Main's `/^gitdir:\s*(.+)\s*$/m` in resolve-git-dir captured trailing padding
into the path and honored a `gitdir:` line anywhere in the file.
Per-platform delta: none on macOS, Linux, native Windows, WSL, SSH, relay, or
folder workspaces. The wslDistro option is inert; this change adds no caller.
For a malformed `.git` gitfile, padding is now stripped (strict improvement), a
whitespace-only payload falls back to `<worktree>/.git`, and a `gitdir:` line
that is not the first line is no longer honored — a narrowing, since main could
return a working gitdir there. All four resolveGitDir consumers already degrade
through a catch, so that case reports no sparse state / conflict operation /
diff stamp rather than failing.
Six other hand-rolled `gitdir:` parsers remain, including the relay's SSH copy;
converging them is its own change.
62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
import { posix, win32 } from 'node:path'
|
|
import { parseWslUncPath, toWindowsWslDrivePath, toWindowsWslPath } from './wsl-paths'
|
|
|
|
export type GitMetadataPathOptions = {
|
|
/** Host that reads the pointer back. Defaults to the current process platform. */
|
|
platform?: NodeJS.Platform
|
|
/** Distro that wrote the pointer, for callers whose base path does not encode one. Windows-only. */
|
|
wslDistro?: string
|
|
}
|
|
|
|
/**
|
|
* Resolve a Git metadata pointer (a `.git` gitfile payload or a `commondir`) in the path namespace
|
|
* of the host that reads it.
|
|
*
|
|
* Why: git running inside WSL writes these pointers in the guest namespace, but Node reads them
|
|
* back through Win32, where a drvfs pointer like `/mnt/c/repo/.git` silently means
|
|
* `C:\mnt\c\repo\.git`. Returns null only for an empty pointer.
|
|
*/
|
|
export function resolveGitMetadataPath(
|
|
basePath: string,
|
|
rawPath: string,
|
|
options: GitMetadataPathOptions = {}
|
|
): string | null {
|
|
const platform = options.platform ?? process.platform
|
|
const value = rawPath.trim()
|
|
if (!value) {
|
|
return null
|
|
}
|
|
if (value.startsWith('/')) {
|
|
const translated = translateGuestPointer(value, basePath, platform, options.wslDistro)
|
|
if (translated) {
|
|
return translated
|
|
}
|
|
}
|
|
const host = platform === 'win32' ? win32 : posix
|
|
return host.isAbsolute(value) ? value : host.resolve(basePath, value)
|
|
}
|
|
|
|
/**
|
|
* The Win32 spelling of a POSIX-rooted pointer, or null to leave it alone. A WSL UNC base names the
|
|
* distro that wrote the pointer and outranks the caller's guess; failing both, only a drvfs mount
|
|
* has a spelling we can derive.
|
|
*
|
|
* Only a Windows host is translated at all, so a caller-named distro cannot make a POSIX host
|
|
* fabricate a Win32 path. A WSL UNC base is exempt because that spelling only exists on Windows.
|
|
*/
|
|
function translateGuestPointer(
|
|
value: string,
|
|
basePath: string,
|
|
platform: NodeJS.Platform,
|
|
wslDistro: string | undefined
|
|
): string | null {
|
|
const baseDistro = parseWslUncPath(basePath)?.distro
|
|
if (baseDistro) {
|
|
return toWindowsWslPath(value, baseDistro)
|
|
}
|
|
if (platform !== 'win32') {
|
|
return null
|
|
}
|
|
return wslDistro ? toWindowsWslPath(value, wslDistro) : toWindowsWslDrivePath(value)
|
|
}
|