@gitkraken/core-gitlens 0.20.1 → 0.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -1
- package/dist/git/providers/config.d.ts +4 -1
- package/dist/git/providers/remotes.d.ts +18 -0
- package/dist/git-cli/exec/git.js +1 -1
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/providers/config.d.ts +6 -2
- package/dist/git-cli/providers/config.js +47 -7
- package/dist/git-cli/providers/config.js.map +1 -1
- package/dist/git-cli/providers/remotes.d.ts +9 -1
- package/dist/git-cli/providers/remotes.js +79 -4
- package/dist/git-cli/providers/remotes.js.map +1 -1
- package/dist/plus/integrations/providers/models.js +11 -12
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","names":["isAbsolute","resolvePath","dirname"],"sources":["../../../../git-cli/src/exec/git.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport { resolve as resolvePath } from 'path';\nimport * as process from 'process';\nimport type {\n\tBranchErrorReason,\n\tCheckoutErrorReason,\n\tCherryPickErrorReason,\n\tCommitErrorReason,\n\tFetchErrorReason,\n\tGitCommandError,\n\tGitSearchErrorReason,\n\tGitWarningKey,\n\tMergeErrorReason,\n\tPausedOperationAbortErrorReason,\n\tPausedOperationContinueErrorReason,\n\tPullErrorReason,\n\tPushErrorReason,\n\tRebaseErrorReason,\n\tReferenceUpdateErrorReason,\n\tResetErrorReason,\n\tRevertErrorReason,\n\tShowErrorReason,\n\tSigningErrorReason,\n\tStashApplyErrorReason,\n\tStashPushErrorReason,\n\tTagErrorReason,\n\tWorktreeCreateErrorReason,\n\tWorktreeDeleteErrorReason,\n} from '@gitlens/git/errors.js';\nimport { getGitWarning, GitWarnings, WorkspaceUntrustedError } from '@gitlens/git/errors.js';\nimport type { GitHealthSlownessCategory } from '@gitlens/git/gitHealth.js';\nimport type { RepositoryChange } from '@gitlens/git/models/repository.js';\nimport type { SigningFormat } from '@gitlens/git/models/signature.js';\nimport type { GitRunCancellation } from '@gitlens/git/run.types.js';\nimport { CancellationError, getAbortSignalId, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { getScopedCounter } from '@gitlens/utils/counter.js';\nimport { getDurationMilliseconds, hrtime } from '@gitlens/utils/hrtime.js';\nimport { chunkByStringLength } from '@gitlens/utils/iterable.js';\nimport type { LogChannel } from '@gitlens/utils/logger.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport { formatLoggableScopeBlock } from '@gitlens/utils/logger.scoped.js';\nimport { arePathsEqual, dirname, isAbsolute, isDescendant, joinPaths, normalizePath } from '@gitlens/utils/path.js';\nimport { defer } from '@gitlens/utils/promise.js';\nimport type { Mutable } from '@gitlens/utils/types.js';\nimport { compare, fromString } from '@gitlens/utils/version.js';\nimport type { CommandChanges } from './commandClassifier.js';\nimport { getChangesForCommand, leadingCommand } from './commandClassifier.js';\nimport { EventLoopMonitor } from './eventLoopMonitor.js';\nimport { CancelledRunError, RunError } from './exec.errors.js';\nimport type { ProcessSpawner, ProcessSpawnOptions, RunOptions, RunResult } from './exec.js';\nimport { endStdin, fsExists, runSpawn } from './exec.js';\nimport type { GitCommandPriority, GitResult, GitRunOptions, GitSpawnOptions } from './exec.types.js';\nimport type { FilteredGitFeatures, GitFeatureOrPrefix, GitFeatures } from './features.js';\nimport { gitFeaturesByVersion } from './features.js';\nimport type { GitQueueConfig } from './gitQueue.js';\nimport { getPrimaryGitCommand, GitQueue, inferGitCommandPriority } from './gitQueue.js';\nimport type { HeadState } from './headState.js';\nimport { getMovedHead } from './headState.js';\nimport {\n\tisConfigCommand,\n\tisIndexWriteCommand,\n\tKeyedSequencer,\n\tretryWhileConfigLocked,\n\tretryWhileIndexLocked,\n\ttoExitCode,\n} from './indexLock.js';\nimport type { GitLocation } from './locator.js';\n\nexport const slowCallWarningThreshold = 2000;\nexport type GitFeatureUnsupportedMessage = (requiredVersion: string, installedVersion: string) => string;\n/** Below this, a queue-wait annotation isn't worth adding to the log line. */\nconst queueWaitAnnotationThreshold = 100;\n/** Below this, a measured event-loop stall isn't worth annotating — see {@link EventLoopMonitor}. */\nconst eventLoopDelayAnnotationThreshold = 500;\nexport const maxGitCliLength = 30000;\n\n/** Rejections from a host's `beforeIndexLockRetry` — typed writes rethrow these as thrown instead of mapping them to their own error. */\nconst runHookFailures = new WeakSet<object>();\n\nexport function isRunHookFailure(ex: unknown): boolean {\n\treturn typeof ex === 'object' && ex != null && runHookFailures.has(ex);\n}\n\ninterface PendingCommand {\n\treadonly cwd: string | undefined;\n\treadonly promise: Promise<RunResult<string | Buffer>>;\n\tspawned: boolean;\n\t/** The `onSpawn` of the run and of every call that joined it before it spawned */\n\treadonly spawnListeners: (() => void)[];\n}\n\nfunction notifySpawned(listeners: readonly (() => void)[]): void {\n\tfor (const listener of listeners) {\n\t\ttry {\n\t\t\tlistener();\n\t\t} catch (ex) {\n\t\t\tLogger.error(ex, 'GitRunOptions.onSpawn');\n\t\t}\n\t}\n}\n\n/**\n * Splits `paths` into `:(literal)` pathspec batches that each fit the command-line length limit after `prefix`, so a\n * folder named like a glob (`[id]/`) doesn't match its siblings.\n */\nexport function batchLiteralPathspecs(\n\tpaths: readonly string[],\n\tprefix: readonly string[],\n): Iterable<readonly string[]> {\n\t// Reserve the prefix and a per-arg overhead (separator + possible quoting), so neither a run of long paths nor\n\t// many short ones can push a batch past the OS limit\n\tconst perArgOverhead = 3;\n\tconst prefixLength = [...prefix, '--'].reduce((sum, arg) => sum + arg.length + perArgOverhead, 0);\n\treturn chunkByStringLength(\n\t\tpaths.map(p => `:(literal)${p}`),\n\t\tmaxGitCliLength - prefixLength,\n\t\tperArgOverhead,\n\t);\n}\n\nexport const gitConfigsBranch = ['-c', 'color.branch=false'] as const;\nexport const gitConfigsDiff = ['-c', 'color.diff=false', '-c', 'diff.mnemonicPrefix=false'] as const;\nexport const gitConfigsLog = ['-c', 'log.showSignature=false'] as const;\nexport const gitConfigsLogWithFiles = ['-c', 'log.showSignature=false', '-c', 'diff.renameLimit=0'] as const;\nexport const gitConfigsLogWithSignatures = ['-c', 'log.showSignature=true'] as const;\nexport const gitConfigsPull = ['-c', 'merge.autoStash=true', '-c', 'rebase.autoStash=true'] as const;\nexport const gitConfigsStatus = ['-c', 'color.status=false'] as const;\n\nexport const GitErrors = {\n\talreadyCheckedOut: /already checked out/i,\n\talreadyExists: /already exists/i,\n\tambiguousArgument: /fatal:\\s*ambiguous argument ['\"](.+?)['\"]: unknown revision or path not in the working tree/i,\n\tbadObject: /fatal:\\s*bad object (.*?)/i,\n\tbadRevision: /bad revision '(.*?)'/i,\n\tbranchAlreadyExists: /fatal:\\s*A branch named '.+?' already exists/i,\n\tnotFullyMerged: /error:\\s*The branch '.+?' is not fully merged/i,\n\tcantLockRef: /cannot lock ref|unable to update local ref/i,\n\tchangesWouldBeOverwritten:\n\t\t/Your local changes to the following files would be overwritten|Your local changes would be overwritten|overwritten by checkout/i,\n\tcherryPickAborted: /cherry-pick.*aborted/i,\n\tcherryPickInProgress: /cherry-pick is already in progress|You have not concluded your cherry-pick/i,\n\tcommitChangesFirst: /Please, commit your changes before you can/i,\n\tconflict: /^CONFLICT \\([^)]+\\): \\b/m,\n\tdetachedHead: /You are in 'detached HEAD' state/i,\n\tentryNotUpToDate: /error:\\s*Entry ['\"].+['\"] not uptodate\\. Cannot merge\\./i,\n\tfailedToDeleteDirectoryNotEmpty: /failed to delete '(.*?)': Directory not empty/i,\n\tgpgNotFound: /gpg:?\\s*(?:command\\s+)?not found|'gpg' is not recognized as|cannot run gpg:/i,\n\tgpgSignFailed: /^error:\\s*gpg failed to sign the data/im,\n\tinvalidName: /fatal:\\s*'.+?' is not a valid branch name/i,\n\tinvalidLineCount: /file .+? has only (\\d+) lines/i,\n\tinvalidObjectName: /invalid object name: (.*)\\s/i,\n\tinvalidObjectNameList: /could not open object name list: (.*)\\s/i,\n\t// Regcomp failure reasons from `-G`/pathspec regex compilation (search); matched without a known\n\t// prefix as a fallback when the reason appears in an unrecognized stderr shape\n\tinvalidSearchPattern:\n\t\t/Unmatched \\( or \\\\\\(|Unmatched \\[|Unmatched \\) or \\\\\\)|Invalid content of \\\\\\{\\\\\\}|Invalid preceding regular expression|Invalid regular expression|Trailing backslash|invalid regex/i,\n\tinvalidTagName: /invalid tag name/i,\n\tmainWorkingTree: /is a main working tree/i,\n\tmergeAborted: /merge.*aborted/i,\n\tmergeInProgress: /^fatal:\\s*You have not concluded your merge/i,\n\tnoFastForward: /\\(non-fast-forward\\)/i,\n\tnoMergeBase: /no merge base/i,\n\tnoRemoteReference: /unable to delete '.+?': remote ref does not exist/i,\n\tnoRemoteRepositorySpecified: /No remote repository specified\\./i,\n\tnoUpstream: /^fatal:\\s*The current branch .* has no upstream branch/i,\n\t// `git pull` (not `push`) on a branch with no upstream — distinct wording from `noUpstream` above\n\tnoTrackingInformation: /There is no tracking information for the current branch/i,\n\tnotAValidObjectName: /Not a valid object name/i,\n\tnotPossibleToFastForward: /Not possible to fast-forward/i,\n\tnotAWorkingTree: /'(.*?)' is not a working tree/i,\n\tnoUserNameConfigured: /Please tell me who you are\\./i,\n\tnothingToCommit: /nothing(?: added)? to commit|no changes added to commit/i,\n\tnoPausedOperation:\n\t\t/no merge (?:in progress|to abort)|no cherry-pick(?: or revert)? in progress|no rebase in progress/i,\n\tpermissionDenied: /Permission.*denied/i,\n\tpreviousOperationEmpty: /The previous (?:cherry-pick|revert) is now empty/i,\n\tproblemWithEditor: /there was a problem with the editor/i,\n\tpushRejected: /^error:\\s*failed to push some refs to\\b/m,\n\tpushRejectedRefDoesNotExists: /error:\\s*unable to delete '(.*?)': remote ref does not exist/m,\n\trebaseAborted: /Nothing to do|rebase.*aborted/i,\n\trebaseInProgress: /It seems that there is already a rebase-(?:merge|apply) directory/i,\n\trebaseMissingTodo: /error:\\s*could not read file .*\\/git-rebase-todo': No such file or directory/,\n\trebaseMultipleBranches: /cannot rebase onto multiple branches/i,\n\trevertAborted: /revert.*aborted/i,\n\trevertInProgress: /^(error: )?(revert|cherry-pick) is already in progress/i,\n\trefAlreadyExists: /cannot lock ref '.*?': reference already exists/i,\n\trefBadName: /refusing to update ref with bad name/i,\n\trefLocked: /fatal:\\s*cannot lock ref ['\"].+['\"]: unable to create file/i,\n\trefNonexistentObject: /trying to write ref '.*?' with nonexistent object/i,\n\trefNotAValidSha: /not a valid (?:old )?SHA1/i,\n\trefUnableToResolve: /cannot lock ref '.*?': unable to resolve reference/i,\n\trefValueMismatch: /cannot lock ref '.*?': is at [0-9a-f]+ but expected/i,\n\tremoteAhead: /rejected because the remote contains work/i,\n\tremoteConnectionFailed: /Could not read from remote repository/i,\n\tremoteRejected: /rejected because the remote contains work/i,\n\tsigningKeyNotAvailable: /secret key not available|no secret key|no signing key/i,\n\tsshNotFound: /ssh-keygen[^\\n]*(?:not found|No such file or directory|is not recognized)/i,\n\tstashConflictingStagedAndUnstagedLines: /Cannot remove worktree changes/i,\n\tstashNothingToSave: /No local changes to save/i,\n\tstashSavedWorkingDirAndIndexState: /Saved working directory and index state/i,\n\ttagAlreadyExists: /tag .* already exists/i,\n\ttagConflict: /! \\[rejected\\].*\\(would clobber existing tag\\)/m,\n\ttagNotFound: /tag .* not found/i,\n\tuncommittedChanges: /contains modified or untracked files/i,\n\tunmergedChanges: /error:\\s*you need to resolve your current index first/i,\n\tunmergedFiles: /is not possible because you have unmerged files|You have unmerged files/i,\n\tunresolvedConflicts:\n\t\t/You must edit all merge conflicts|Resolve all conflicts|^CONFLICT \\(|^Automatic merge failed|could not apply .*/im,\n\tunsafeRepository:\n\t\t/(?:^fatal:\\s*detected dubious ownership in repository at '([^']+)'|unsafe repository \\('([^']+)' is owned by someone else\\))[\\s\\S]*(git config --global --add safe\\.directory [^\\n•]+)/m,\n\tunstagedChanges: /You have unstaged changes/i,\n\t// Matches both variants: with a lock reason (`..., lock reason: <reason>`) and without (`...;`)\n\tworktreeLocked: /fatal:\\s*cannot remove a locked working tree/i,\n\t// Only matches the variant where Git reports a lock reason; the reason is free text, so capture the whole line\n\tworktreeLockedReason: /cannot remove a locked working tree,[ \\t]*lock reason:[ \\t]*(.*)/i,\n} as const;\n\n// `GitWarnings` moved to `@gitlens/git/errors.js` so the shared run contract can name its keys; re-exported\n// here because it's long-established as part of this module's surface.\nexport { GitWarnings };\nexport type { GitWarningKey } from '@gitlens/git/errors.js';\n\nexport class GitError extends Error {\n\treadonly cmd: string | undefined;\n\treadonly exitCode: number | string | undefined;\n\treadonly stdout: string | undefined;\n\treadonly stderr: string | undefined;\n\n\tconstructor(readonly original: Error) {\n\t\tlet message: string;\n\t\tlet stdout: string | undefined;\n\t\tlet stderr: string | undefined;\n\t\tlet cmd: string | undefined;\n\t\tlet exitCode: number | string | undefined;\n\n\t\tif (original instanceof RunError) {\n\t\t\tstdout = original.stdout;\n\t\t\tstderr = original.stderr;\n\t\t\tmessage = stderr || stdout || original.message;\n\t\t\tcmd = original.cmd;\n\t\t\texitCode = original.code;\n\t\t} else {\n\t\t\tmessage = original.message;\n\t\t}\n\n\t\tsuper(message);\n\n\t\tthis.stdout = stdout;\n\t\tthis.stderr = stderr;\n\t\tthis.cmd = cmd;\n\t\tthis.exitCode = exitCode;\n\n\t\tError.captureStackTrace?.(this, new.target);\n\t}\n}\n\nexport type PushForceOptions = { withLease: true; ifIncludes?: boolean } | { withLease: false; ifIncludes?: never };\n\ntype GitCommand =\n\t| 'branch'\n\t| 'checkout'\n\t| 'cherry-pick'\n\t| 'commit'\n\t| 'fetch'\n\t| 'merge'\n\t| 'paused-operation-abort'\n\t| 'paused-operation-continue'\n\t| 'pull'\n\t| 'push'\n\t| 'rebase'\n\t| 'reset'\n\t| 'revert'\n\t| 'show'\n\t| 'stash-apply'\n\t| 'stash-push'\n\t| 'tag'\n\t| 'update-ref'\n\t| 'update-ref-delete'\n\t| 'worktree-create'\n\t| 'worktree-delete';\n\ntype GitCommandToReasonMap = {\n\tbranch: BranchErrorReason;\n\tcheckout: CheckoutErrorReason;\n\t'cherry-pick': CherryPickErrorReason;\n\tcommit: CommitErrorReason;\n\tfetch: FetchErrorReason;\n\tmerge: MergeErrorReason;\n\t'paused-operation-abort': PausedOperationAbortErrorReason;\n\t'paused-operation-continue': PausedOperationContinueErrorReason;\n\tpull: PullErrorReason;\n\tpush: PushErrorReason;\n\trebase: RebaseErrorReason;\n\treset: ResetErrorReason;\n\trevert: RevertErrorReason;\n\tshow: ShowErrorReason;\n\t'stash-apply': StashApplyErrorReason;\n\t'stash-push': StashPushErrorReason;\n\ttag: TagErrorReason;\n\t'update-ref': ReferenceUpdateErrorReason;\n\t'update-ref-delete': ReferenceUpdateErrorReason;\n\t'worktree-create': WorktreeCreateErrorReason;\n\t'worktree-delete': WorktreeDeleteErrorReason;\n};\n\nconst errorToReasonMap = new Map<GitCommand, [RegExp, GitCommandToReasonMap[GitCommand]][]>([\n\t[\n\t\t'branch',\n\t\t[\n\t\t\t[GitErrors.branchAlreadyExists, 'alreadyExists'],\n\t\t\t[GitErrors.invalidName, 'invalidName'],\n\t\t\t[GitErrors.notFullyMerged, 'notFullyMerged'],\n\t\t\t[GitErrors.noRemoteReference, 'noRemoteReference'],\n\t\t],\n\t],\n\t[\n\t\t'checkout',\n\t\t[\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t\t[GitErrors.ambiguousArgument, 'pathspecNotFound'],\n\t\t\t[GitErrors.notAValidObjectName, 'invalidRef'],\n\t\t],\n\t],\n\t[\n\t\t'cherry-pick',\n\t\t[\n\t\t\t[GitErrors.cherryPickAborted, 'aborted'],\n\t\t\t[GitErrors.cherryPickInProgress, 'alreadyInProgress'],\n\t\t\t[GitErrors.conflict, 'conflicts'],\n\t\t\t[GitErrors.previousOperationEmpty, 'emptyCommit'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t[\n\t\t'commit',\n\t\t[\n\t\t\t[GitErrors.nothingToCommit, 'nothingToCommit'],\n\t\t\t[GitErrors.unmergedFiles, 'conflicts'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.noUserNameConfigured, 'noUserNameConfigured'],\n\t\t],\n\t],\n\t[\n\t\t'fetch',\n\t\t[\n\t\t\t[GitErrors.noFastForward, 'noFastForward'],\n\t\t\t[GitErrors.noRemoteRepositorySpecified, 'noRemote'],\n\t\t\t[GitErrors.remoteConnectionFailed, 'remoteConnectionFailed'],\n\t\t],\n\t],\n\t[\n\t\t'merge',\n\t\t[\n\t\t\t[GitErrors.mergeAborted, 'aborted'],\n\t\t\t[GitErrors.mergeInProgress, 'alreadyInProgress'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t['paused-operation-abort', [[GitErrors.noPausedOperation, 'nothingToAbort']]],\n\t[\n\t\t'paused-operation-continue',\n\t\t[\n\t\t\t// Kept FIRST: an editor failure's stderr can also carry broader messages (\"could not\n\t\t\t// commit staged changes\", …) that later patterns would otherwise claim\n\t\t\t[GitErrors.problemWithEditor, 'messageEditFailed'],\n\t\t\t[GitErrors.previousOperationEmpty, 'emptyCommit'],\n\t\t\t[GitErrors.noPausedOperation, 'nothingToContinue'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.unmergedFiles, 'unmergedFiles'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.unstagedChanges, 'unstagedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t\t// A single (non-sequencer) revert resolved to a no-op never gets git's \"previous revert is now\n\t\t\t// empty\" message — its `--continue` falls through to the commit, which reports having nothing to\n\t\t\t// commit. Mid-paused-op that means the step became empty, so it earns the same choice.\n\t\t\t//\n\t\t\t// Kept LAST because the pattern is deliberately broad: it also matches \"no changes added to\n\t\t\t// commit\" and \"nothing added to commit\", which appear alongside the more specific unmerged /\n\t\t\t// conflict / unstaged messages. Matching first would shadow those. It isn't narrowed to the\n\t\t\t// \"working tree clean\" variant because an empty step with untracked files present instead reports\n\t\t\t// \"nothing added to commit but untracked files present\".\n\t\t\t[GitErrors.nothingToCommit, 'emptyCommit'],\n\t\t],\n\t],\n\t[\n\t\t'pull',\n\t\t[\n\t\t\t[GitErrors.conflict, 'conflict'],\n\t\t\t[GitErrors.noUserNameConfigured, 'gitIdentity'],\n\t\t\t[GitErrors.remoteConnectionFailed, 'remoteConnectionFailed'],\n\t\t\t[GitErrors.unstagedChanges, 'unstagedChanges'],\n\t\t\t[GitErrors.unmergedFiles, 'unmergedFiles'],\n\t\t\t[GitErrors.commitChangesFirst, 'uncommittedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t\t[GitErrors.cantLockRef, 'refLocked'],\n\t\t\t[GitErrors.rebaseMultipleBranches, 'rebaseMultipleBranches'],\n\t\t\t[GitErrors.tagConflict, 'tagConflict'],\n\t\t\t[GitErrors.notPossibleToFastForward, 'noFastForward'],\n\t\t\t[GitErrors.noTrackingInformation, 'noUpstream'],\n\t\t],\n\t],\n\t[\n\t\t'push',\n\t\t[\n\t\t\t[GitErrors.remoteAhead, 'remoteAhead'],\n\t\t\t[GitWarnings.tipBehind, 'tipBehind'],\n\t\t\t// Kept BEFORE the generic push rejection: a failed `push -d` of a missing ref reports both\n\t\t\t// \"unable to delete '<ref>': remote ref does not exist\" and \"failed to push some refs to ...\",\n\t\t\t// and the specific reason is the actionable one.\n\t\t\t[GitErrors.pushRejectedRefDoesNotExists, 'rejectedRefDoesNotExist'],\n\t\t\t[GitErrors.pushRejected, 'rejected'],\n\t\t\t[GitErrors.permissionDenied, 'permissionDenied'],\n\t\t\t[GitErrors.remoteConnectionFailed, 'remoteConnectionFailed'],\n\t\t\t[GitErrors.noUpstream, 'noUpstream'],\n\t\t],\n\t],\n\t[\n\t\t'rebase',\n\t\t[\n\t\t\t[GitErrors.rebaseAborted, 'aborted'],\n\t\t\t[GitErrors.rebaseMissingTodo, 'aborted'],\n\t\t\t[GitErrors.rebaseInProgress, 'alreadyInProgress'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t[\n\t\t'reset',\n\t\t[\n\t\t\t[GitErrors.ambiguousArgument, 'ambiguousArgument'],\n\t\t\t[GitErrors.detachedHead, 'detachedHead'],\n\t\t\t[GitErrors.refLocked, 'refLocked'],\n\t\t\t[GitErrors.entryNotUpToDate, 'notUpToDate'],\n\t\t\t[GitErrors.permissionDenied, 'permissionDenied'],\n\t\t\t[GitErrors.unmergedChanges, 'unmergedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t[\n\t\t'revert',\n\t\t[\n\t\t\t[GitErrors.revertAborted, 'aborted'],\n\t\t\t[GitErrors.revertInProgress, 'alreadyInProgress'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t[\n\t\t'show',\n\t\t[\n\t\t\t[GitErrors.badObject, 'invalidObject'],\n\t\t\t[GitErrors.badRevision, 'invalidRevision'],\n\t\t\t[GitErrors.notAValidObjectName, 'invalidRevision'],\n\t\t\t[GitWarnings.notFound, 'notFound'],\n\t\t\t[GitWarnings.foundButNotInRevision, 'notInRevision'],\n\t\t],\n\t],\n\t['stash-apply', [[GitErrors.changesWouldBeOverwritten, 'uncommittedChanges']]],\n\t[\n\t\t'stash-push',\n\t\t[\n\t\t\t[GitErrors.stashConflictingStagedAndUnstagedLines, 'conflictingStagedAndUnstagedLines'],\n\t\t\t[GitErrors.stashNothingToSave, 'nothingToSave'],\n\t\t\t[GitErrors.stashSavedWorkingDirAndIndexState, 'conflictingStagedAndUnstagedLines'],\n\t\t],\n\t],\n\t[\n\t\t'tag',\n\t\t[\n\t\t\t[GitErrors.tagAlreadyExists, 'alreadyExists'],\n\t\t\t[GitErrors.invalidTagName, 'invalidName'],\n\t\t\t[GitErrors.tagNotFound, 'notFound'],\n\t\t\t[GitErrors.permissionDenied, 'permissionDenied'],\n\t\t\t[GitErrors.remoteRejected, 'remoteRejected'],\n\t\t\t[GitErrors.tagConflict, 'tagConflict'],\n\t\t],\n\t],\n\t[\n\t\t'update-ref',\n\t\t[\n\t\t\t// Every entry below also matches the broad `cantLockRef` catch-all that closes the list, so\n\t\t\t// order is load-bearing — the specific shapes must be claimed first.\n\t\t\t[GitErrors.refBadName, 'invalidRef'],\n\t\t\t[GitErrors.refNonexistentObject, 'invalidObject'],\n\t\t\t[GitErrors.refNotAValidSha, 'invalidObject'],\n\t\t\t[GitErrors.refValueMismatch, 'conflict'],\n\t\t\t[GitErrors.refAlreadyExists, 'conflict'],\n\t\t\t// A ref that vanished under a compare-and-swap lost the same race as one that moved, so an\n\t\t\t// update reports both as a conflict — the caller's response (re-read, retry) is identical.\n\t\t\t[GitErrors.refUnableToResolve, 'conflict'],\n\t\t\t// Directory/file collisions and any other lock refusal\n\t\t\t[GitErrors.cantLockRef, 'conflict'],\n\t\t],\n\t],\n\t[\n\t\t'update-ref-delete',\n\t\t[\n\t\t\t[GitErrors.refBadName, 'invalidRef'],\n\t\t\t[GitErrors.refNotAValidSha, 'invalidObject'],\n\t\t\t// Kept BEFORE the generic lock failures, and split from the update table above: a deleter\n\t\t\t// that finds its target already gone has reached the state it wanted, while one that finds\n\t\t\t// the target moved has not. Collapsing both into `conflict` would force every caller to\n\t\t\t// re-read just to tell an idempotent no-op from a real race.\n\t\t\t[GitErrors.refUnableToResolve, 'notFound'],\n\t\t\t[GitErrors.refValueMismatch, 'conflict'],\n\t\t\t[GitErrors.cantLockRef, 'conflict'],\n\t\t],\n\t],\n\t[\n\t\t'worktree-create',\n\t\t[\n\t\t\t[GitErrors.alreadyCheckedOut, 'alreadyCheckedOut'],\n\t\t\t[GitErrors.alreadyExists, 'alreadyExists'],\n\t\t],\n\t],\n\t[\n\t\t'worktree-delete',\n\t\t[\n\t\t\t// Must come first -- a locked worktree's lock reason is free text that can otherwise match the errors below\n\t\t\t[GitErrors.worktreeLocked, 'locked'],\n\t\t\t[GitErrors.mainWorkingTree, 'defaultWorkingTree'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.failedToDeleteDirectoryNotEmpty, 'directoryNotEmpty'],\n\t\t],\n\t],\n]);\n\nexport function getGitCommandError<T extends GitCommand, TReturn extends GitCommandError<any>>(\n\tcommand: T,\n\tex: GitError,\n\tcreator: (reason: GitCommandToReasonMap[T] | undefined) => TReturn,\n): TReturn {\n\tconst msg: string = ex?.toString() ?? '';\n\n\tconst errorsToReasons = errorToReasonMap.get(command) as [RegExp, GitCommandToReasonMap[T]][] | undefined;\n\tif (errorsToReasons != null) {\n\t\tfor (const [error, reason] of errorsToReasons) {\n\t\t\tif (error.test(msg) || (ex.stderr && error.test(ex.stderr)) || (ex.stdout && error.test(ex.stdout))) {\n\t\t\t\treturn creator(reason);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn creator(undefined);\n}\n\nfunction extractSigningErrorText(ex: unknown): string {\n\tif (ex == null) return '';\n\tif (ex instanceof GitError) return ex.stderr || ex.stdout || ex.message || '';\n\tif (ex instanceof Error) return ex.message || '';\n\tif (typeof ex === 'string') return ex;\n\tif (typeof ex === 'number' || typeof ex === 'boolean' || typeof ex === 'bigint') return String(ex);\n\tif (typeof ex === 'object' && 'message' in ex && typeof ex.message === 'string') return ex.message;\n\treturn '';\n}\n\n/**\n * Classifies a Git error as a signing-related failure using the {@link GitErrors}\n * signing regexes. Returns the matched {@link SigningErrorReason}, or `undefined`\n * when the error is not a recognized signing failure.\n *\n * Precedence is significant: `passphraseFailed` (gpg sign failure) is checked\n * before `noKey`, matching the ordering used historically in patch.ts — a\n * combined stderr like \"error: gpg failed to sign … gpg: No secret key\"\n * resolves to `passphraseFailed`, the outer cause.\n */\nexport function classifySigningError(ex: unknown): SigningErrorReason | undefined {\n\tconst text = extractSigningErrorText(ex);\n\tif (!text) return undefined;\n\tif (GitErrors.gpgSignFailed.test(text)) return 'passphraseFailed';\n\tif (GitErrors.signingKeyNotAvailable.test(text)) return 'noKey';\n\tif (GitErrors.gpgNotFound.test(text)) return 'gpgNotFound';\n\tif (GitErrors.sshNotFound.test(text)) return 'sshNotFound';\n\treturn undefined;\n}\n\n/**\n * Infers the {@link SigningFormat} from stderr hints (e.g., mentions of\n * `ssh-keygen` or `gpg.ssh.*` config keys). Returns `undefined` when no hints\n * are present so callers can supply their own default (typically `'gpg'`).\n *\n * Used as a fallback when `config.getSigningConfig` is unavailable or rejects\n * on the error path.\n */\nexport function inferSigningFormatFromError(ex: unknown): SigningFormat | undefined {\n\tconst text = extractSigningErrorText(ex);\n\tif (!text) return undefined;\n\tif (/\\bssh-keygen\\b|gpg\\.ssh\\.(?:program|allowedsignersfile)/i.test(text)) return 'ssh';\n\tif (/\\bgpg\\b/i.test(text)) return 'gpg';\n\treturn undefined;\n}\n\nexport interface SearchErrorClassification {\n\treason: GitSearchErrorReason;\n\tdetail?: string;\n}\n\n/**\n * Classifies a graph search failure from its stderr into an {@link GitSearchErrorReason}, with the\n * offending pattern/ref text (when git reports one) as `detail`. Returns `undefined` when the error\n * isn't a `GitError` with stderr, or the stderr doesn't match a recognized shape.\n */\nexport function classifySearchError(ex: unknown): SearchErrorClassification | undefined {\n\tif (!(ex instanceof GitError) || !ex.stderr) return undefined;\n\n\tconst stderr = ex.stderr;\n\n\t// `-G<pattern>`/pathspec regex compile failures report one of two shapes:\n\t// fatal: command line, '<pattern>': <regcomp reason>\n\t// fatal: invalid regex: <regcomp reason>\n\t// The pattern itself may contain \"': \", so anchor on the known prefixes and let the greedy `.*`\n\t// resolve to the LAST matching delimiter rather than splitting on the first occurrence.\n\tconst patternDetail =\n\t\t/^fatal:\\s*command line,\\s*'.*':\\s*(.+)$/im.exec(stderr)?.[1] ??\n\t\t/^fatal:\\s*invalid regex:\\s*(.+)$/im.exec(stderr)?.[1];\n\tif (patternDetail != null) return { reason: 'invalidPattern', detail: patternDetail.trim() };\n\n\tif (GitErrors.invalidSearchPattern.test(stderr)) return { reason: 'invalidPattern' };\n\n\tconst ambiguous = GitErrors.ambiguousArgument.exec(stderr);\n\tif (ambiguous != null) return { reason: 'invalidRef', detail: ambiguous[1] };\n\n\tconst badRevision = GitErrors.badRevision.exec(stderr);\n\tif (badRevision != null) return { reason: 'invalidRef', detail: badRevision[1] };\n\n\tif (/unknown revision/i.test(stderr)) return { reason: 'invalidRef' };\n\n\treturn undefined;\n}\n\nexport interface GitOptions {\n\t/** Custom environment variables to add to every git command */\n\tenv?: Record<string, string | undefined>;\n\t/** Dynamic environment provider called for each command (e.g., host-discovered SCM credentials) */\n\tgetEnvironment?: () => Record<string, string | undefined> | undefined;\n\t/** Git command timeout in milliseconds, for runs that don't set their own. Defaults to 60000. Set to 0 to disable. */\n\tgitTimeout?: number;\n\t/** Returns whether the workspace is currently trusted. Defaults to true when not provided. Called on every exec/stream. */\n\tisTrusted?: () => boolean;\n\t/** Queue configuration (max concurrent processes, etc.) */\n\tqueue?: GitQueueConfig;\n\t/** Decodes non-UTF-8 git output. Required when repositories use non-UTF-8 encodings. */\n\tdecode?: (data: Uint8Array, options?: { readonly encoding: string }) => string | Promise<string>;\n\t/** Hooks for observing git execution events */\n\thooks?: GitHooks;\n\t/** Optional dedicated logger for git command logging */\n\tlogger?: LogChannel;\n\t/** Launches the git process of every run and stream (not the locator's); defaults to Node's `spawn`. Set it to start git from a helper process when the host's own is too large to fork cheaply. */\n\tspawn?: ProcessSpawner;\n}\n\nexport interface GitHooks {\n\t/** Called when a git command is aborted (timeout or cancellation) */\n\tonAborted?(info: {\n\t\toperation: string;\n\t\treason: 'timeout' | 'cancellation' | 'unknown';\n\t\tduration: number;\n\t\ttimeout: number;\n\t}): void;\n\t/** Called when a queued command waited longer than 1s before executing */\n\tonSlowQueue?(info: {\n\t\tpriority: GitCommandPriority;\n\t\twaitTime: number;\n\t\tactive: number;\n\t\tqueued: Record<GitCommandPriority, number>;\n\t\tmaxConcurrent: number;\n\t}): void;\n\t/**\n\t * Called once per git command that ran slowly (over the slow-call threshold). Fired only for the\n\t * command that actually executed, never for a deduplicated rider that merely awaited it, so a single\n\t * slow subprocess counts once. `operation` is the primary git subcommand (e.g. `status`, `rev-list`).\n\t */\n\tonSlowCommand?(info: {\n\t\toperation: string | undefined;\n\t\tcwd: string | undefined;\n\t\tduration: number;\n\t\t/** Measured event-loop stall overlapping the command; omitted (or 0) when none was observed. */\n\t\teventLoopDelay?: number;\n\t\t/** Caller-declared operation family, see `GitRunOptions.slownessCategory`. */\n\t\tslownessCategory?: GitHealthSlownessCategory;\n\t}): void;\n}\n\n/**\n * Keys dropped from the INHERITED `process.env` before it seeds the base git environment. git hands these\n * to anything it launches (a hook, `rebase -x`, an editor invoked as `GIT_EDITOR`) to describe the command\n * it is running; a host started that way would otherwise run every command against THAT repository with\n * THAT command's settings, whatever `cwd` we pass. None is worth keeping when set deliberately either: a\n * `GIT_DIR` would point every repository the host opens at one. `options.env`, `options.getEnvironment()`\n * and a per-call `env` are merged in afterwards, so any of them can still set these keys (e.g. a temporary\n * `GIT_INDEX_FILE` for a call).\n */\nconst inheritedEnvKeysToDrop: ReadonlySet<string> = new Set([\n\t// The parent's repository location — must come from our own cwd\n\t'GIT_DIR',\n\t'GIT_WORK_TREE',\n\t'GIT_INDEX_FILE',\n\t'GIT_COMMON_DIR',\n\t'GIT_OBJECT_DIRECTORY',\n\t'GIT_ALTERNATE_OBJECT_DIRECTORIES',\n\t'GIT_NAMESPACE',\n\t// What git tells a child about the command it's running: its `-c` overrides, its helpers' location, the\n\t// subdirectory it ran from, and the label for its reflog entries\n\t'GIT_CONFIG_PARAMETERS',\n\t'GIT_EXEC_PATH',\n\t'GIT_PREFIX',\n\t'GIT_REFLOG_ACTION',\n]);\n\n/**\n * Dropped only when git launched the host, which it always marks by exporting `GIT_EXEC_PATH`: an editor\n * opened for `commit --amend` gets that commit's author and date, while an identity set deliberately (e.g.\n * by direnv) must still reach our commits.\n */\nconst inheritedIdentityKeysToDrop: ReadonlySet<string> = new Set([\n\t'GIT_AUTHOR_NAME',\n\t'GIT_AUTHOR_EMAIL',\n\t'GIT_AUTHOR_DATE',\n\t'GIT_COMMITTER_NAME',\n\t'GIT_COMMITTER_EMAIL',\n\t'GIT_COMMITTER_DATE',\n]);\n\n/** `process.env` with {@link inheritedEnvKeysToDrop} removed, and {@link inheritedIdentityKeysToDrop} when git launched us. */\nfunction getInheritedEnv(): Record<string, string | undefined> {\n\tconst launchedByGit = process.env.GIT_EXEC_PATH != null;\n\treturn Object.fromEntries(\n\t\tObject.entries(process.env).filter(\n\t\t\t([key]) => !inheritedEnvKeysToDrop.has(key) && !(launchedByGit && inheritedIdentityKeysToDrop.has(key)),\n\t\t),\n\t);\n}\n\nconst emptyArray: readonly never[] = Object.freeze([]);\nconst emptyObj = Object.freeze({});\nconst trailingNewlineRegex = /[\\r|\\n]+$/;\nconst unsharedRunCounter = getScopedCounter();\nconst uniqueCounterForStream = getScopedCounter();\n\ntype ExitCodeOnlyGitCommandOptions = GitRunOptions & { exitCodeOnly: true };\n\n/** What a `notify`-flagged run announces once it settles, worked out before it spawns */\ntype PendingNotify =\n\t/** An explicit `notify` list, announced as given */\n\t| { readonly cwd: string; readonly pathOverride: string | undefined; readonly changes: readonly RepositoryChange[] }\n\t/** `notify: 'infer'`'s classification, with HEAD before the run when the verb moves only HEAD's branch */\n\t| { readonly cwd: string; readonly command: CommandChanges; readonly headBefore: HeadState };\n\n/** The refs a `notify`-flagged run proved it moved, as {@link Git.bindChangeNotifier} passes them on */\nexport type NamedRefs = { readonly refs: readonly string[]; readonly configConfinedToRefs?: boolean };\n\nexport class Git {\n\t/** Map of running git commands — avoids running duplicate overlapping commands */\n\tprivate readonly pendingCommands = new Map<string, PendingCommand>();\n\t/** Queue for throttling background git operations */\n\tprivate readonly _queue: GitQueue;\n\t/** Orders the index-writing runs of each checkout, so they don't race for its `index.lock` */\n\tprivate readonly _indexWrites = new KeyedSequencer();\n\t/** The spawn behind every non-streaming run — a field only so tests can substitute it */\n\tprivate readonly _runSpawn: typeof runSpawn = runSpawn;\n\t/** Detects event-loop stalls while at least one git command is in flight */\n\tprivate readonly _eventLoopMonitor = new EventLoopMonitor();\n\t/** Count of git commands currently in flight, across both the exec and streaming paths */\n\tprivate _activeCommandCount = 0;\n\n\t/** Cached base environment: process.env (minus {@link inheritedEnvKeysToDrop}) + static options.env + GCM/LC_ALL vars */\n\tprivate _baseEnv: Record<string, string | undefined> | undefined;\n\t/** Cached full environment: base + dynamic getEnvironment() result */\n\tprivate _fullEnv: Record<string, string | undefined> | undefined;\n\t/** Last dynamic env reference, used to detect when getEnvironment() returns a new object */\n\tprivate _lastDynamicEnv: Record<string, string | undefined> | undefined | null;\n\n\t/** Bound via {@link bindChangeNotifier}; announces a `notify`-flagged run's changes. No-op until bound. */\n\tprivate _changeNotifier:\n\t\t| ((\n\t\t\t\trepoPaths: readonly string[],\n\t\t\t\tchanges: readonly RepositoryChange[],\n\t\t\t\tsharedPaths?: readonly string[],\n\t\t\t\tnamed?: NamedRefs,\n\t\t ) => void)\n\t\t| undefined;\n\t/** Bound via {@link bindHeadReader}; reads HEAD around a `notify: 'infer'` run that moves only HEAD's branch */\n\tprivate _headReader: ((path: string) => Promise<HeadState>) | undefined;\n\t/** Bound via {@link bindIgnoredWorktreeRootsReader}; read before a `notify: 'infer'` worktree write */\n\tprivate _ignoredWorktreeRootsReader: ((path: string) => Promise<readonly string[] | undefined>) | undefined;\n\t/** The classifier behind `notify: 'infer'` — a field only so tests can substitute it */\n\tprivate readonly _classify: typeof getChangesForCommand = getChangesForCommand;\n\n\tconstructor(\n\t\tprivate readonly _locator: () => Promise<GitLocation>,\n\t\treadonly options: GitOptions = {},\n\t) {\n\t\tthis._queue = new GitQueue(options.queue, { onSlowQueue: options.hooks?.onSlowQueue });\n\t}\n\n\t/**\n\t * Binds the callback a `notify`-flagged {@link run} calls once it settles. `CliGitProvider` wires this\n\t * to its own `notifyChanged` from its constructor — including when it's handed a pre-built `Git` via\n\t * `options.git`, so a host-supplied instance gets bound too. With nothing bound, `notify` is a no-op.\n\t * `repoPaths` holds more than one path only for a `-C`-scoped shared-state verb: the `-C` target, then the\n\t * caller's own `cwd`. `sharedPaths` names the paths that were not run in but share the repository, which\n\t * hear only the part of `changes` every worktree sees (the caller's `cwd`, when the verb also changed\n\t * something local to the `-C` target). `named.refs`, given only when the run proved them, are the full ref\n\t * names it moved, as `repository.onChanged`'s `refs` are: `repoPaths` hear all of them, `sharedPaths` those of\n\t * the kinds they hear. `named.configConfinedToRefs` confines a `config` change to those branches' sections.\n\t */\n\tbindChangeNotifier(\n\t\tfn: (\n\t\t\trepoPaths: readonly string[],\n\t\t\tchanges: readonly RepositoryChange[],\n\t\t\tsharedPaths?: readonly string[],\n\t\t\tnamed?: NamedRefs,\n\t\t) => void,\n\t): void {\n\t\tthis._changeNotifier = fn;\n\t}\n\n\t/**\n\t * Binds the reader a `notify: 'infer'` {@link run} of a verb that moves only HEAD's branch (a commit, a reset)\n\t * calls on the tree it runs in, before and after the run, to name that branch. It must not run git, and resolves\n\t * `undefined` when HEAD can't be read. With nothing bound, such a run announces its branch move unnamed.\n\t */\n\tbindHeadReader(fn: (path: string) => Promise<HeadState>): void {\n\t\tthis._headReader = fn;\n\t}\n\n\t/**\n\t * Binds the reader a `notify: 'infer'` {@link run} of a worktree write calls on the tree it runs in: the absolute\n\t * folders, under that repository's common git dir, whose worktrees the host has core ignore. No worktree list shows\n\t * one, so its add, remove, lock, unlock or move announces no `worktrees` change. Each folder comes in every spelling\n\t * a path may take (as the host spells the git dir, and resolved through symlinks); a path spelled through some other\n\t * symlink keeps the change. It runs git at most once per repository (for a common git dir its files don't show),\n\t * resolves `[]` (or `undefined`) when nothing is ignored, and rejects when the folders can't be read, which keeps the\n\t * change. With nothing bound, every worktree write announces `worktrees`.\n\t */\n\tbindIgnoredWorktreeRootsReader(fn: (path: string) => Promise<readonly string[] | undefined>): void {\n\t\tthis._ignoredWorktreeRootsReader = fn;\n\t}\n\n\t/**\n\t * Returns the base environment for git commands. Cached to avoid spreading\n\t * process.env (30-100+ keys) on every call. Includes static options.env and\n\t * GCM/LC_ALL vars but NOT dynamic getEnvironment() or per-call env overrides.\n\t */\n\tprivate getBaseEnv(): Record<string, string | undefined> {\n\t\treturn (this._baseEnv ??= {\n\t\t\t...getInheritedEnv(),\n\t\t\t...(this.options.env ?? emptyObj),\n\t\t\tGCM_INTERACTIVE: 'NEVER',\n\t\t\tGCM_PRESERVE_CREDS: 'TRUE',\n\t\t\tLC_ALL: 'C',\n\t\t});\n\t}\n\n\t/**\n\t * Returns the full environment (base + dynamic). Cached and invalidated\n\t * when getEnvironment() returns a different object reference.\n\t */\n\tprivate getFullEnv(): Record<string, string | undefined> {\n\t\tconst dynamicEnv = this.options.getEnvironment?.() ?? undefined;\n\t\tif (this._fullEnv != null && dynamicEnv === this._lastDynamicEnv) return this._fullEnv;\n\n\t\tthis._lastDynamicEnv = dynamicEnv;\n\t\tthis._fullEnv = dynamicEnv != null ? { ...this.getBaseEnv(), ...dynamicEnv } : this.getBaseEnv();\n\t\treturn this._fullEnv;\n\t}\n\n\t/**\n\t * Builds the environment for a git command. Returns the cached full env\n\t * directly when there are no per-call overrides (the common case).\n\t * Only allocates a new object when per-call env overrides are provided.\n\t */\n\tprivate buildEnv(perCallEnv: Record<string, string | undefined> | undefined): Record<string, string | undefined> {\n\t\tif (perCallEnv == null) return this.getFullEnv();\n\n\t\treturn { ...this.getFullEnv(), ...perCallEnv };\n\t}\n\n\tdispose(): void {\n\t\tthis._queue.dispose();\n\t\tthis._eventLoopMonitor.dispose();\n\t}\n\n\t/**\n\t * Drops in-flight commands so a later identical call spawns its own run instead of joining one that\n\t * started before a change. With `repoPaths`, drops only runs whose `cwd` is one of them or inside one;\n\t * without, drops every run.\n\t */\n\tclearPendingCommands(repoPaths?: readonly string[]): void {\n\t\tif (repoPaths == null) {\n\t\t\tthis.pendingCommands.clear();\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const [key, { cwd }] of this.pendingCommands) {\n\t\t\tif (cwd == null) continue;\n\n\t\t\tif (repoPaths.some(p => arePathsEqual(cwd, p) || isDescendant(cwd, p))) {\n\t\t\t\tthis.pendingCommands.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Marks one more git command as in flight; starts the event-loop monitor on the first. */\n\tprivate beginActiveCommand(): void {\n\t\tthis._activeCommandCount++;\n\t\tif (this._activeCommandCount === 1) {\n\t\t\tthis._eventLoopMonitor.start();\n\t\t}\n\t}\n\n\t/** Marks a git command as finished; stops the event-loop monitor once none remain. */\n\tprivate endActiveCommand(): void {\n\t\tthis._activeCommandCount--;\n\t\tif (this._activeCommandCount === 0) {\n\t\t\tthis._eventLoopMonitor.stop();\n\t\t}\n\t}\n\n\t/** Formats the shared \"event loop blocked\" log annotation; undefined below {@link eventLoopDelayAnnotationThreshold}. */\n\tprivate formatEventLoopDelayAnnotation(sinceEpochMs: number): string | undefined {\n\t\tconst delay = this._eventLoopMonitor.maxDelaySince(sinceEpochMs);\n\t\treturn delay >= eventLoopDelayAnnotationThreshold ? `event loop blocked ~${delay}ms` : undefined;\n\t}\n\n\tprivate _gitLocation: GitLocation | undefined;\n\tprivate _gitLocationPromise: Promise<GitLocation> | undefined;\n\n\tprivate async getLocation(): Promise<GitLocation> {\n\t\tif (this._gitLocation == null) {\n\t\t\tthis._gitLocationPromise ??= this._locator();\n\t\t\tthis._gitLocation = await this._gitLocationPromise;\n\t\t}\n\t\treturn this._gitLocation;\n\t}\n\n\tasync path(): Promise<string> {\n\t\treturn (await this.getLocation()).path;\n\t}\n\n\tasync version(): Promise<string> {\n\t\treturn (await this.getLocation()).version;\n\t}\n\n\tsupports(feature: GitFeatures): boolean | Promise<boolean> {\n\t\tconst version = gitFeaturesByVersion.get(feature);\n\t\tif (version == null) return true;\n\n\t\treturn this._gitLocation != null\n\t\t\t? compare(fromString(this._gitLocation.version), fromString(version)) !== -1\n\t\t\t: this.version().then(v => compare(fromString(v), fromString(version)) !== -1);\n\t}\n\n\tsupported<T extends GitFeatureOrPrefix>(feature: T): FilteredGitFeatures<T>[] | Promise<FilteredGitFeatures<T>[]> {\n\t\tfunction supportedCore(gitVersion: string): FilteredGitFeatures<T>[] {\n\t\t\treturn [...gitFeaturesByVersion]\n\t\t\t\t.filter(([f, v]) => f.startsWith(feature) && compare(fromString(gitVersion), v) !== -1)\n\t\t\t\t.map(([f]) => f as FilteredGitFeatures<T>);\n\t\t}\n\n\t\tif (this._gitLocation == null) {\n\t\t\treturn this.version().then(v => supportedCore(v));\n\t\t}\n\t\treturn supportedCore(this._gitLocation.version);\n\t}\n\n\tasync ensureSupports(feature: GitFeatures, prefix: string, suffix: string): Promise<void>;\n\tasync ensureSupports(feature: GitFeatures, message: GitFeatureUnsupportedMessage): Promise<void>;\n\tasync ensureSupports(\n\t\tfeature: GitFeatures,\n\t\tprefixOrMessage: string | GitFeatureUnsupportedMessage,\n\t\tsuffix?: string,\n\t): Promise<void> {\n\t\tconst version = gitFeaturesByVersion.get(feature);\n\t\tif (version == null) return;\n\n\t\tconst gitVersion = await this.version();\n\t\tif (compare(fromString(gitVersion), fromString(version)) !== -1) return;\n\n\t\tconst message =\n\t\t\ttypeof prefixOrMessage === 'function'\n\t\t\t\t? prefixOrMessage(version, gitVersion)\n\t\t\t\t: `${prefixOrMessage} requires a newer version of Git (>= ${version}) than is currently installed (${gitVersion}).${suffix}`;\n\t\tthrow new Error(message);\n\t}\n\n\tasync run(\n\t\toptions: ExitCodeOnlyGitCommandOptions,\n\t\t...args: readonly (string | undefined)[]\n\t): Promise<GitResult<unknown>>;\n\tasync run<T extends string | Buffer = string>(\n\t\toptions: GitRunOptions,\n\t\t...args: readonly (string | undefined)[]\n\t): Promise<GitResult<T>>;\n\tasync run<T extends string | Buffer = string>(\n\t\toptions: GitRunOptions,\n\t\t...args: readonly (string | undefined)[]\n\t): Promise<GitResult<T | unknown>> {\n\t\tif (this.options.isTrusted?.() === false) throw new WorkspaceUntrustedError();\n\n\t\tconst runArgs = args.filter(a => a != null);\n\n\t\t// `notify` announces once the run settles (success, failure or cancellation), which the bare\n\t\t// `return <promise>` paths below don't wait for; callers without it never take this branch.\n\t\tif (options.notify != null) {\n\t\t\tconst pending = await this.prepareNotify(options, runArgs);\n\t\t\ttry {\n\t\t\t\treturn await this.run<T>({ ...options, notify: undefined }, ...args);\n\t\t\t} finally {\n\t\t\t\tif (pending != null) {\n\t\t\t\t\tawait this.applyNotify(pending);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst gitCommand = `git ${runArgs.join(' ')}`;\n\n\t\t// If cache is provided, use it to cache the full result\n\t\tif (options.caching != null) {\n\t\t\tconst cachePath = options.caching.commonPath ?? options.cwd!;\n\t\t\t// Drop the cached (or in-flight) entry first so `getOrCreate` below always creates a fresh\n\t\t\t// entry with its own `AbortAggregate` — the underlying spawn can then never join an in-flight\n\t\t\t// run that started before this caller's own write.\n\t\t\tif (options.caching.force) {\n\t\t\t\toptions.caching.cache.delete(cachePath, gitCommand);\n\t\t\t}\n\n\t\t\treturn options.caching.cache.getOrCreate(\n\t\t\t\tcachePath,\n\t\t\t\tgitCommand,\n\t\t\t\tasync (cacheable, signal) => {\n\t\t\t\t\t// Bind the shared spawn to the aggregate `signal` (fires only when ALL current callers\n\t\t\t\t\t// abort), not this-caller's `options.cancellation` — otherwise a superseded caller's\n\t\t\t\t\t// abort would kill the shared command and reject concurrent riders that never cancelled.\n\t\t\t\t\tconst result = await this.runCore<T>(\n\t\t\t\t\t\t{ ...options, caching: undefined, cancellation: signal ?? options.cancellation },\n\t\t\t\t\t\trunArgs,\n\t\t\t\t\t\tgitCommand,\n\t\t\t\t\t);\n\t\t\t\t\t// Never cache a result that isn't a genuine command outcome. Under `errors: 'ignore'` a\n\t\t\t\t\t// cancelled/aborted run RESOLVES an empty result, which — left cached — would be served as a\n\t\t\t\t\t// real empty result for the full TTL (e.g. a valid merge-base read back as \"none\").\n\t\t\t\t\t// Invalidate on anything that isn't a clean exit, or whenever the aggregate signal aborted,\n\t\t\t\t\t// so the entry self-evicts instead of poisoning later callers.\n\t\t\t\t\t//\n\t\t\t\t\t// `status !== 'exited'` is what catches the case a bare `exitCode` check cannot. A swallowed\n\t\t\t\t\t// `GitWarnings` match used to report `exitCode: 0` UNCONDITIONALLY — the old code read it off\n\t\t\t\t\t// a `result` that is only ever assigned on the non-throwing path, so it was always the `?? 0`\n\t\t\t\t\t// fallback — which meant `exitCode !== 0` could never fire and every swallowed failure was\n\t\t\t\t\t// cached. A `warned` result now carries git's real code, so it's the status, not the code,\n\t\t\t\t\t// that has to do the work here. The `exitCode !== 0` half is kept as-is — a non-zero exit is\n\t\t\t\t\t// a real answer and arguably cacheable, but it isn't cached today and this isn't the change\n\t\t\t\t\t// to start.\n\t\t\t\t\tif (result.completion.status !== 'exited' || result.exitCode !== 0 || signal?.aborted) {\n\t\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t},\n\t\t\t\t// Forward this caller's cancellation so `getOrCreate` races each caller's own wait — an\n\t\t\t\t// aborting caller rejects only itself, leaving the shared work (and its riders) intact.\n\t\t\t\t{ ...options.caching.options, cancellation: options.cancellation },\n\t\t\t);\n\t\t}\n\n\t\treturn this.runCore<T>(options, runArgs, gitCommand);\n\t}\n\n\t/**\n\t * Works out, before a `notify`-flagged {@link run} spawns, what it announces once it settles — `undefined` unless\n\t * both `notify` and a {@link bindChangeNotifier bound} notifier are present, so an unflagged caller pays nothing.\n\t * A verb that moves only HEAD's branch reads HEAD here, since the run may move it.\n\t */\n\tprivate async prepareNotify(options: GitRunOptions, args: readonly string[]): Promise<PendingNotify | undefined> {\n\t\tconst notify = options.notify;\n\t\tif (notify == null || this._changeNotifier == null || options.cwd == null) return undefined;\n\n\t\t// The argv git sees, which `options.configs` (a `-c`, or even a `-C`) leads\n\t\tconst argv = options.configs?.length ? [...options.configs, ...args] : args;\n\t\tif (notify !== 'infer') {\n\t\t\t// The caller decided exactly what changed; still resolve WHERE it changed the same way `infer`\n\t\t\t// does, since the caller may have passed its own `-C` in the argv.\n\t\t\treturn { cwd: options.cwd, pathOverride: leadingCommand(argv).pathOverride, changes: notify };\n\t\t}\n\n\t\tlet command = this._classify(argv);\n\t\tif (command == null) return undefined; // read-only or object-store-only — nothing to announce\n\n\t\tif (command.worktreePaths != null && command.changes.includes('worktrees')) {\n\t\t\tcommand = await this.withoutIgnoredWorktrees(\n\t\t\t\tcommand,\n\t\t\t\tcommand.worktreePaths,\n\t\t\t\tthis.resolveNotifyPath(options.cwd, command.pathOverride),\n\t\t\t);\n\t\t\tif (command == null) return undefined;\n\t\t}\n\n\t\tconst headBefore =\n\t\t\tcommand.movesHeadBranch && this._headReader != null\n\t\t\t\t? await this.readHead(this.resolveNotifyPath(options.cwd, command.pathOverride))\n\t\t\t\t: undefined;\n\t\treturn { cwd: options.cwd, command: command, headBefore: headBefore };\n\t}\n\n\t/** Announces what {@link prepareNotify} worked out, once the run has settled */\n\tprivate async applyNotify(pending: PendingNotify): Promise<void> {\n\t\tif (!('command' in pending)) {\n\t\t\tthis._changeNotifier?.([this.resolveNotifyPath(pending.cwd, pending.pathOverride)], pending.changes);\n\t\t\treturn;\n\t\t}\n\n\t\tconst command = pending.command;\n\t\tconst ranIn = this.resolveNotifyPath(pending.cwd, command.pathOverride);\n\t\tlet changes = command.changes;\n\t\tlet sharedChanges = command.sharedChanges;\n\t\tconst refs = [...(command.refs ?? [])];\n\t\tif (command.movesHeadBranch && this._headReader != null) {\n\t\t\tconst moved = getMovedHead(pending.headBefore, await this.readHead(ranIn));\n\t\t\tif (moved === 'detached') {\n\t\t\t\t// A detached HEAD moving moves no branch\n\t\t\t\tchanges = changes.filter(c => c !== 'heads');\n\t\t\t\tsharedChanges = sharedChanges.filter(c => c !== 'heads');\n\t\t\t\t// Nothing else changed, and announcing `[]` would reset everything\n\t\t\t\tif (!changes.length) return;\n\t\t\t} else if (moved != null && changes.includes('heads') && !refs.includes(moved.branch)) {\n\t\t\t\trefs.push(moved.branch);\n\t\t\t}\n\t\t}\n\n\t\tconst notifier = this._changeNotifier;\n\t\tif (notifier == null) return;\n\n\t\tlet named: NamedRefs | undefined;\n\t\tif (refs.length) {\n\t\t\tnamed = command.configConfinedToRefs ? { refs: refs, configConfinedToRefs: true } : { refs: refs };\n\t\t}\n\n\t\t// A `-C`-scoped write also changes what the caller's own `cwd` sees when both share a `.git`: a branch,\n\t\t// tag or stash it wrote. The target may be a worktree the cache never registered, so its eviction can't be\n\t\t// trusted to reach `cwd`; announce the shared kinds there too, and only those. A write it can't classify\n\t\t// (`[]`) resets both, since what it shares is unknown.\n\t\tconst cwd = normalizePath(pending.cwd);\n\t\tif (command.pathOverride != null && cwd !== ranIn && (sharedChanges.length || !changes.length)) {\n\t\t\tif (sharedChanges.length === changes.length) {\n\t\t\t\tnotifier([ranIn, cwd], changes, undefined, named);\n\t\t\t} else {\n\t\t\t\tnotifier([ranIn], changes, [cwd], named);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tnotifier([ranIn], changes, undefined, named);\n\t}\n\n\t/**\n\t * `command` without its `worktrees` and `worktreeHead` changes when every worktree it acts on lies under a folder\n\t * whose worktrees are ignored, read before the run while the tree it runs in surely exists; `undefined` when nothing\n\t * else is left to announce, since announcing `[]` would reset everything. Git first matches an argument against the\n\t * trailing path components of every worktree, so a relative one may name a worktree outside those folders whatever\n\t * it resolves to, and keeps the change.\n\t */\n\tprivate async withoutIgnoredWorktrees(\n\t\tcommand: CommandChanges,\n\t\tworktreePaths: readonly string[],\n\t\tranIn: string,\n\t): Promise<CommandChanges | undefined> {\n\t\tconst reader = this._ignoredWorktreeRootsReader;\n\t\tif (reader == null || !worktreePaths.every(p => isAbsolute(p))) return command;\n\n\t\tlet roots: readonly string[] | undefined;\n\t\ttry {\n\t\t\troots = await reader(ranIn);\n\t\t} catch {}\n\t\tif (!roots?.length) return command;\n\n\t\t// Resolved as git resolves them, so a `..` segment can't lead a path that only starts under a folder out of it\n\t\tconst resolved = worktreePaths.map(p => normalizePath(resolvePath(ranIn, p)));\n\t\tif (!resolved.every(p => roots.some(root => isDescendant(p, root)))) return command;\n\n\t\tconst changes = command.changes.filter(c => c !== 'worktrees' && c !== 'worktreeHead');\n\t\tif (!changes.length) return undefined;\n\n\t\treturn {\n\t\t\t...command,\n\t\t\tchanges: changes,\n\t\t\tsharedChanges: command.sharedChanges.filter(c => c !== 'worktrees' && c !== 'worktreeHead'),\n\t\t};\n\t}\n\n\t/** HEAD of `path` through the {@link bindHeadReader bound} reader, or `undefined` when it can't be read */\n\tprivate async readHead(path: string): Promise<HeadState> {\n\t\ttry {\n\t\t\treturn await this._headReader?.(path);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate resolveNotifyPath(cwd: string, pathOverride: string | undefined): string {\n\t\treturn normalizePath(pathOverride != null ? resolvePath(cwd, pathOverride) : cwd);\n\t}\n\n\tprivate async runCore<T extends string | Buffer>(\n\t\toptions: GitRunOptions,\n\t\targs: string[],\n\t\tgitCommand: string,\n\t): Promise<GitResult<T | unknown>> {\n\t\tconst start = hrtime();\n\t\tconst startEpochMs = Date.now();\n\n\t\tgitCommand = `[${options.cwd}] ${gitCommand}`;\n\t\tconst {\n\t\t\tbeforeIndexLockRetry,\n\t\t\tcancellation,\n\t\t\tconfigs,\n\t\t\tcorrelationKey,\n\t\t\tonSpawn,\n\t\t\terrors: errorHandling,\n\t\t\tencoding,\n\t\t\texpectedExitCodes,\n\t\t\trunLocally: _,\n\t\t\tselfMaintenance,\n\t\t\tslownessCategory,\n\t\t\t...opts\n\t\t} = options;\n\n\t\t// A run's own timeout holds even when the default is disabled (0), so an unrequested background run stays capped\n\t\tconst runTimeout = opts.timeout ?? this.options.gitTimeout ?? 60000;\n\t\tconst runOpts: Mutable<RunOptions> = {\n\t\t\t...opts,\n\t\t\ttimeout: runTimeout === 0 ? undefined : runTimeout,\n\t\t\tencoding: (encoding ?? 'utf8') === 'utf8' ? 'utf8' : 'buffer',\n\t\t\tdecode: this.options.decode,\n\t\t\tenv: this.buildEnv(options.env),\n\t\t\tquiet: errorHandling === 'ignore',\n\t\t\tspawn: this.options.spawn,\n\t\t};\n\n\t\t// A run fed its own stdin or per-call env is never shared: the same argv can answer differently for\n\t\t// each (a temporary index through `GIT_INDEX_FILE`, config injected through `GIT_CONFIG_*`). Nor is one\n\t\t// carrying a retry hook, since the check it makes is that caller's own.\n\t\tconst unshared =\n\t\t\toptions?.stdin != null ||\n\t\t\t(options?.env != null && Object.keys(options.env).length > 0) ||\n\t\t\tbeforeIndexLockRetry != null;\n\t\tconst cacheKey = `${correlationKey !== undefined ? `${correlationKey}:` : ''}${\n\t\t\tunshared ? `${unsharedRunCounter.next()}:` : ''\n\t\t}${cancellation != null ? `${getAbortSignalId(cancellation)}:` : ''}${gitCommand}`;\n\n\t\t// When the subprocess actually started — `start` includes GitQueue wait, which is congestion rather\n\t\t// than anything the repository did. Stays undefined for a dedup rider or a command aborted while queued.\n\t\tlet execStart: ReturnType<typeof hrtime> | undefined;\n\t\t// What the caller's retry hook threw. It is the caller's own failure, so it must reach them as thrown\n\t\t// rather than be classified like a git failure below.\n\t\tlet hookFailure: { error: unknown } | undefined;\n\t\tlet waiting;\n\t\tlet promise: Promise<RunResult<string | Buffer>>;\n\t\tconst pending = this.pendingCommands.get(cacheKey);\n\t\tif (pending == null) {\n\t\t\twaiting = false;\n\n\t\t\t// Create a deferred promise and store it immediately to prevent duplicate commands\n\t\t\t// Note: the cancellation signal is part of the dedup key — calls with different AbortSignals are not deduplicated\n\t\t\tconst deferred = defer<RunResult<string | Buffer>>();\n\t\t\tpromise = deferred.promise;\n\t\t\tconst command: PendingCommand = {\n\t\t\t\tcwd: options.cwd,\n\t\t\t\tpromise: promise,\n\t\t\t\tspawned: false,\n\t\t\t\tspawnListeners: onSpawn != null ? [onSpawn] : [],\n\t\t\t};\n\t\t\tthis.pendingCommands.set(cacheKey, command);\n\n\t\t\t// A write to the index takes `index.lock` and fails at once if another process holds it, so these\n\t\t\t// runs queue behind one another per checkout and retry briefly when something outside still beats\n\t\t\t// them to it. A temporary index (`GIT_INDEX_FILE`) has a lock of its own, so it never joins the order.\n\t\t\tconst writesIndex = isIndexWriteCommand(args);\n\t\t\tconst checkoutKey =\n\t\t\t\twritesIndex && options.cwd != null && runOpts.env?.GIT_INDEX_FILE == null\n\t\t\t\t\t? this.resolveNotifyPath(options.cwd, leadingCommand(args).pathOverride)\n\t\t\t\t\t: undefined;\n\n\t\t\t// Fixes https://github.com/gitkraken/vscode-gitlens/issues/73 & https://github.com/gitkraken/vscode-gitlens/issues/161\n\t\t\t// See https://stackoverflow.com/questions/4144417/how-to-handle-asian-characters-in-file-names-in-git-on-os-x\n\t\t\targs.unshift('-c', 'core.quotepath=false', '-c', 'color.ui=false', ...(configs ?? emptyArray));\n\n\t\t\tif (process.platform === 'win32') {\n\t\t\t\targs.unshift('-c', 'core.longpaths=true');\n\t\t\t}\n\n\t\t\tif (cancellation != null) {\n\t\t\t\trunOpts.cancellation = cancellation;\n\t\t\t}\n\n\t\t\t// Determine command priority:\n\t\t\t// Priority resolution:\n\t\t\t// 1. Explicit priority from options (highest precedence)\n\t\t\t// 2. Inferred from command type (only downgrades expensive commands to Background)\n\t\t\tconst priority = options.priority ?? inferGitCommandPriority(args);\n\n\t\t\t// Execute through the queue (interactive/normal run immediately, background is throttled)\n\t\t\tconst gitPath = await this.path();\n\t\t\tconst spawnQueued = () =>\n\t\t\t\tthis._queue.run(\n\t\t\t\t\tpriority,\n\t\t\t\t\t() => {\n\t\t\t\t\t\texecStart = hrtime();\n\t\t\t\t\t\t// A lock retry spawns again, but the run has already started\n\t\t\t\t\t\tif (!command.spawned) {\n\t\t\t\t\t\t\tcommand.spawned = true;\n\t\t\t\t\t\t\tnotifySpawned(command.spawnListeners.splice(0));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn this._runSpawn<T>(gitPath, args, encoding ?? 'utf8', runOpts);\n\t\t\t\t\t},\n\t\t\t\t\tcancellation,\n\t\t\t\t);\n\t\t\t// The retry wraps the spawn itself, before any `errors` mode turns a failure into a result or a\n\t\t\t// throw, because only the raw `RunError` carries the stderr that says the lock was held. It re-queues\n\t\t\t// each attempt, so waiting between them doesn't hold a queue slot.\n\t\t\t// A config write likewise fails at once on a held `<file>.lock`. Reads never produce that failure, so\n\t\t\t// the retry costs them nothing, and one wrap covers both `errors` modes.\n\t\t\tconst beforeRetry =\n\t\t\t\tbeforeIndexLockRetry != null\n\t\t\t\t\t? async (lockError: Error) => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait beforeIndexLockRetry(lockError);\n\t\t\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t\t\t// The lock error thrown back only declines the retry, leaving the lock failure as the result\n\t\t\t\t\t\t\t\tif (ex !== lockError) {\n\t\t\t\t\t\t\t\t\thookFailure = { error: ex };\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthrow ex;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\t\t\tconst spawnWithRetry = writesIndex\n\t\t\t\t? () => retryWhileIndexLocked(spawnQueued, cancellation, beforeRetry)\n\t\t\t\t: isConfigCommand(args)\n\t\t\t\t\t? () => retryWhileConfigLocked(spawnQueued, cancellation)\n\t\t\t\t\t: spawnQueued;\n\t\t\tvoid (\n\t\t\t\tcheckoutKey != null\n\t\t\t\t\t? this._indexWrites.run(checkoutKey, cancellation, spawnWithRetry)\n\t\t\t\t\t: spawnWithRetry()\n\t\t\t)\n\t\t\t\t.then(deferred.fulfill, (e: unknown) => deferred.cancel(e instanceof Error ? e : new Error(String(e))))\n\t\t\t\t.finally(() => {\n\t\t\t\t\t// A clear may have dropped this run and a later identical call registered its own under the key\n\t\t\t\t\tif (this.pendingCommands.get(cacheKey)?.promise === deferred.promise) {\n\t\t\t\t\t\tthis.pendingCommands.delete(cacheKey);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(() => {});\n\t\t} else {\n\t\t\twaiting = true;\n\t\t\tpromise = pending.promise;\n\t\t\tif (onSpawn != null) {\n\t\t\t\tif (pending.spawned) {\n\t\t\t\t\tnotifySpawned([onSpawn]);\n\t\t\t\t} else {\n\t\t\t\t\tpending.spawnListeners.push(onSpawn);\n\t\t\t\t}\n\t\t\t}\n\t\t\tLogger.trace(`${formatLoggableScopeBlock('GIT')} ${gitCommand} \\u00b7 awaiting existing call...`);\n\t\t}\n\n\t\t// Placed HERE, not at the top of the method — every path from this point flows through the\n\t\t// `finally` below, so the active count can't leak if setup (e.g. locating git) throws.\n\t\tthis.beginActiveCommand();\n\n\t\tlet exception: Error | undefined;\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await promise;\n\t\t\t// A normal `runSpawn` only resolves on a clean exit — `code !== 0 || signal` rejects — but the\n\t\t\t// `exitCodeOnly` overload resolves unconditionally, INCLUDING for a signalled run (no code, partial\n\t\t\t// or absent stdout). Coercing that to `0` would report a killed command as a clean success, so\n\t\t\t// classify it as the failure it is.\n\t\t\tif (result.exitCode == null) {\n\t\t\t\t// SIGTERM groups with cancellations here exactly as it does on the reject path — `failed`/`signal`\n\t\t\t\t// is for every OTHER signal. Only `exitCodeOnly` reaches this: a native spawn `timeout` fires\n\t\t\t\t// `close(null, 'SIGTERM')` with no `error` event, so it resolves instead of rejecting (a caller\n\t\t\t\t// abort never does — `'error'` rejects first). Throwing hands it to the catch below, which owns\n\t\t\t\t// the ABORTED log and the `onAborted` hook — neither of which a branch here would fire.\n\t\t\t\tif (result.signal === 'SIGTERM') {\n\t\t\t\t\tthrow new CancelledRunError(\n\t\t\t\t\t\tgitCommand,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tresult.signal,\n\t\t\t\t\t\tresult.killed ? 'timeout' : 'unknown',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tstdout: result.stdout,\n\t\t\t\t\tstderr: result.stderr,\n\t\t\t\t\tcompletion: {\n\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t\treason: result.signal != null ? 'signal' : 'unstarted',\n\t\t\t\t\t\terror: new Error(\n\t\t\t\t\t\t\t`Command terminated without an exit code${result.signal != null ? ` (${result.signal})` : ''}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tstdout: result.stdout,\n\t\t\t\tstderr: result.stderr,\n\t\t\t\texitCode: result.exitCode,\n\t\t\t\tcompletion: { status: 'exited', code: result.exitCode },\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tif (hookFailure != null) {\n\t\t\t\texception =\n\t\t\t\t\thookFailure.error instanceof Error ? hookFailure.error : new Error(String(hookFailure.error));\n\t\t\t\tif (typeof hookFailure.error === 'object' && hookFailure.error != null) {\n\t\t\t\t\trunHookFailures.add(hookFailure.error);\n\t\t\t\t}\n\n\t\t\t\tthrow hookFailure.error;\n\t\t\t}\n\n\t\t\tif (expectedExitCodes?.length && ex instanceof RunError && !(ex instanceof CancelledRunError)) {\n\t\t\t\tconst code = toExitCode(ex.code);\n\t\t\t\tif (code != null && expectedExitCodes.includes(code)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstdout: ex.stdout,\n\t\t\t\t\t\tstderr: ex.stderr,\n\t\t\t\t\t\texitCode: code,\n\t\t\t\t\t\tcompletion: { status: 'exited', code: code },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet cancellationReason: GitRunCancellation = 'unknown';\n\t\t\tif (ex instanceof CancelledRunError) {\n\t\t\t\tconst duration = getDurationMilliseconds(start);\n\t\t\t\tconst timeout = runOpts.timeout ?? 0;\n\t\t\t\tcancellationReason =\n\t\t\t\t\tex.reason !== 'unknown' ? ex.reason : cancellation?.aborted ? 'aborted' : 'unknown';\n\t\t\t\tconst reason = cancellationReason === 'aborted' ? 'cancellation' : cancellationReason;\n\n\t\t\t\t// A stalled event loop can leave a command looking timed out when it merely never got its exit\n\t\t\t\t// event delivered in time \\u2014 surface the same signal here so it isn't misread as a real timeout.\n\t\t\t\tconst loopDelayAnnotation = this.formatEventLoopDelayAnnotation(startEpochMs);\n\t\t\t\tconst loopDelayText = loopDelayAnnotation != null ? ` \\u00b7 ${loopDelayAnnotation}` : '';\n\n\t\t\t\tLogger.warn(\n\t\t\t\t\t`${formatLoggableScopeBlock('GIT')} ${gitCommand} \\u00b7 ABORTED after ${duration}ms (${reason})${loopDelayText}`,\n\t\t\t\t);\n\t\t\t\tthis.options.hooks?.onAborted?.({\n\t\t\t\t\toperation: gitCommand,\n\t\t\t\t\treason: reason,\n\t\t\t\t\tduration: duration,\n\t\t\t\t\ttimeout: timeout,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (errorHandling === 'ignore') {\n\t\t\t\tif (ex instanceof RunError) {\n\t\t\t\t\tconst code = toExitCode(ex.code);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstdout: ex.stdout,\n\t\t\t\t\t\tstderr: ex.stderr,\n\t\t\t\t\t\t...(code != null ? { exitCode: code } : {}),\n\t\t\t\t\t\tcompletion:\n\t\t\t\t\t\t\tex instanceof CancelledRunError\n\t\t\t\t\t\t\t\t? { status: 'cancelled', reason: cancellationReason, error: ex }\n\t\t\t\t\t\t\t\t: code != null\n\t\t\t\t\t\t\t\t\t? { status: 'exited', code: code }\n\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t\t\t\t\t\t\t// A signal means it ran and was killed (partial `stdout` may exist);\n\t\t\t\t\t\t\t\t\t\t\t// no signal and no numeric code means it never got that far.\n\t\t\t\t\t\t\t\t\t\t\treason: ex.signal != null ? 'signal' : 'unstarted',\n\t\t\t\t\t\t\t\t\t\t\terror: ex,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// No cancellation branch here: `CancelledRunError extends RunError`, so reaching this at all\n\t\t\t\t// proves `ex` is neither.\n\t\t\t\treturn {\n\t\t\t\t\tstdout: '',\n\t\t\t\t\tstderr: undefined,\n\t\t\t\t\tcompletion: {\n\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t\t// No `RunError` means no process was ever spawned — a queue rejection or a\n\t\t\t\t\t\t// failure before `spawn` returned. (Not an untrusted workspace: `run` refuses\n\t\t\t\t\t\t// those up front, so they never reach this catch.)\n\t\t\t\t\t\treason: 'unstarted',\n\t\t\t\t\t\terror: ex instanceof Error ? ex : new Error(String(ex)),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// The queue refuses an already-aborted signal, or drops a command aborted while it waited, by\n\t\t\t// rejecting with the signal's own reason; that never reached a spawn, so it isn't a `RunError`,\n\t\t\t// and wrapping it as a `GitError` would make a cancellation read as the command failing.\n\t\t\tif (ex instanceof CancelledRunError) {\n\t\t\t\texception = new CancellationError(ex, cancellationReason);\n\t\t\t} else if (!(ex instanceof RunError) && cancellation?.aborted) {\n\t\t\t\texception = new CancellationError(ex instanceof Error ? ex : undefined, 'aborted');\n\t\t\t} else {\n\t\t\t\texception = new GitError(ex);\n\t\t\t}\n\t\t\tif (errorHandling === 'throw') throw exception;\n\n\t\t\t// Rethrows unless the message matches a `GitWarnings` pattern, in which case it logs and returns the\n\t\t\t// key that matched. Capture the error first — `exception` is cleared to keep it out of the `finally`\n\t\t\t// log, but the result still needs to carry it.\n\t\t\tconst swallowed = exception;\n\t\t\tconst warning = defaultExceptionHandler(exception, options.cwd, start);\n\t\t\texception = undefined;\n\t\t\t// The command did NOT produce this empty stdout — a warning was swallowed. Say so, or the caller\n\t\t\t// can't tell a genuinely empty answer (`noCommits`) from a read that never happened\n\t\t\t// (`notARepository`).\n\t\t\t//\n\t\t\t// The process DID exit though (a warning is only ever swallowed for a non-zero exit), so report the\n\t\t\t// code.\n\t\t\tconst code = toExitCode(swallowed instanceof GitError ? swallowed.exitCode : undefined);\n\n\t\t\t// No `stderr`: it belongs to the error here. The top-level field is the channel for runs that\n\t\t\t// completed WITHOUT one (`exited` carries no error, so a successful command's stderr has nowhere\n\t\t\t// else to go) — a swallowed warning always has a `GitError`, and it carries the stderr. Reading\n\t\t\t// `result?.stderr` would be dead anyway: `result` is only assigned on the non-throwing path.\n\t\t\treturn {\n\t\t\t\tstdout: '',\n\t\t\t\t...(code != null ? { exitCode: code } : {}),\n\t\t\t\tcompletion: { status: 'warned', warning: warning, error: swallowed },\n\t\t\t};\n\t\t} finally {\n\t\t\tthis.logGitCommandComplete(\n\t\t\t\tgitCommand,\n\t\t\t\texception,\n\t\t\t\tgetDurationMilliseconds(start),\n\t\t\t\t// 0 when the subprocess never started — there is no execution time to attribute. Also 0 for\n\t\t\t\t// GitLens's own maintenance work, which is slow by design and must not read as repo slowness.\n\t\t\t\texecStart == null || selfMaintenance ? 0 : getDurationMilliseconds(execStart),\n\t\t\t\twaiting,\n\t\t\t\toptions.cwd,\n\t\t\t\targs,\n\t\t\t\tslownessCategory,\n\t\t\t\tstartEpochMs,\n\t\t\t);\n\t\t\tthis.endActiveCommand();\n\t\t}\n\t}\n\n\tasync *stream(options: GitSpawnOptions, ...args: readonly (string | undefined)[]): AsyncGenerator<string> {\n\t\tif (this.options.isTrusted?.() === false) throw new WorkspaceUntrustedError();\n\n\t\tconst start = hrtime();\n\t\tconst startEpochMs = Date.now();\n\t\tconst streamId = uniqueCounterForStream.next();\n\n\t\tconst { configs, stdin, stdinEncoding, cancellation, encoding, slownessCategory, cwd, timeout } = options;\n\t\tconst runArgs = args.filter(a => a != null);\n\n\t\tconst spawnOpts: ProcessSpawnOptions = {\n\t\t\t// Unless provided, ignore stdin and leave default streams for stdout and stderr\n\t\t\tstdio: [stdin ? 'pipe' : 'ignore', null, null],\n\t\t\tcwd: cwd,\n\t\t\tenv: this.buildEnv(options.env),\n\t\t\t// 0 disables it, which the spawner contract spells as absent\n\t\t\ttimeout: timeout === 0 ? undefined : timeout,\n\t\t\tsignal: cancellation,\n\t\t};\n\n\t\tconst gitCommand = `(spawn) [${cwd}] git ${runArgs.join(' ')}`;\n\n\t\t// Fixes https://github.com/gitkraken/vscode-gitlens/issues/73 & https://github.com/gitkraken/vscode-gitlens/issues/161\n\t\t// See https://stackoverflow.com/questions/4144417/how-to-handle-asian-characters-in-file-names-in-git-on-os-x\n\t\trunArgs.unshift('-c', 'core.quotepath=false', '-c', 'color.ui=false', ...(configs ?? emptyArray));\n\n\t\tif (process.platform === 'win32') {\n\t\t\trunArgs.unshift('-c', 'core.longpaths=true');\n\t\t}\n\n\t\tconst command = await this.path();\n\t\tconst proc = (this.options.spawn ?? spawn)(command, runArgs, spawnOpts);\n\n\t\tif (stdin) {\n\t\t\tendStdin(proc.stdin, stdin, stdinEncoding);\n\t\t}\n\n\t\tlet exception: Error | undefined;\n\n\t\tconst promise = new Promise<void>((resolve, reject) => {\n\t\t\tconst stderrChunks: string[] = [];\n\t\t\tif (proc.stderr) {\n\t\t\t\tproc.stderr?.setEncoding('utf8');\n\t\t\t\tproc.stderr.on('data', chunk => stderrChunks.push(chunk));\n\t\t\t}\n\n\t\t\tproc.once('error', ex => {\n\t\t\t\tif (ex?.name === 'AbortError') return;\n\n\t\t\t\texception = new GitError(ex);\n\t\t\t});\n\t\t\tproc.once('close', (code, signal) => {\n\t\t\t\tif (code === 0) {\n\t\t\t\t\tresolve();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (signal === 'SIGTERM') {\n\t\t\t\t\t// If the caller aborted, just resolve\n\t\t\t\t\tif (cancellation?.aborted) {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t} else {\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew CancelledRunError(\n\t\t\t\t\t\t\t\tproc.spawnargs.join(' '),\n\t\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t\tcode ?? undefined,\n\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t\tproc.killed ? 'timeout' : 'unknown',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If the caller didn't read the complete stream, just resolve\n\t\t\t\tif (\n\t\t\t\t\tsignal === 'SIGPIPE' ||\n\t\t\t\t\tcode === 141 /* SIGPIPE */ ||\n\t\t\t\t\t(code === 128 && stderrChunks.some(c => c.includes('Connection reset by peer')))\n\t\t\t\t) {\n\t\t\t\t\tresolve();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst stderr = stderrChunks.join('').trim();\n\t\t\t\treject(\n\t\t\t\t\tnew GitError(\n\t\t\t\t\t\tnew RunError(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmessage: `Error (${code}): ${stderr || 'Unknown'}`,\n\t\t\t\t\t\t\t\tcmd: proc.spawnargs.join(' '),\n\t\t\t\t\t\t\t\tkilled: proc.killed,\n\t\t\t\t\t\t\t\tcode: proc.exitCode,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'',\n\t\t\t\t\t\t\tstderr,\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t});\n\t\t});\n\n\t\tlet cleanedUp = false;\n\t\tconst cleanup = () => {\n\t\t\tif (cleanedUp) return;\n\n\t\t\tcleanedUp = true;\n\n\t\t\ttry {\n\t\t\t\tproc.removeAllListeners();\n\t\t\t} catch {}\n\t\t\t// Streaming spawns directly, with no GitQueue wait to exclude. It isn't pure subprocess time\n\t\t\t// either — the generator applies backpressure, so a slow consumer stalls the pipe and inflates\n\t\t\t// this — but there's no separate signal to measure here.\n\t\t\tconst duration = getDurationMilliseconds(start);\n\t\t\tthis.logGitCommandComplete(\n\t\t\t\tgitCommand,\n\t\t\t\texception,\n\t\t\t\tduration,\n\t\t\t\tduration,\n\t\t\t\tfalse,\n\t\t\t\tcwd,\n\t\t\t\trunArgs,\n\t\t\t\tslownessCategory,\n\t\t\t\tstartEpochMs,\n\t\t\t\tstreamId,\n\t\t\t);\n\t\t\tthis.endActiveCommand();\n\t\t};\n\n\t\t// Placed HERE, not at the top of the method — every path from this point reaches `cleanup()`\n\t\t// (the `finally` below, or the generator-close return), so the active count can't leak if\n\t\t// setup (e.g. locating git) throws.\n\t\tthis.beginActiveCommand();\n\n\t\ttry {\n\t\t\tthis.logGitCommandStart(gitCommand, streamId);\n\n\t\t\ttry {\n\t\t\t\t// Only a host spawner can leave it out; reading no output as empty would pass for a clean answer\n\t\t\t\tif (proc.stdout == null) throw new Error(`'${command}' was spawned without a stdout pipe`);\n\n\t\t\t\tconst enc = encoding ?? 'utf8';\n\t\t\t\tif (enc === 'utf8' || enc === 'binary' || enc === 'buffer') {\n\t\t\t\t\tproc.stdout.setEncoding(enc === 'buffer' ? 'utf8' : enc);\n\t\t\t\t\tfor await (const chunk of proc.stdout) {\n\t\t\t\t\t\tyield chunk;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Non-UTF-8 encoding: collect raw buffers and decode at the end.\n\t\t\t\t\t// Streaming decode is unsafe because chunk boundaries can split\n\t\t\t\t\t// multi-byte sequences in the source encoding.\n\t\t\t\t\tconst decode = this.options.decode;\n\t\t\t\t\tif (decode == null) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Non-UTF-8 encoding '${enc}' requested for stream but no decode function configured`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst buffers: Buffer[] = [];\n\t\t\t\t\tfor await (const chunk of proc.stdout) {\n\t\t\t\t\t\tbuffers.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n\t\t\t\t\t}\n\t\t\t\t\tyield await decode(Buffer.concat(buffers), { encoding: enc });\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// This await MUST be in this inner finally block to ensure the child process close event completes\n\t\t\t\t// before we call removeAllListeners() in the outer finally. When consumers break early from the\n\t\t\t\t// async generator (e.g., reading only the first chunk), the git process receives SIGPIPE and triggers\n\t\t\t\t// the close handler asynchronously. Without awaiting here, removeAllListeners() would execute before\n\t\t\t\t// the close handler finishes, causing a race condition and potential resource leaks.\n\t\t\t\tawait promise;\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\texception = ex;\n\t\t\tthrow ex;\n\t\t} finally {\n\t\t\tcleanup();\n\t\t}\n\n\t\t// Ensure cleanup happens immediately when the generator is explicitly closed (e.g., via break or return)\n\t\t// This is called by JavaScript when the generator is abandoned, ensuring logGitCommand is called\n\t\t// synchronously rather than waiting for garbage collection.\n\t\t// oxlint-disable-next-line typescript/no-meaningless-void-operator\n\t\treturn void cleanup();\n\t}\n\n\t/**\n\t * Resolves the git dir (and common dir, for a linked worktree) of `cwd`.\n\t *\n\t * Resolves `undefined` when `cwd` is not in a repository: git reported so, or `cwd` doesn't exist. Any\n\t * other failure (unsafe ownership, a timeout or cancellation, a missing git binary) rejects.\n\t */\n\tasync rev_parse__git_dir(cwd: string): Promise<{ path: string; commonPath?: string } | undefined> {\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await this.run({ cwd: cwd, errors: 'throw' }, 'rev-parse', '--git-dir', '--git-common-dir');\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof GitError && GitWarnings.notARepository.test(ex.stderr ?? '')) return undefined;\n\t\t\t// A missing `cwd` fails the spawn itself (ENOENT) before git can say anything about it\n\t\t\tif (!(await fsExists(cwd))) return undefined;\n\t\t\tthrow ex;\n\t\t}\n\t\tif (!result.stdout) return undefined;\n\n\t\t// Keep trailing spaces which are part of the directory name\n\t\tlet [dotGitPath, commonDotGitPath] = result.stdout.split('\\n').map(r => r.trimStart());\n\n\t\t// Make sure to normalize: https://github.com/git-for-windows/git/issues/2478\n\n\t\tif (!isAbsolute(dotGitPath)) {\n\t\t\tdotGitPath = joinPaths(cwd, dotGitPath);\n\t\t}\n\t\tdotGitPath = normalizePath(dotGitPath);\n\n\t\tif (commonDotGitPath) {\n\t\t\tif (!isAbsolute(commonDotGitPath)) {\n\t\t\t\tcommonDotGitPath = joinPaths(cwd, commonDotGitPath);\n\t\t\t}\n\t\t\tcommonDotGitPath = normalizePath(commonDotGitPath);\n\n\t\t\treturn { path: dotGitPath, commonPath: commonDotGitPath !== dotGitPath ? commonDotGitPath : undefined };\n\t\t}\n\n\t\treturn { path: dotGitPath };\n\t}\n\n\tasync rev_parse__show_toplevel(cwd: string): Promise<[safe: true, repoPath: string] | [safe: false] | []> {\n\t\tlet result;\n\n\t\tif (this.options.isTrusted?.() === false) {\n\t\t\t// Check if the folder is a bare clone: if it has a file named HEAD && `rev-parse --show-cdup` is empty\n\t\t\tif (await fsExists(joinPaths(cwd, 'HEAD'))) {\n\t\t\t\ttry {\n\t\t\t\t\tresult = await this.run(\n\t\t\t\t\t\t{ cwd: cwd, errors: 'throw', configs: ['-C', cwd] },\n\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t'--show-cdup',\n\t\t\t\t\t);\n\t\t\t\t\tif (!result.stdout.trim()) {\n\t\t\t\t\t\tLogger.warn(`Skipping (untrusted workspace); bare clone repository detected in '${cwd}'`);\n\t\t\t\t\t\treturn emptyArray as [];\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// If this throws, we should be good to open the repo (e.g. HEAD doesn't exist)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tresult = await this.run({ cwd: cwd, errors: 'throw' }, 'rev-parse', '--show-toplevel');\n\t\t\t// Make sure to normalize: https://github.com/git-for-windows/git/issues/2478\n\t\t\t// Keep trailing spaces which are part of the directory name\n\t\t\treturn !result.stdout\n\t\t\t\t? (emptyArray as [])\n\t\t\t\t: [true, normalizePath(result.stdout.trimStart().replace(trailingNewlineRegex, ''))];\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof WorkspaceUntrustedError) return emptyArray as [];\n\t\t\tif (!(ex instanceof GitError)) throw ex;\n\n\t\t\tconst unsafeMatch = GitErrors.unsafeRepository.exec(ex.stderr ?? '');\n\t\t\tif (unsafeMatch != null) {\n\t\t\t\tLogger.warn(\n\t\t\t\t\t`Skipping; unsafe repository detected in '${unsafeMatch[1] || unsafeMatch[2]}'; run '${\n\t\t\t\t\t\tunsafeMatch[3]\n\t\t\t\t\t}' to allow it`,\n\t\t\t\t);\n\t\t\t\treturn [false];\n\t\t\t}\n\n\t\t\tconst inDotGit = GitWarnings.mustRunInWorkTree.test(ex.stderr ?? '');\n\t\t\t// Check if we are in a bare clone\n\t\t\tif (inDotGit && this.options.isTrusted?.() !== false) {\n\t\t\t\tresult = await this.run({ cwd: cwd, errors: 'ignore' }, 'rev-parse', '--is-bare-repository');\n\t\t\t\tif (result.stdout.trim() === 'true') {\n\t\t\t\t\tconst result = await this.rev_parse__git_dir(cwd).catch(() => undefined);\n\t\t\t\t\tconst repoPath = result?.commonPath ?? result?.path;\n\t\t\t\t\tif (repoPath?.length) return [true, repoPath];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (inDotGit || (ex.original as NodeJS.ErrnoException)?.code === 'ENOENT') {\n\t\t\t\t// If the `cwd` doesn't exist, walk backward to see if any parent folder exists\n\t\t\t\tlet exists = inDotGit ? false : await fsExists(cwd);\n\t\t\t\tif (!exists) {\n\t\t\t\t\tdo {\n\t\t\t\t\t\tconst parent = dirname(cwd);\n\t\t\t\t\t\tif (parent === cwd || parent.length === 0) return emptyArray as [];\n\n\t\t\t\t\t\tcwd = parent;\n\t\t\t\t\t\texists = await fsExists(cwd);\n\t\t\t\t\t} while (!exists);\n\n\t\t\t\t\treturn this.rev_parse__show_toplevel(cwd);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn emptyArray as [];\n\t\t}\n\t}\n\n\tprivate logGitCommandStart(command: string, id: number): void {\n\t\tLogger.info(`${formatLoggableScopeBlock(`GIT:\\u2192${id}`)} ${command} \\u00b7 starting...`);\n\t\tthis.options.logger?.info(`${formatLoggableScopeBlock(`\\u2192${id}`, '')} ${command} \\u2022 starting...`);\n\t}\n\n\tprivate logGitCommandComplete(\n\t\tcommand: string,\n\t\tex: Error | undefined,\n\t\tduration: number,\n\t\t/** Subprocess-only duration (excludes GitQueue wait); 0 when it never ran. */\n\t\texecDuration: number,\n\t\twaiting: boolean,\n\t\tcwd: string | undefined,\n\t\targs: readonly (string | undefined)[] | undefined,\n\t\tslownessCategory: GitHealthSlownessCategory | undefined,\n\t\tstartEpochMs: number,\n\t\tid?: number,\n\t): void {\n\t\tconst slow = duration > slowCallWarningThreshold;\n\n\t\tconst annotations: string[] = [];\n\t\tif (slow) {\n\t\t\tannotations.push('slow');\n\t\t}\n\n\t\tif (waiting) {\n\t\t\tannotations.push('waiting');\n\t\t} else if (execDuration > 0) {\n\t\t\t// Dedup riders (`waiting`) and never-started commands (`execDuration === 0`) have no queue\n\t\t\t// wait of their own to report.\n\t\t\tconst queued = duration - execDuration;\n\t\t\tif (queued >= queueWaitAnnotationThreshold) {\n\t\t\t\tannotations.push(`queued ${queued}ms`);\n\t\t\t}\n\t\t}\n\n\t\t// `hrtime` spans don't correlate with the monitor's wall-clock ring, so the lookup needs the\n\t\t// command's own start time — only worth measuring once the command is already slow. Whole-call\n\t\t// window on purpose: the annotation explains the TOTAL duration this log line reports.\n\t\tif (slow) {\n\t\t\tconst loopDelayAnnotation = this.formatEventLoopDelayAnnotation(startEpochMs);\n\t\t\tif (loopDelayAnnotation != null) {\n\t\t\t\tannotations.push(loopDelayAnnotation);\n\t\t\t}\n\t\t}\n\n\t\tconst status = annotations.length > 0 ? ` (${annotations.join(', ')})` : '';\n\n\t\t// The health signal is gated on the SUBPROCESS time, not the total: time spent queued behind other\n\t\t// git work is congestion, not repository slowness, and counting it would let a busy queue (including\n\t\t// our own background maintenance holding slots) manufacture the evidence that recommends more\n\t\t// maintenance. Logging keeps the total — the wait is exactly what you want to see when diagnosing.\n\t\t//\n\t\t// A deduplicated rider (`waiting`) shares the executed command's duration, so counting it too\n\t\t// would double-count a single slow subprocess — fire only for the command that actually ran.\n\t\t// Guarded: this runs inside the command's `finally`, so a hook throw would otherwise replace\n\t\t// the command's real result/error for the caller.\n\t\tif (execDuration > slowCallWarningThreshold && !waiting) {\n\t\t\t// Scoped to the SUBPROCESS window, matching the hook's `duration`: `duration - execDuration`\n\t\t\t// is the queue wait, and a stall while queued is congestion, not the command's own signal\n\t\t\t// (same reasoning as the `execDuration` gate above). The subprocess ends at log time, so it\n\t\t\t// started `duration - execDuration` after the call did.\n\t\t\tconst execEventLoopDelay = this._eventLoopMonitor.maxDelaySince(startEpochMs + (duration - execDuration));\n\t\t\ttry {\n\t\t\t\tthis.options.hooks?.onSlowCommand?.({\n\t\t\t\t\toperation: args != null ? getPrimaryGitCommand(args) : undefined,\n\t\t\t\t\tcwd: cwd,\n\t\t\t\t\tduration: execDuration,\n\t\t\t\t\teventLoopDelay: execEventLoopDelay,\n\t\t\t\t\tslownessCategory: slownessCategory,\n\t\t\t\t});\n\t\t\t} catch {}\n\t\t}\n\n\t\tif (ex != null) {\n\t\t\tLogger.error(\n\t\t\t\tundefined,\n\t\t\t\t`${formatLoggableScopeBlock(id ? `GIT:\\u2190${id}` : 'GIT')} ${command} \\u00b7 ${\n\t\t\t\t\tisCancellationError(ex)\n\t\t\t\t\t\t? 'cancelled'\n\t\t\t\t\t\t: (ex.message || String(ex) || '')\n\t\t\t\t\t\t\t\t.trim()\n\t\t\t\t\t\t\t\t.replace(/fatal:\\s*/g, '')\n\t\t\t\t\t\t\t\t.replace(/\\r?\\n|\\r/g, ' \\u00b7 ')\n\t\t\t\t} [${duration}ms]${status}`,\n\t\t\t);\n\t\t} else if (slow) {\n\t\t\tLogger.warn(\n\t\t\t\t`${formatLoggableScopeBlock(id ? `GIT:\\u2190${id}` : 'GIT', `*${duration}ms`)} ${command} [*${duration}ms]${status}`,\n\t\t\t);\n\t\t} else {\n\t\t\tLogger.info(\n\t\t\t\t`${formatLoggableScopeBlock(id ? `GIT:\\u2190${id}` : 'GIT', `${duration}ms`)} ${command} [${duration}ms]${status}`,\n\t\t\t);\n\t\t}\n\n\t\tconst logMessage = `${formatLoggableScopeBlock(\n\t\t\t`${id ? `\\u2190${id}` : ''}${slow ? '*' : ''}`,\n\t\t\t`${duration}ms`,\n\t\t)} ${command}${status}`;\n\t\tif (ex != null) {\n\t\t\tthis.options.logger?.error(`${logMessage} \\u2022 FAILED\\n${String(ex)}`);\n\t\t} else {\n\t\t\tthis.options.logger?.info(`${logMessage} \\u2022 completed`);\n\t\t}\n\t}\n}\n\n/**\n * Swallows an error whose message matches a known-benign {@link GitWarnings} pattern, returning WHICH one\n * matched so the caller can record it — the distinction matters, since `noCommits` is a real answer while\n * `notARepository` is a failed read. Rethrows anything else.\n */\nexport function defaultExceptionHandler(\n\tex: Error,\n\tcwd: string | undefined,\n\tstart?: [number, number],\n): GitWarningKey | undefined {\n\tif (isCancellationError(ex)) throw ex;\n\n\tconst msg = ex.message || ex.toString();\n\tif (msg) {\n\t\tconst warning = getGitWarning(ex);\n\t\tif (warning != null) {\n\t\t\tconst duration = start !== undefined ? ` [${getDurationMilliseconds(start)}ms]` : '';\n\t\t\tLogger.warn(\n\t\t\t\t`[${cwd}] Git ${msg\n\t\t\t\t\t.trim()\n\t\t\t\t\t.replace(/fatal:\\s*/g, '')\n\t\t\t\t\t.replace(/\\r?\\n|\\r/g, ' \\u00b7 ')}${duration}`,\n\t\t\t);\n\t\t\treturn warning;\n\t\t}\n\n\t\tconst match = GitErrors.badRevision.exec(msg);\n\t\tif (match != null) {\n\t\t\tconst [, ref] = match;\n\n\t\t\t// Since looking up a ref with ^3 (e.g. looking for untracked files in a stash) can error on some versions of git just ignore it\n\t\t\t// Swallowed, but it matched no `GitWarnings` entry — `undefined` records \"unclassified\", which\n\t\t\t// callers must treat as \"not a real answer\" exactly like any warning they don't whitelist.\n\t\t\tif (ref?.endsWith('^3')) return undefined;\n\t\t}\n\t}\n\n\tthrow ex;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"git.js","names":["isAbsolute","resolvePath","dirname"],"sources":["../../../../git-cli/src/exec/git.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport { resolve as resolvePath } from 'path';\nimport * as process from 'process';\nimport type {\n\tBranchErrorReason,\n\tCheckoutErrorReason,\n\tCherryPickErrorReason,\n\tCommitErrorReason,\n\tFetchErrorReason,\n\tGitCommandError,\n\tGitSearchErrorReason,\n\tGitWarningKey,\n\tMergeErrorReason,\n\tPausedOperationAbortErrorReason,\n\tPausedOperationContinueErrorReason,\n\tPullErrorReason,\n\tPushErrorReason,\n\tRebaseErrorReason,\n\tReferenceUpdateErrorReason,\n\tResetErrorReason,\n\tRevertErrorReason,\n\tShowErrorReason,\n\tSigningErrorReason,\n\tStashApplyErrorReason,\n\tStashPushErrorReason,\n\tTagErrorReason,\n\tWorktreeCreateErrorReason,\n\tWorktreeDeleteErrorReason,\n} from '@gitlens/git/errors.js';\nimport { getGitWarning, GitWarnings, WorkspaceUntrustedError } from '@gitlens/git/errors.js';\nimport type { GitHealthSlownessCategory } from '@gitlens/git/gitHealth.js';\nimport type { RepositoryChange } from '@gitlens/git/models/repository.js';\nimport type { SigningFormat } from '@gitlens/git/models/signature.js';\nimport type { GitRunCancellation } from '@gitlens/git/run.types.js';\nimport { CancellationError, getAbortSignalId, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { getScopedCounter } from '@gitlens/utils/counter.js';\nimport { getDurationMilliseconds, hrtime } from '@gitlens/utils/hrtime.js';\nimport { chunkByStringLength } from '@gitlens/utils/iterable.js';\nimport type { LogChannel } from '@gitlens/utils/logger.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport { formatLoggableScopeBlock } from '@gitlens/utils/logger.scoped.js';\nimport { arePathsEqual, dirname, isAbsolute, isDescendant, joinPaths, normalizePath } from '@gitlens/utils/path.js';\nimport { defer } from '@gitlens/utils/promise.js';\nimport type { Mutable } from '@gitlens/utils/types.js';\nimport { compare, fromString } from '@gitlens/utils/version.js';\nimport type { CommandChanges } from './commandClassifier.js';\nimport { getChangesForCommand, leadingCommand } from './commandClassifier.js';\nimport { EventLoopMonitor } from './eventLoopMonitor.js';\nimport { CancelledRunError, RunError } from './exec.errors.js';\nimport type { ProcessSpawner, ProcessSpawnOptions, RunOptions, RunResult } from './exec.js';\nimport { endStdin, fsExists, runSpawn } from './exec.js';\nimport type { GitCommandPriority, GitResult, GitRunOptions, GitSpawnOptions } from './exec.types.js';\nimport type { FilteredGitFeatures, GitFeatureOrPrefix, GitFeatures } from './features.js';\nimport { gitFeaturesByVersion } from './features.js';\nimport type { GitQueueConfig } from './gitQueue.js';\nimport { getPrimaryGitCommand, GitQueue, inferGitCommandPriority } from './gitQueue.js';\nimport type { HeadState } from './headState.js';\nimport { getMovedHead } from './headState.js';\nimport {\n\tisConfigCommand,\n\tisIndexWriteCommand,\n\tKeyedSequencer,\n\tretryWhileConfigLocked,\n\tretryWhileIndexLocked,\n\ttoExitCode,\n} from './indexLock.js';\nimport type { GitLocation } from './locator.js';\n\nexport const slowCallWarningThreshold = 2000;\nexport type GitFeatureUnsupportedMessage = (requiredVersion: string, installedVersion: string) => string;\n/** Below this, a queue-wait annotation isn't worth adding to the log line. */\nconst queueWaitAnnotationThreshold = 100;\n/** Below this, a measured event-loop stall isn't worth annotating — see {@link EventLoopMonitor}. */\nconst eventLoopDelayAnnotationThreshold = 500;\nexport const maxGitCliLength = 30000;\n\n/** Rejections from a host's `beforeIndexLockRetry` — typed writes rethrow these as thrown instead of mapping them to their own error. */\nconst runHookFailures = new WeakSet<object>();\n\nexport function isRunHookFailure(ex: unknown): boolean {\n\treturn typeof ex === 'object' && ex != null && runHookFailures.has(ex);\n}\n\ninterface PendingCommand {\n\treadonly cwd: string | undefined;\n\treadonly promise: Promise<RunResult<string | Buffer>>;\n\tspawned: boolean;\n\t/** The `onSpawn` of the run and of every call that joined it before it spawned */\n\treadonly spawnListeners: (() => void)[];\n}\n\nfunction notifySpawned(listeners: readonly (() => void)[]): void {\n\tfor (const listener of listeners) {\n\t\ttry {\n\t\t\tlistener();\n\t\t} catch (ex) {\n\t\t\tLogger.error(ex, 'GitRunOptions.onSpawn');\n\t\t}\n\t}\n}\n\n/**\n * Splits `paths` into `:(literal)` pathspec batches that each fit the command-line length limit after `prefix`, so a\n * folder named like a glob (`[id]/`) doesn't match its siblings.\n */\nexport function batchLiteralPathspecs(\n\tpaths: readonly string[],\n\tprefix: readonly string[],\n): Iterable<readonly string[]> {\n\t// Reserve the prefix and a per-arg overhead (separator + possible quoting), so neither a run of long paths nor\n\t// many short ones can push a batch past the OS limit\n\tconst perArgOverhead = 3;\n\tconst prefixLength = [...prefix, '--'].reduce((sum, arg) => sum + arg.length + perArgOverhead, 0);\n\treturn chunkByStringLength(\n\t\tpaths.map(p => `:(literal)${p}`),\n\t\tmaxGitCliLength - prefixLength,\n\t\tperArgOverhead,\n\t);\n}\n\nexport const gitConfigsBranch = ['-c', 'color.branch=false'] as const;\nexport const gitConfigsDiff = ['-c', 'color.diff=false', '-c', 'diff.mnemonicPrefix=false'] as const;\nexport const gitConfigsLog = ['-c', 'log.showSignature=false'] as const;\nexport const gitConfigsLogWithFiles = ['-c', 'log.showSignature=false', '-c', 'diff.renameLimit=0'] as const;\nexport const gitConfigsLogWithSignatures = ['-c', 'log.showSignature=true'] as const;\nexport const gitConfigsPull = ['-c', 'merge.autoStash=true', '-c', 'rebase.autoStash=true'] as const;\nexport const gitConfigsStatus = ['-c', 'color.status=false'] as const;\n\nexport const GitErrors = {\n\talreadyCheckedOut: /already checked out/i,\n\talreadyExists: /already exists/i,\n\tambiguousArgument: /fatal:\\s*ambiguous argument ['\"](.+?)['\"]: unknown revision or path not in the working tree/i,\n\tbadObject: /fatal:\\s*bad object (.*?)/i,\n\tbadRevision: /bad revision '(.*?)'/i,\n\tbranchAlreadyExists: /fatal:\\s*A branch named '.+?' already exists/i,\n\tnotFullyMerged: /error:\\s*The branch '.+?' is not fully merged/i,\n\tcantLockRef: /cannot lock ref|unable to update local ref/i,\n\tchangesWouldBeOverwritten:\n\t\t/Your local changes to the following files would be overwritten|Your local changes would be overwritten|overwritten by checkout/i,\n\tcherryPickAborted: /cherry-pick.*aborted/i,\n\tcherryPickInProgress: /cherry-pick is already in progress|You have not concluded your cherry-pick/i,\n\tcommitChangesFirst: /Please, commit your changes before you can/i,\n\tconflict: /^CONFLICT \\([^)]+\\): \\b/m,\n\tdetachedHead: /You are in 'detached HEAD' state/i,\n\tentryNotUpToDate: /error:\\s*Entry ['\"].+['\"] not uptodate\\. Cannot merge\\./i,\n\tfailedToDeleteDirectoryNotEmpty: /failed to delete '(.*?)': Directory not empty/i,\n\tgpgNotFound: /gpg:?\\s*(?:command\\s+)?not found|'gpg' is not recognized as|cannot run gpg:/i,\n\tgpgSignFailed: /^error:\\s*gpg failed to sign the data/im,\n\tinvalidName: /fatal:\\s*'.+?' is not a valid branch name/i,\n\tinvalidLineCount: /file .+? has only (\\d+) lines/i,\n\tinvalidObjectName: /invalid object name: (.*)\\s/i,\n\tinvalidObjectNameList: /could not open object name list: (.*)\\s/i,\n\t// Regcomp failure reasons from `-G`/pathspec regex compilation (search); matched without a known\n\t// prefix as a fallback when the reason appears in an unrecognized stderr shape\n\tinvalidSearchPattern:\n\t\t/Unmatched \\( or \\\\\\(|Unmatched \\[|Unmatched \\) or \\\\\\)|Invalid content of \\\\\\{\\\\\\}|Invalid preceding regular expression|Invalid regular expression|Trailing backslash|invalid regex/i,\n\tinvalidTagName: /invalid tag name/i,\n\tmainWorkingTree: /is a main working tree/i,\n\tmergeAborted: /merge.*aborted/i,\n\tmergeInProgress: /^fatal:\\s*You have not concluded your merge/i,\n\tnoFastForward: /\\(non-fast-forward\\)/i,\n\tnoMergeBase: /no merge base/i,\n\tnoRemoteReference: /unable to delete '.+?': remote ref does not exist/i,\n\tnoRemoteRepositorySpecified: /No remote repository specified\\./i,\n\tnoUpstream: /^fatal:\\s*The current branch .* has no upstream branch/i,\n\t// `git pull` (not `push`) on a branch with no upstream — distinct wording from `noUpstream` above\n\tnoTrackingInformation: /There is no tracking information for the current branch/i,\n\tnotAValidObjectName: /Not a valid object name/i,\n\tnotPossibleToFastForward: /Not possible to fast-forward/i,\n\tnotAWorkingTree: /'(.*?)' is not a working tree/i,\n\tnoUserNameConfigured: /Please tell me who you are\\./i,\n\tnothingToCommit: /nothing(?: added)? to commit|no changes added to commit/i,\n\tnoPausedOperation:\n\t\t/no merge (?:in progress|to abort)|no cherry-pick(?: or revert)? in progress|no rebase in progress/i,\n\tpermissionDenied: /Permission.*denied/i,\n\tpreviousOperationEmpty: /The previous (?:cherry-pick|revert) is now empty/i,\n\tproblemWithEditor: /there was a problem with the editor/i,\n\tpushRejected: /^error:\\s*failed to push some refs to\\b/m,\n\tpushRejectedRefDoesNotExists: /error:\\s*unable to delete '(.*?)': remote ref does not exist/m,\n\trebaseAborted: /Nothing to do|rebase.*aborted/i,\n\trebaseInProgress: /It seems that there is already a rebase-(?:merge|apply) directory/i,\n\trebaseMissingTodo: /error:\\s*could not read file .*\\/git-rebase-todo': No such file or directory/,\n\trebaseMultipleBranches: /cannot rebase onto multiple branches/i,\n\trevertAborted: /revert.*aborted/i,\n\trevertInProgress: /^(error: )?(revert|cherry-pick) is already in progress/i,\n\trefAlreadyExists: /cannot lock ref '.*?': reference already exists/i,\n\trefBadName: /refusing to update ref with bad name/i,\n\trefLocked: /fatal:\\s*cannot lock ref ['\"].+['\"]: unable to create file/i,\n\trefNonexistentObject: /trying to write ref '.*?' with nonexistent object/i,\n\trefNotAValidSha: /not a valid (?:old )?SHA1/i,\n\trefUnableToResolve: /cannot lock ref '.*?': unable to resolve reference/i,\n\trefValueMismatch: /cannot lock ref '.*?': is at [0-9a-f]+ but expected/i,\n\tremoteAhead: /rejected because the remote contains work/i,\n\t// SSH/git transports report \"Could not read from remote repository\"; HTTP(S) reports the curl failure after\n\t// \"unable to access '<url>':\", so only the connection-level curl reasons are matched (an HTTP status like\n\t// 403/404 reaches the host fine and is a different problem)\n\tremoteConnectionFailed:\n\t\t/Could not read from remote repository|unable to access '[^']+': (?:Could not resolve host|Failed to connect|Couldn't connect|Connection (?:refused|timed out|reset)|Operation timed out|Recv failure|Empty reply)/i,\n\tremoteRejected: /rejected because the remote contains work/i,\n\tsigningKeyNotAvailable: /secret key not available|no secret key|no signing key/i,\n\tsshNotFound: /ssh-keygen[^\\n]*(?:not found|No such file or directory|is not recognized)/i,\n\tstashConflictingStagedAndUnstagedLines: /Cannot remove worktree changes/i,\n\tstashNothingToSave: /No local changes to save/i,\n\tstashSavedWorkingDirAndIndexState: /Saved working directory and index state/i,\n\ttagAlreadyExists: /tag .* already exists/i,\n\ttagConflict: /! \\[rejected\\].*\\(would clobber existing tag\\)/m,\n\ttagNotFound: /tag .* not found/i,\n\tuncommittedChanges: /contains modified or untracked files/i,\n\tunmergedChanges: /error:\\s*you need to resolve your current index first/i,\n\tunmergedFiles: /is not possible because you have unmerged files|You have unmerged files/i,\n\tunresolvedConflicts:\n\t\t/You must edit all merge conflicts|Resolve all conflicts|^CONFLICT \\(|^Automatic merge failed|could not apply .*/im,\n\tunsafeRepository:\n\t\t/(?:^fatal:\\s*detected dubious ownership in repository at '([^']+)'|unsafe repository \\('([^']+)' is owned by someone else\\))[\\s\\S]*(git config --global --add safe\\.directory [^\\n•]+)/m,\n\tunstagedChanges: /You have unstaged changes/i,\n\t// Matches both variants: with a lock reason (`..., lock reason: <reason>`) and without (`...;`)\n\tworktreeLocked: /fatal:\\s*cannot remove a locked working tree/i,\n\t// Only matches the variant where Git reports a lock reason; the reason is free text, so capture the whole line\n\tworktreeLockedReason: /cannot remove a locked working tree,[ \\t]*lock reason:[ \\t]*(.*)/i,\n} as const;\n\n// `GitWarnings` moved to `@gitlens/git/errors.js` so the shared run contract can name its keys; re-exported\n// here because it's long-established as part of this module's surface.\nexport { GitWarnings };\nexport type { GitWarningKey } from '@gitlens/git/errors.js';\n\nexport class GitError extends Error {\n\treadonly cmd: string | undefined;\n\treadonly exitCode: number | string | undefined;\n\treadonly stdout: string | undefined;\n\treadonly stderr: string | undefined;\n\n\tconstructor(readonly original: Error) {\n\t\tlet message: string;\n\t\tlet stdout: string | undefined;\n\t\tlet stderr: string | undefined;\n\t\tlet cmd: string | undefined;\n\t\tlet exitCode: number | string | undefined;\n\n\t\tif (original instanceof RunError) {\n\t\t\tstdout = original.stdout;\n\t\t\tstderr = original.stderr;\n\t\t\tmessage = stderr || stdout || original.message;\n\t\t\tcmd = original.cmd;\n\t\t\texitCode = original.code;\n\t\t} else {\n\t\t\tmessage = original.message;\n\t\t}\n\n\t\tsuper(message);\n\n\t\tthis.stdout = stdout;\n\t\tthis.stderr = stderr;\n\t\tthis.cmd = cmd;\n\t\tthis.exitCode = exitCode;\n\n\t\tError.captureStackTrace?.(this, new.target);\n\t}\n}\n\nexport type PushForceOptions = { withLease: true; ifIncludes?: boolean } | { withLease: false; ifIncludes?: never };\n\ntype GitCommand =\n\t| 'branch'\n\t| 'checkout'\n\t| 'cherry-pick'\n\t| 'commit'\n\t| 'fetch'\n\t| 'merge'\n\t| 'paused-operation-abort'\n\t| 'paused-operation-continue'\n\t| 'pull'\n\t| 'push'\n\t| 'rebase'\n\t| 'reset'\n\t| 'revert'\n\t| 'show'\n\t| 'stash-apply'\n\t| 'stash-push'\n\t| 'tag'\n\t| 'update-ref'\n\t| 'update-ref-delete'\n\t| 'worktree-create'\n\t| 'worktree-delete';\n\ntype GitCommandToReasonMap = {\n\tbranch: BranchErrorReason;\n\tcheckout: CheckoutErrorReason;\n\t'cherry-pick': CherryPickErrorReason;\n\tcommit: CommitErrorReason;\n\tfetch: FetchErrorReason;\n\tmerge: MergeErrorReason;\n\t'paused-operation-abort': PausedOperationAbortErrorReason;\n\t'paused-operation-continue': PausedOperationContinueErrorReason;\n\tpull: PullErrorReason;\n\tpush: PushErrorReason;\n\trebase: RebaseErrorReason;\n\treset: ResetErrorReason;\n\trevert: RevertErrorReason;\n\tshow: ShowErrorReason;\n\t'stash-apply': StashApplyErrorReason;\n\t'stash-push': StashPushErrorReason;\n\ttag: TagErrorReason;\n\t'update-ref': ReferenceUpdateErrorReason;\n\t'update-ref-delete': ReferenceUpdateErrorReason;\n\t'worktree-create': WorktreeCreateErrorReason;\n\t'worktree-delete': WorktreeDeleteErrorReason;\n};\n\nconst errorToReasonMap = new Map<GitCommand, [RegExp, GitCommandToReasonMap[GitCommand]][]>([\n\t[\n\t\t'branch',\n\t\t[\n\t\t\t[GitErrors.branchAlreadyExists, 'alreadyExists'],\n\t\t\t[GitErrors.invalidName, 'invalidName'],\n\t\t\t[GitErrors.notFullyMerged, 'notFullyMerged'],\n\t\t\t[GitErrors.noRemoteReference, 'noRemoteReference'],\n\t\t],\n\t],\n\t[\n\t\t'checkout',\n\t\t[\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t\t[GitErrors.ambiguousArgument, 'pathspecNotFound'],\n\t\t\t[GitErrors.notAValidObjectName, 'invalidRef'],\n\t\t],\n\t],\n\t[\n\t\t'cherry-pick',\n\t\t[\n\t\t\t[GitErrors.cherryPickAborted, 'aborted'],\n\t\t\t[GitErrors.cherryPickInProgress, 'alreadyInProgress'],\n\t\t\t[GitErrors.conflict, 'conflicts'],\n\t\t\t[GitErrors.previousOperationEmpty, 'emptyCommit'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t[\n\t\t'commit',\n\t\t[\n\t\t\t[GitErrors.nothingToCommit, 'nothingToCommit'],\n\t\t\t[GitErrors.unmergedFiles, 'conflicts'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.noUserNameConfigured, 'noUserNameConfigured'],\n\t\t],\n\t],\n\t[\n\t\t'fetch',\n\t\t[\n\t\t\t[GitErrors.noFastForward, 'noFastForward'],\n\t\t\t[GitErrors.noRemoteRepositorySpecified, 'noRemote'],\n\t\t\t[GitErrors.remoteConnectionFailed, 'remoteConnectionFailed'],\n\t\t],\n\t],\n\t[\n\t\t'merge',\n\t\t[\n\t\t\t[GitErrors.mergeAborted, 'aborted'],\n\t\t\t[GitErrors.mergeInProgress, 'alreadyInProgress'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t['paused-operation-abort', [[GitErrors.noPausedOperation, 'nothingToAbort']]],\n\t[\n\t\t'paused-operation-continue',\n\t\t[\n\t\t\t// Kept FIRST: an editor failure's stderr can also carry broader messages (\"could not\n\t\t\t// commit staged changes\", …) that later patterns would otherwise claim\n\t\t\t[GitErrors.problemWithEditor, 'messageEditFailed'],\n\t\t\t[GitErrors.previousOperationEmpty, 'emptyCommit'],\n\t\t\t[GitErrors.noPausedOperation, 'nothingToContinue'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.unmergedFiles, 'unmergedFiles'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.unstagedChanges, 'unstagedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t\t// A single (non-sequencer) revert resolved to a no-op never gets git's \"previous revert is now\n\t\t\t// empty\" message — its `--continue` falls through to the commit, which reports having nothing to\n\t\t\t// commit. Mid-paused-op that means the step became empty, so it earns the same choice.\n\t\t\t//\n\t\t\t// Kept LAST because the pattern is deliberately broad: it also matches \"no changes added to\n\t\t\t// commit\" and \"nothing added to commit\", which appear alongside the more specific unmerged /\n\t\t\t// conflict / unstaged messages. Matching first would shadow those. It isn't narrowed to the\n\t\t\t// \"working tree clean\" variant because an empty step with untracked files present instead reports\n\t\t\t// \"nothing added to commit but untracked files present\".\n\t\t\t[GitErrors.nothingToCommit, 'emptyCommit'],\n\t\t],\n\t],\n\t[\n\t\t'pull',\n\t\t[\n\t\t\t[GitErrors.conflict, 'conflict'],\n\t\t\t[GitErrors.noUserNameConfigured, 'gitIdentity'],\n\t\t\t[GitErrors.remoteConnectionFailed, 'remoteConnectionFailed'],\n\t\t\t[GitErrors.unstagedChanges, 'unstagedChanges'],\n\t\t\t[GitErrors.unmergedFiles, 'unmergedFiles'],\n\t\t\t[GitErrors.commitChangesFirst, 'uncommittedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t\t[GitErrors.cantLockRef, 'refLocked'],\n\t\t\t[GitErrors.rebaseMultipleBranches, 'rebaseMultipleBranches'],\n\t\t\t[GitErrors.tagConflict, 'tagConflict'],\n\t\t\t[GitErrors.notPossibleToFastForward, 'noFastForward'],\n\t\t\t[GitErrors.noTrackingInformation, 'noUpstream'],\n\t\t],\n\t],\n\t[\n\t\t'push',\n\t\t[\n\t\t\t[GitErrors.remoteAhead, 'remoteAhead'],\n\t\t\t[GitWarnings.tipBehind, 'tipBehind'],\n\t\t\t// Kept BEFORE the generic push rejection: a failed `push -d` of a missing ref reports both\n\t\t\t// \"unable to delete '<ref>': remote ref does not exist\" and \"failed to push some refs to ...\",\n\t\t\t// and the specific reason is the actionable one.\n\t\t\t[GitErrors.pushRejectedRefDoesNotExists, 'rejectedRefDoesNotExist'],\n\t\t\t[GitErrors.pushRejected, 'rejected'],\n\t\t\t[GitErrors.permissionDenied, 'permissionDenied'],\n\t\t\t[GitErrors.remoteConnectionFailed, 'remoteConnectionFailed'],\n\t\t\t[GitErrors.noUpstream, 'noUpstream'],\n\t\t],\n\t],\n\t[\n\t\t'rebase',\n\t\t[\n\t\t\t[GitErrors.rebaseAborted, 'aborted'],\n\t\t\t[GitErrors.rebaseMissingTodo, 'aborted'],\n\t\t\t[GitErrors.rebaseInProgress, 'alreadyInProgress'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t[\n\t\t'reset',\n\t\t[\n\t\t\t[GitErrors.ambiguousArgument, 'ambiguousArgument'],\n\t\t\t[GitErrors.detachedHead, 'detachedHead'],\n\t\t\t[GitErrors.refLocked, 'refLocked'],\n\t\t\t[GitErrors.entryNotUpToDate, 'notUpToDate'],\n\t\t\t[GitErrors.permissionDenied, 'permissionDenied'],\n\t\t\t[GitErrors.unmergedChanges, 'unmergedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t[\n\t\t'revert',\n\t\t[\n\t\t\t[GitErrors.revertAborted, 'aborted'],\n\t\t\t[GitErrors.revertInProgress, 'alreadyInProgress'],\n\t\t\t[GitErrors.unresolvedConflicts, 'conflicts'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.changesWouldBeOverwritten, 'wouldOverwriteChanges'],\n\t\t],\n\t],\n\t[\n\t\t'show',\n\t\t[\n\t\t\t[GitErrors.badObject, 'invalidObject'],\n\t\t\t[GitErrors.badRevision, 'invalidRevision'],\n\t\t\t[GitErrors.notAValidObjectName, 'invalidRevision'],\n\t\t\t[GitWarnings.notFound, 'notFound'],\n\t\t\t[GitWarnings.foundButNotInRevision, 'notInRevision'],\n\t\t],\n\t],\n\t['stash-apply', [[GitErrors.changesWouldBeOverwritten, 'uncommittedChanges']]],\n\t[\n\t\t'stash-push',\n\t\t[\n\t\t\t[GitErrors.stashConflictingStagedAndUnstagedLines, 'conflictingStagedAndUnstagedLines'],\n\t\t\t[GitErrors.stashNothingToSave, 'nothingToSave'],\n\t\t\t[GitErrors.stashSavedWorkingDirAndIndexState, 'conflictingStagedAndUnstagedLines'],\n\t\t],\n\t],\n\t[\n\t\t'tag',\n\t\t[\n\t\t\t[GitErrors.tagAlreadyExists, 'alreadyExists'],\n\t\t\t[GitErrors.invalidTagName, 'invalidName'],\n\t\t\t[GitErrors.tagNotFound, 'notFound'],\n\t\t\t[GitErrors.permissionDenied, 'permissionDenied'],\n\t\t\t[GitErrors.remoteRejected, 'remoteRejected'],\n\t\t\t[GitErrors.tagConflict, 'tagConflict'],\n\t\t],\n\t],\n\t[\n\t\t'update-ref',\n\t\t[\n\t\t\t// Every entry below also matches the broad `cantLockRef` catch-all that closes the list, so\n\t\t\t// order is load-bearing — the specific shapes must be claimed first.\n\t\t\t[GitErrors.refBadName, 'invalidRef'],\n\t\t\t[GitErrors.refNonexistentObject, 'invalidObject'],\n\t\t\t[GitErrors.refNotAValidSha, 'invalidObject'],\n\t\t\t[GitErrors.refValueMismatch, 'conflict'],\n\t\t\t[GitErrors.refAlreadyExists, 'conflict'],\n\t\t\t// A ref that vanished under a compare-and-swap lost the same race as one that moved, so an\n\t\t\t// update reports both as a conflict — the caller's response (re-read, retry) is identical.\n\t\t\t[GitErrors.refUnableToResolve, 'conflict'],\n\t\t\t// Directory/file collisions and any other lock refusal\n\t\t\t[GitErrors.cantLockRef, 'conflict'],\n\t\t],\n\t],\n\t[\n\t\t'update-ref-delete',\n\t\t[\n\t\t\t[GitErrors.refBadName, 'invalidRef'],\n\t\t\t[GitErrors.refNotAValidSha, 'invalidObject'],\n\t\t\t// Kept BEFORE the generic lock failures, and split from the update table above: a deleter\n\t\t\t// that finds its target already gone has reached the state it wanted, while one that finds\n\t\t\t// the target moved has not. Collapsing both into `conflict` would force every caller to\n\t\t\t// re-read just to tell an idempotent no-op from a real race.\n\t\t\t[GitErrors.refUnableToResolve, 'notFound'],\n\t\t\t[GitErrors.refValueMismatch, 'conflict'],\n\t\t\t[GitErrors.cantLockRef, 'conflict'],\n\t\t],\n\t],\n\t[\n\t\t'worktree-create',\n\t\t[\n\t\t\t[GitErrors.alreadyCheckedOut, 'alreadyCheckedOut'],\n\t\t\t[GitErrors.alreadyExists, 'alreadyExists'],\n\t\t],\n\t],\n\t[\n\t\t'worktree-delete',\n\t\t[\n\t\t\t// Must come first -- a locked worktree's lock reason is free text that can otherwise match the errors below\n\t\t\t[GitErrors.worktreeLocked, 'locked'],\n\t\t\t[GitErrors.mainWorkingTree, 'defaultWorkingTree'],\n\t\t\t[GitErrors.uncommittedChanges, 'uncommittedChanges'],\n\t\t\t[GitErrors.failedToDeleteDirectoryNotEmpty, 'directoryNotEmpty'],\n\t\t],\n\t],\n]);\n\nexport function getGitCommandError<T extends GitCommand, TReturn extends GitCommandError<any>>(\n\tcommand: T,\n\tex: GitError,\n\tcreator: (reason: GitCommandToReasonMap[T] | undefined) => TReturn,\n): TReturn {\n\tconst msg: string = ex?.toString() ?? '';\n\n\tconst errorsToReasons = errorToReasonMap.get(command) as [RegExp, GitCommandToReasonMap[T]][] | undefined;\n\tif (errorsToReasons != null) {\n\t\tfor (const [error, reason] of errorsToReasons) {\n\t\t\tif (error.test(msg) || (ex.stderr && error.test(ex.stderr)) || (ex.stdout && error.test(ex.stdout))) {\n\t\t\t\treturn creator(reason);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn creator(undefined);\n}\n\nfunction extractSigningErrorText(ex: unknown): string {\n\tif (ex == null) return '';\n\tif (ex instanceof GitError) return ex.stderr || ex.stdout || ex.message || '';\n\tif (ex instanceof Error) return ex.message || '';\n\tif (typeof ex === 'string') return ex;\n\tif (typeof ex === 'number' || typeof ex === 'boolean' || typeof ex === 'bigint') return String(ex);\n\tif (typeof ex === 'object' && 'message' in ex && typeof ex.message === 'string') return ex.message;\n\treturn '';\n}\n\n/**\n * Classifies a Git error as a signing-related failure using the {@link GitErrors}\n * signing regexes. Returns the matched {@link SigningErrorReason}, or `undefined`\n * when the error is not a recognized signing failure.\n *\n * Precedence is significant: `passphraseFailed` (gpg sign failure) is checked\n * before `noKey`, matching the ordering used historically in patch.ts — a\n * combined stderr like \"error: gpg failed to sign … gpg: No secret key\"\n * resolves to `passphraseFailed`, the outer cause.\n */\nexport function classifySigningError(ex: unknown): SigningErrorReason | undefined {\n\tconst text = extractSigningErrorText(ex);\n\tif (!text) return undefined;\n\tif (GitErrors.gpgSignFailed.test(text)) return 'passphraseFailed';\n\tif (GitErrors.signingKeyNotAvailable.test(text)) return 'noKey';\n\tif (GitErrors.gpgNotFound.test(text)) return 'gpgNotFound';\n\tif (GitErrors.sshNotFound.test(text)) return 'sshNotFound';\n\treturn undefined;\n}\n\n/**\n * Infers the {@link SigningFormat} from stderr hints (e.g., mentions of\n * `ssh-keygen` or `gpg.ssh.*` config keys). Returns `undefined` when no hints\n * are present so callers can supply their own default (typically `'gpg'`).\n *\n * Used as a fallback when `config.getSigningConfig` is unavailable or rejects\n * on the error path.\n */\nexport function inferSigningFormatFromError(ex: unknown): SigningFormat | undefined {\n\tconst text = extractSigningErrorText(ex);\n\tif (!text) return undefined;\n\tif (/\\bssh-keygen\\b|gpg\\.ssh\\.(?:program|allowedsignersfile)/i.test(text)) return 'ssh';\n\tif (/\\bgpg\\b/i.test(text)) return 'gpg';\n\treturn undefined;\n}\n\nexport interface SearchErrorClassification {\n\treason: GitSearchErrorReason;\n\tdetail?: string;\n}\n\n/**\n * Classifies a graph search failure from its stderr into an {@link GitSearchErrorReason}, with the\n * offending pattern/ref text (when git reports one) as `detail`. Returns `undefined` when the error\n * isn't a `GitError` with stderr, or the stderr doesn't match a recognized shape.\n */\nexport function classifySearchError(ex: unknown): SearchErrorClassification | undefined {\n\tif (!(ex instanceof GitError) || !ex.stderr) return undefined;\n\n\tconst stderr = ex.stderr;\n\n\t// `-G<pattern>`/pathspec regex compile failures report one of two shapes:\n\t// fatal: command line, '<pattern>': <regcomp reason>\n\t// fatal: invalid regex: <regcomp reason>\n\t// The pattern itself may contain \"': \", so anchor on the known prefixes and let the greedy `.*`\n\t// resolve to the LAST matching delimiter rather than splitting on the first occurrence.\n\tconst patternDetail =\n\t\t/^fatal:\\s*command line,\\s*'.*':\\s*(.+)$/im.exec(stderr)?.[1] ??\n\t\t/^fatal:\\s*invalid regex:\\s*(.+)$/im.exec(stderr)?.[1];\n\tif (patternDetail != null) return { reason: 'invalidPattern', detail: patternDetail.trim() };\n\n\tif (GitErrors.invalidSearchPattern.test(stderr)) return { reason: 'invalidPattern' };\n\n\tconst ambiguous = GitErrors.ambiguousArgument.exec(stderr);\n\tif (ambiguous != null) return { reason: 'invalidRef', detail: ambiguous[1] };\n\n\tconst badRevision = GitErrors.badRevision.exec(stderr);\n\tif (badRevision != null) return { reason: 'invalidRef', detail: badRevision[1] };\n\n\tif (/unknown revision/i.test(stderr)) return { reason: 'invalidRef' };\n\n\treturn undefined;\n}\n\nexport interface GitOptions {\n\t/** Custom environment variables to add to every git command */\n\tenv?: Record<string, string | undefined>;\n\t/** Dynamic environment provider called for each command (e.g., host-discovered SCM credentials) */\n\tgetEnvironment?: () => Record<string, string | undefined> | undefined;\n\t/** Git command timeout in milliseconds, for runs that don't set their own. Defaults to 60000. Set to 0 to disable. */\n\tgitTimeout?: number;\n\t/** Returns whether the workspace is currently trusted. Defaults to true when not provided. Called on every exec/stream. */\n\tisTrusted?: () => boolean;\n\t/** Queue configuration (max concurrent processes, etc.) */\n\tqueue?: GitQueueConfig;\n\t/** Decodes non-UTF-8 git output. Required when repositories use non-UTF-8 encodings. */\n\tdecode?: (data: Uint8Array, options?: { readonly encoding: string }) => string | Promise<string>;\n\t/** Hooks for observing git execution events */\n\thooks?: GitHooks;\n\t/** Optional dedicated logger for git command logging */\n\tlogger?: LogChannel;\n\t/** Launches the git process of every run and stream (not the locator's); defaults to Node's `spawn`. Set it to start git from a helper process when the host's own is too large to fork cheaply. */\n\tspawn?: ProcessSpawner;\n}\n\nexport interface GitHooks {\n\t/** Called when a git command is aborted (timeout or cancellation) */\n\tonAborted?(info: {\n\t\toperation: string;\n\t\treason: 'timeout' | 'cancellation' | 'unknown';\n\t\tduration: number;\n\t\ttimeout: number;\n\t}): void;\n\t/** Called when a queued command waited longer than 1s before executing */\n\tonSlowQueue?(info: {\n\t\tpriority: GitCommandPriority;\n\t\twaitTime: number;\n\t\tactive: number;\n\t\tqueued: Record<GitCommandPriority, number>;\n\t\tmaxConcurrent: number;\n\t}): void;\n\t/**\n\t * Called once per git command that ran slowly (over the slow-call threshold). Fired only for the\n\t * command that actually executed, never for a deduplicated rider that merely awaited it, so a single\n\t * slow subprocess counts once. `operation` is the primary git subcommand (e.g. `status`, `rev-list`).\n\t */\n\tonSlowCommand?(info: {\n\t\toperation: string | undefined;\n\t\tcwd: string | undefined;\n\t\tduration: number;\n\t\t/** Measured event-loop stall overlapping the command; omitted (or 0) when none was observed. */\n\t\teventLoopDelay?: number;\n\t\t/** Caller-declared operation family, see `GitRunOptions.slownessCategory`. */\n\t\tslownessCategory?: GitHealthSlownessCategory;\n\t}): void;\n}\n\n/**\n * Keys dropped from the INHERITED `process.env` before it seeds the base git environment. git hands these\n * to anything it launches (a hook, `rebase -x`, an editor invoked as `GIT_EDITOR`) to describe the command\n * it is running; a host started that way would otherwise run every command against THAT repository with\n * THAT command's settings, whatever `cwd` we pass. None is worth keeping when set deliberately either: a\n * `GIT_DIR` would point every repository the host opens at one. `options.env`, `options.getEnvironment()`\n * and a per-call `env` are merged in afterwards, so any of them can still set these keys (e.g. a temporary\n * `GIT_INDEX_FILE` for a call).\n */\nconst inheritedEnvKeysToDrop: ReadonlySet<string> = new Set([\n\t// The parent's repository location — must come from our own cwd\n\t'GIT_DIR',\n\t'GIT_WORK_TREE',\n\t'GIT_INDEX_FILE',\n\t'GIT_COMMON_DIR',\n\t'GIT_OBJECT_DIRECTORY',\n\t'GIT_ALTERNATE_OBJECT_DIRECTORIES',\n\t'GIT_NAMESPACE',\n\t// What git tells a child about the command it's running: its `-c` overrides, its helpers' location, the\n\t// subdirectory it ran from, and the label for its reflog entries\n\t'GIT_CONFIG_PARAMETERS',\n\t'GIT_EXEC_PATH',\n\t'GIT_PREFIX',\n\t'GIT_REFLOG_ACTION',\n]);\n\n/**\n * Dropped only when git launched the host, which it always marks by exporting `GIT_EXEC_PATH`: an editor\n * opened for `commit --amend` gets that commit's author and date, while an identity set deliberately (e.g.\n * by direnv) must still reach our commits.\n */\nconst inheritedIdentityKeysToDrop: ReadonlySet<string> = new Set([\n\t'GIT_AUTHOR_NAME',\n\t'GIT_AUTHOR_EMAIL',\n\t'GIT_AUTHOR_DATE',\n\t'GIT_COMMITTER_NAME',\n\t'GIT_COMMITTER_EMAIL',\n\t'GIT_COMMITTER_DATE',\n]);\n\n/** `process.env` with {@link inheritedEnvKeysToDrop} removed, and {@link inheritedIdentityKeysToDrop} when git launched us. */\nfunction getInheritedEnv(): Record<string, string | undefined> {\n\tconst launchedByGit = process.env.GIT_EXEC_PATH != null;\n\treturn Object.fromEntries(\n\t\tObject.entries(process.env).filter(\n\t\t\t([key]) => !inheritedEnvKeysToDrop.has(key) && !(launchedByGit && inheritedIdentityKeysToDrop.has(key)),\n\t\t),\n\t);\n}\n\nconst emptyArray: readonly never[] = Object.freeze([]);\nconst emptyObj = Object.freeze({});\nconst trailingNewlineRegex = /[\\r|\\n]+$/;\nconst unsharedRunCounter = getScopedCounter();\nconst uniqueCounterForStream = getScopedCounter();\n\ntype ExitCodeOnlyGitCommandOptions = GitRunOptions & { exitCodeOnly: true };\n\n/** What a `notify`-flagged run announces once it settles, worked out before it spawns */\ntype PendingNotify =\n\t/** An explicit `notify` list, announced as given */\n\t| { readonly cwd: string; readonly pathOverride: string | undefined; readonly changes: readonly RepositoryChange[] }\n\t/** `notify: 'infer'`'s classification, with HEAD before the run when the verb moves only HEAD's branch */\n\t| { readonly cwd: string; readonly command: CommandChanges; readonly headBefore: HeadState };\n\n/** The refs a `notify`-flagged run proved it moved, as {@link Git.bindChangeNotifier} passes them on */\nexport type NamedRefs = { readonly refs: readonly string[]; readonly configConfinedToRefs?: boolean };\n\nexport class Git {\n\t/** Map of running git commands — avoids running duplicate overlapping commands */\n\tprivate readonly pendingCommands = new Map<string, PendingCommand>();\n\t/** Queue for throttling background git operations */\n\tprivate readonly _queue: GitQueue;\n\t/** Orders the index-writing runs of each checkout, so they don't race for its `index.lock` */\n\tprivate readonly _indexWrites = new KeyedSequencer();\n\t/** The spawn behind every non-streaming run — a field only so tests can substitute it */\n\tprivate readonly _runSpawn: typeof runSpawn = runSpawn;\n\t/** Detects event-loop stalls while at least one git command is in flight */\n\tprivate readonly _eventLoopMonitor = new EventLoopMonitor();\n\t/** Count of git commands currently in flight, across both the exec and streaming paths */\n\tprivate _activeCommandCount = 0;\n\n\t/** Cached base environment: process.env (minus {@link inheritedEnvKeysToDrop}) + static options.env + GCM/LC_ALL vars */\n\tprivate _baseEnv: Record<string, string | undefined> | undefined;\n\t/** Cached full environment: base + dynamic getEnvironment() result */\n\tprivate _fullEnv: Record<string, string | undefined> | undefined;\n\t/** Last dynamic env reference, used to detect when getEnvironment() returns a new object */\n\tprivate _lastDynamicEnv: Record<string, string | undefined> | undefined | null;\n\n\t/** Bound via {@link bindChangeNotifier}; announces a `notify`-flagged run's changes. No-op until bound. */\n\tprivate _changeNotifier:\n\t\t| ((\n\t\t\t\trepoPaths: readonly string[],\n\t\t\t\tchanges: readonly RepositoryChange[],\n\t\t\t\tsharedPaths?: readonly string[],\n\t\t\t\tnamed?: NamedRefs,\n\t\t ) => void)\n\t\t| undefined;\n\t/** Bound via {@link bindHeadReader}; reads HEAD around a `notify: 'infer'` run that moves only HEAD's branch */\n\tprivate _headReader: ((path: string) => Promise<HeadState>) | undefined;\n\t/** Bound via {@link bindIgnoredWorktreeRootsReader}; read before a `notify: 'infer'` worktree write */\n\tprivate _ignoredWorktreeRootsReader: ((path: string) => Promise<readonly string[] | undefined>) | undefined;\n\t/** The classifier behind `notify: 'infer'` — a field only so tests can substitute it */\n\tprivate readonly _classify: typeof getChangesForCommand = getChangesForCommand;\n\n\tconstructor(\n\t\tprivate readonly _locator: () => Promise<GitLocation>,\n\t\treadonly options: GitOptions = {},\n\t) {\n\t\tthis._queue = new GitQueue(options.queue, { onSlowQueue: options.hooks?.onSlowQueue });\n\t}\n\n\t/**\n\t * Binds the callback a `notify`-flagged {@link run} calls once it settles. `CliGitProvider` wires this\n\t * to its own `notifyChanged` from its constructor — including when it's handed a pre-built `Git` via\n\t * `options.git`, so a host-supplied instance gets bound too. With nothing bound, `notify` is a no-op.\n\t * `repoPaths` holds more than one path only for a `-C`-scoped shared-state verb: the `-C` target, then the\n\t * caller's own `cwd`. `sharedPaths` names the paths that were not run in but share the repository, which\n\t * hear only the part of `changes` every worktree sees (the caller's `cwd`, when the verb also changed\n\t * something local to the `-C` target). `named.refs`, given only when the run proved them, are the full ref\n\t * names it moved, as `repository.onChanged`'s `refs` are: `repoPaths` hear all of them, `sharedPaths` those of\n\t * the kinds they hear. `named.configConfinedToRefs` confines a `config` change to those branches' sections.\n\t */\n\tbindChangeNotifier(\n\t\tfn: (\n\t\t\trepoPaths: readonly string[],\n\t\t\tchanges: readonly RepositoryChange[],\n\t\t\tsharedPaths?: readonly string[],\n\t\t\tnamed?: NamedRefs,\n\t\t) => void,\n\t): void {\n\t\tthis._changeNotifier = fn;\n\t}\n\n\t/**\n\t * Binds the reader a `notify: 'infer'` {@link run} of a verb that moves only HEAD's branch (a commit, a reset)\n\t * calls on the tree it runs in, before and after the run, to name that branch. It must not run git, and resolves\n\t * `undefined` when HEAD can't be read. With nothing bound, such a run announces its branch move unnamed.\n\t */\n\tbindHeadReader(fn: (path: string) => Promise<HeadState>): void {\n\t\tthis._headReader = fn;\n\t}\n\n\t/**\n\t * Binds the reader a `notify: 'infer'` {@link run} of a worktree write calls on the tree it runs in: the absolute\n\t * folders, under that repository's common git dir, whose worktrees the host has core ignore. No worktree list shows\n\t * one, so its add, remove, lock, unlock or move announces no `worktrees` change. Each folder comes in every spelling\n\t * a path may take (as the host spells the git dir, and resolved through symlinks); a path spelled through some other\n\t * symlink keeps the change. It runs git at most once per repository (for a common git dir its files don't show),\n\t * resolves `[]` (or `undefined`) when nothing is ignored, and rejects when the folders can't be read, which keeps the\n\t * change. With nothing bound, every worktree write announces `worktrees`.\n\t */\n\tbindIgnoredWorktreeRootsReader(fn: (path: string) => Promise<readonly string[] | undefined>): void {\n\t\tthis._ignoredWorktreeRootsReader = fn;\n\t}\n\n\t/**\n\t * Returns the base environment for git commands. Cached to avoid spreading\n\t * process.env (30-100+ keys) on every call. Includes static options.env and\n\t * GCM/LC_ALL vars but NOT dynamic getEnvironment() or per-call env overrides.\n\t */\n\tprivate getBaseEnv(): Record<string, string | undefined> {\n\t\treturn (this._baseEnv ??= {\n\t\t\t...getInheritedEnv(),\n\t\t\t...(this.options.env ?? emptyObj),\n\t\t\tGCM_INTERACTIVE: 'NEVER',\n\t\t\tGCM_PRESERVE_CREDS: 'TRUE',\n\t\t\tLC_ALL: 'C',\n\t\t});\n\t}\n\n\t/**\n\t * Returns the full environment (base + dynamic). Cached and invalidated\n\t * when getEnvironment() returns a different object reference.\n\t */\n\tprivate getFullEnv(): Record<string, string | undefined> {\n\t\tconst dynamicEnv = this.options.getEnvironment?.() ?? undefined;\n\t\tif (this._fullEnv != null && dynamicEnv === this._lastDynamicEnv) return this._fullEnv;\n\n\t\tthis._lastDynamicEnv = dynamicEnv;\n\t\tthis._fullEnv = dynamicEnv != null ? { ...this.getBaseEnv(), ...dynamicEnv } : this.getBaseEnv();\n\t\treturn this._fullEnv;\n\t}\n\n\t/**\n\t * Builds the environment for a git command. Returns the cached full env\n\t * directly when there are no per-call overrides (the common case).\n\t * Only allocates a new object when per-call env overrides are provided.\n\t */\n\tprivate buildEnv(perCallEnv: Record<string, string | undefined> | undefined): Record<string, string | undefined> {\n\t\tif (perCallEnv == null) return this.getFullEnv();\n\n\t\treturn { ...this.getFullEnv(), ...perCallEnv };\n\t}\n\n\tdispose(): void {\n\t\tthis._queue.dispose();\n\t\tthis._eventLoopMonitor.dispose();\n\t}\n\n\t/**\n\t * Drops in-flight commands so a later identical call spawns its own run instead of joining one that\n\t * started before a change. With `repoPaths`, drops only runs whose `cwd` is one of them or inside one;\n\t * without, drops every run.\n\t */\n\tclearPendingCommands(repoPaths?: readonly string[]): void {\n\t\tif (repoPaths == null) {\n\t\t\tthis.pendingCommands.clear();\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const [key, { cwd }] of this.pendingCommands) {\n\t\t\tif (cwd == null) continue;\n\n\t\t\tif (repoPaths.some(p => arePathsEqual(cwd, p) || isDescendant(cwd, p))) {\n\t\t\t\tthis.pendingCommands.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Marks one more git command as in flight; starts the event-loop monitor on the first. */\n\tprivate beginActiveCommand(): void {\n\t\tthis._activeCommandCount++;\n\t\tif (this._activeCommandCount === 1) {\n\t\t\tthis._eventLoopMonitor.start();\n\t\t}\n\t}\n\n\t/** Marks a git command as finished; stops the event-loop monitor once none remain. */\n\tprivate endActiveCommand(): void {\n\t\tthis._activeCommandCount--;\n\t\tif (this._activeCommandCount === 0) {\n\t\t\tthis._eventLoopMonitor.stop();\n\t\t}\n\t}\n\n\t/** Formats the shared \"event loop blocked\" log annotation; undefined below {@link eventLoopDelayAnnotationThreshold}. */\n\tprivate formatEventLoopDelayAnnotation(sinceEpochMs: number): string | undefined {\n\t\tconst delay = this._eventLoopMonitor.maxDelaySince(sinceEpochMs);\n\t\treturn delay >= eventLoopDelayAnnotationThreshold ? `event loop blocked ~${delay}ms` : undefined;\n\t}\n\n\tprivate _gitLocation: GitLocation | undefined;\n\tprivate _gitLocationPromise: Promise<GitLocation> | undefined;\n\n\tprivate async getLocation(): Promise<GitLocation> {\n\t\tif (this._gitLocation == null) {\n\t\t\tthis._gitLocationPromise ??= this._locator();\n\t\t\tthis._gitLocation = await this._gitLocationPromise;\n\t\t}\n\t\treturn this._gitLocation;\n\t}\n\n\tasync path(): Promise<string> {\n\t\treturn (await this.getLocation()).path;\n\t}\n\n\tasync version(): Promise<string> {\n\t\treturn (await this.getLocation()).version;\n\t}\n\n\tsupports(feature: GitFeatures): boolean | Promise<boolean> {\n\t\tconst version = gitFeaturesByVersion.get(feature);\n\t\tif (version == null) return true;\n\n\t\treturn this._gitLocation != null\n\t\t\t? compare(fromString(this._gitLocation.version), fromString(version)) !== -1\n\t\t\t: this.version().then(v => compare(fromString(v), fromString(version)) !== -1);\n\t}\n\n\tsupported<T extends GitFeatureOrPrefix>(feature: T): FilteredGitFeatures<T>[] | Promise<FilteredGitFeatures<T>[]> {\n\t\tfunction supportedCore(gitVersion: string): FilteredGitFeatures<T>[] {\n\t\t\treturn [...gitFeaturesByVersion]\n\t\t\t\t.filter(([f, v]) => f.startsWith(feature) && compare(fromString(gitVersion), v) !== -1)\n\t\t\t\t.map(([f]) => f as FilteredGitFeatures<T>);\n\t\t}\n\n\t\tif (this._gitLocation == null) {\n\t\t\treturn this.version().then(v => supportedCore(v));\n\t\t}\n\t\treturn supportedCore(this._gitLocation.version);\n\t}\n\n\tasync ensureSupports(feature: GitFeatures, prefix: string, suffix: string): Promise<void>;\n\tasync ensureSupports(feature: GitFeatures, message: GitFeatureUnsupportedMessage): Promise<void>;\n\tasync ensureSupports(\n\t\tfeature: GitFeatures,\n\t\tprefixOrMessage: string | GitFeatureUnsupportedMessage,\n\t\tsuffix?: string,\n\t): Promise<void> {\n\t\tconst version = gitFeaturesByVersion.get(feature);\n\t\tif (version == null) return;\n\n\t\tconst gitVersion = await this.version();\n\t\tif (compare(fromString(gitVersion), fromString(version)) !== -1) return;\n\n\t\tconst message =\n\t\t\ttypeof prefixOrMessage === 'function'\n\t\t\t\t? prefixOrMessage(version, gitVersion)\n\t\t\t\t: `${prefixOrMessage} requires a newer version of Git (>= ${version}) than is currently installed (${gitVersion}).${suffix}`;\n\t\tthrow new Error(message);\n\t}\n\n\tasync run(\n\t\toptions: ExitCodeOnlyGitCommandOptions,\n\t\t...args: readonly (string | undefined)[]\n\t): Promise<GitResult<unknown>>;\n\tasync run<T extends string | Buffer = string>(\n\t\toptions: GitRunOptions,\n\t\t...args: readonly (string | undefined)[]\n\t): Promise<GitResult<T>>;\n\tasync run<T extends string | Buffer = string>(\n\t\toptions: GitRunOptions,\n\t\t...args: readonly (string | undefined)[]\n\t): Promise<GitResult<T | unknown>> {\n\t\tif (this.options.isTrusted?.() === false) throw new WorkspaceUntrustedError();\n\n\t\tconst runArgs = args.filter(a => a != null);\n\n\t\t// `notify` announces once the run settles (success, failure or cancellation), which the bare\n\t\t// `return <promise>` paths below don't wait for; callers without it never take this branch.\n\t\tif (options.notify != null) {\n\t\t\tconst pending = await this.prepareNotify(options, runArgs);\n\t\t\ttry {\n\t\t\t\treturn await this.run<T>({ ...options, notify: undefined }, ...args);\n\t\t\t} finally {\n\t\t\t\tif (pending != null) {\n\t\t\t\t\tawait this.applyNotify(pending);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst gitCommand = `git ${runArgs.join(' ')}`;\n\n\t\t// If cache is provided, use it to cache the full result\n\t\tif (options.caching != null) {\n\t\t\tconst cachePath = options.caching.commonPath ?? options.cwd!;\n\t\t\t// Drop the cached (or in-flight) entry first so `getOrCreate` below always creates a fresh\n\t\t\t// entry with its own `AbortAggregate` — the underlying spawn can then never join an in-flight\n\t\t\t// run that started before this caller's own write.\n\t\t\tif (options.caching.force) {\n\t\t\t\toptions.caching.cache.delete(cachePath, gitCommand);\n\t\t\t}\n\n\t\t\treturn options.caching.cache.getOrCreate(\n\t\t\t\tcachePath,\n\t\t\t\tgitCommand,\n\t\t\t\tasync (cacheable, signal) => {\n\t\t\t\t\t// Bind the shared spawn to the aggregate `signal` (fires only when ALL current callers\n\t\t\t\t\t// abort), not this-caller's `options.cancellation` — otherwise a superseded caller's\n\t\t\t\t\t// abort would kill the shared command and reject concurrent riders that never cancelled.\n\t\t\t\t\tconst result = await this.runCore<T>(\n\t\t\t\t\t\t{ ...options, caching: undefined, cancellation: signal ?? options.cancellation },\n\t\t\t\t\t\trunArgs,\n\t\t\t\t\t\tgitCommand,\n\t\t\t\t\t);\n\t\t\t\t\t// Never cache a result that isn't a genuine command outcome. Under `errors: 'ignore'` a\n\t\t\t\t\t// cancelled/aborted run RESOLVES an empty result, which — left cached — would be served as a\n\t\t\t\t\t// real empty result for the full TTL (e.g. a valid merge-base read back as \"none\").\n\t\t\t\t\t// Invalidate on anything that isn't a clean exit, or whenever the aggregate signal aborted,\n\t\t\t\t\t// so the entry self-evicts instead of poisoning later callers.\n\t\t\t\t\t//\n\t\t\t\t\t// `status !== 'exited'` is what catches the case a bare `exitCode` check cannot. A swallowed\n\t\t\t\t\t// `GitWarnings` match used to report `exitCode: 0` UNCONDITIONALLY — the old code read it off\n\t\t\t\t\t// a `result` that is only ever assigned on the non-throwing path, so it was always the `?? 0`\n\t\t\t\t\t// fallback — which meant `exitCode !== 0` could never fire and every swallowed failure was\n\t\t\t\t\t// cached. A `warned` result now carries git's real code, so it's the status, not the code,\n\t\t\t\t\t// that has to do the work here. The `exitCode !== 0` half is kept as-is — a non-zero exit is\n\t\t\t\t\t// a real answer and arguably cacheable, but it isn't cached today and this isn't the change\n\t\t\t\t\t// to start.\n\t\t\t\t\tif (result.completion.status !== 'exited' || result.exitCode !== 0 || signal?.aborted) {\n\t\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t},\n\t\t\t\t// Forward this caller's cancellation so `getOrCreate` races each caller's own wait — an\n\t\t\t\t// aborting caller rejects only itself, leaving the shared work (and its riders) intact.\n\t\t\t\t{ ...options.caching.options, cancellation: options.cancellation },\n\t\t\t);\n\t\t}\n\n\t\treturn this.runCore<T>(options, runArgs, gitCommand);\n\t}\n\n\t/**\n\t * Works out, before a `notify`-flagged {@link run} spawns, what it announces once it settles — `undefined` unless\n\t * both `notify` and a {@link bindChangeNotifier bound} notifier are present, so an unflagged caller pays nothing.\n\t * A verb that moves only HEAD's branch reads HEAD here, since the run may move it.\n\t */\n\tprivate async prepareNotify(options: GitRunOptions, args: readonly string[]): Promise<PendingNotify | undefined> {\n\t\tconst notify = options.notify;\n\t\tif (notify == null || this._changeNotifier == null || options.cwd == null) return undefined;\n\n\t\t// The argv git sees, which `options.configs` (a `-c`, or even a `-C`) leads\n\t\tconst argv = options.configs?.length ? [...options.configs, ...args] : args;\n\t\tif (notify !== 'infer') {\n\t\t\t// The caller decided exactly what changed; still resolve WHERE it changed the same way `infer`\n\t\t\t// does, since the caller may have passed its own `-C` in the argv.\n\t\t\treturn { cwd: options.cwd, pathOverride: leadingCommand(argv).pathOverride, changes: notify };\n\t\t}\n\n\t\tlet command = this._classify(argv);\n\t\tif (command == null) return undefined; // read-only or object-store-only — nothing to announce\n\n\t\tif (command.worktreePaths != null && command.changes.includes('worktrees')) {\n\t\t\tcommand = await this.withoutIgnoredWorktrees(\n\t\t\t\tcommand,\n\t\t\t\tcommand.worktreePaths,\n\t\t\t\tthis.resolveNotifyPath(options.cwd, command.pathOverride),\n\t\t\t);\n\t\t\tif (command == null) return undefined;\n\t\t}\n\n\t\tconst headBefore =\n\t\t\tcommand.movesHeadBranch && this._headReader != null\n\t\t\t\t? await this.readHead(this.resolveNotifyPath(options.cwd, command.pathOverride))\n\t\t\t\t: undefined;\n\t\treturn { cwd: options.cwd, command: command, headBefore: headBefore };\n\t}\n\n\t/** Announces what {@link prepareNotify} worked out, once the run has settled */\n\tprivate async applyNotify(pending: PendingNotify): Promise<void> {\n\t\tif (!('command' in pending)) {\n\t\t\tthis._changeNotifier?.([this.resolveNotifyPath(pending.cwd, pending.pathOverride)], pending.changes);\n\t\t\treturn;\n\t\t}\n\n\t\tconst command = pending.command;\n\t\tconst ranIn = this.resolveNotifyPath(pending.cwd, command.pathOverride);\n\t\tlet changes = command.changes;\n\t\tlet sharedChanges = command.sharedChanges;\n\t\tconst refs = [...(command.refs ?? [])];\n\t\tif (command.movesHeadBranch && this._headReader != null) {\n\t\t\tconst moved = getMovedHead(pending.headBefore, await this.readHead(ranIn));\n\t\t\tif (moved === 'detached') {\n\t\t\t\t// A detached HEAD moving moves no branch\n\t\t\t\tchanges = changes.filter(c => c !== 'heads');\n\t\t\t\tsharedChanges = sharedChanges.filter(c => c !== 'heads');\n\t\t\t\t// Nothing else changed, and announcing `[]` would reset everything\n\t\t\t\tif (!changes.length) return;\n\t\t\t} else if (moved != null && changes.includes('heads') && !refs.includes(moved.branch)) {\n\t\t\t\trefs.push(moved.branch);\n\t\t\t}\n\t\t}\n\n\t\tconst notifier = this._changeNotifier;\n\t\tif (notifier == null) return;\n\n\t\tlet named: NamedRefs | undefined;\n\t\tif (refs.length) {\n\t\t\tnamed = command.configConfinedToRefs ? { refs: refs, configConfinedToRefs: true } : { refs: refs };\n\t\t}\n\n\t\t// A `-C`-scoped write also changes what the caller's own `cwd` sees when both share a `.git`: a branch,\n\t\t// tag or stash it wrote. The target may be a worktree the cache never registered, so its eviction can't be\n\t\t// trusted to reach `cwd`; announce the shared kinds there too, and only those. A write it can't classify\n\t\t// (`[]`) resets both, since what it shares is unknown.\n\t\tconst cwd = normalizePath(pending.cwd);\n\t\tif (command.pathOverride != null && cwd !== ranIn && (sharedChanges.length || !changes.length)) {\n\t\t\tif (sharedChanges.length === changes.length) {\n\t\t\t\tnotifier([ranIn, cwd], changes, undefined, named);\n\t\t\t} else {\n\t\t\t\tnotifier([ranIn], changes, [cwd], named);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tnotifier([ranIn], changes, undefined, named);\n\t}\n\n\t/**\n\t * `command` without its `worktrees` and `worktreeHead` changes when every worktree it acts on lies under a folder\n\t * whose worktrees are ignored, read before the run while the tree it runs in surely exists; `undefined` when nothing\n\t * else is left to announce, since announcing `[]` would reset everything. Git first matches an argument against the\n\t * trailing path components of every worktree, so a relative one may name a worktree outside those folders whatever\n\t * it resolves to, and keeps the change.\n\t */\n\tprivate async withoutIgnoredWorktrees(\n\t\tcommand: CommandChanges,\n\t\tworktreePaths: readonly string[],\n\t\tranIn: string,\n\t): Promise<CommandChanges | undefined> {\n\t\tconst reader = this._ignoredWorktreeRootsReader;\n\t\tif (reader == null || !worktreePaths.every(p => isAbsolute(p))) return command;\n\n\t\tlet roots: readonly string[] | undefined;\n\t\ttry {\n\t\t\troots = await reader(ranIn);\n\t\t} catch {}\n\t\tif (!roots?.length) return command;\n\n\t\t// Resolved as git resolves them, so a `..` segment can't lead a path that only starts under a folder out of it\n\t\tconst resolved = worktreePaths.map(p => normalizePath(resolvePath(ranIn, p)));\n\t\tif (!resolved.every(p => roots.some(root => isDescendant(p, root)))) return command;\n\n\t\tconst changes = command.changes.filter(c => c !== 'worktrees' && c !== 'worktreeHead');\n\t\tif (!changes.length) return undefined;\n\n\t\treturn {\n\t\t\t...command,\n\t\t\tchanges: changes,\n\t\t\tsharedChanges: command.sharedChanges.filter(c => c !== 'worktrees' && c !== 'worktreeHead'),\n\t\t};\n\t}\n\n\t/** HEAD of `path` through the {@link bindHeadReader bound} reader, or `undefined` when it can't be read */\n\tprivate async readHead(path: string): Promise<HeadState> {\n\t\ttry {\n\t\t\treturn await this._headReader?.(path);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate resolveNotifyPath(cwd: string, pathOverride: string | undefined): string {\n\t\treturn normalizePath(pathOverride != null ? resolvePath(cwd, pathOverride) : cwd);\n\t}\n\n\tprivate async runCore<T extends string | Buffer>(\n\t\toptions: GitRunOptions,\n\t\targs: string[],\n\t\tgitCommand: string,\n\t): Promise<GitResult<T | unknown>> {\n\t\tconst start = hrtime();\n\t\tconst startEpochMs = Date.now();\n\n\t\tgitCommand = `[${options.cwd}] ${gitCommand}`;\n\t\tconst {\n\t\t\tbeforeIndexLockRetry,\n\t\t\tcancellation,\n\t\t\tconfigs,\n\t\t\tcorrelationKey,\n\t\t\tonSpawn,\n\t\t\terrors: errorHandling,\n\t\t\tencoding,\n\t\t\texpectedExitCodes,\n\t\t\trunLocally: _,\n\t\t\tselfMaintenance,\n\t\t\tslownessCategory,\n\t\t\t...opts\n\t\t} = options;\n\n\t\t// A run's own timeout holds even when the default is disabled (0), so an unrequested background run stays capped\n\t\tconst runTimeout = opts.timeout ?? this.options.gitTimeout ?? 60000;\n\t\tconst runOpts: Mutable<RunOptions> = {\n\t\t\t...opts,\n\t\t\ttimeout: runTimeout === 0 ? undefined : runTimeout,\n\t\t\tencoding: (encoding ?? 'utf8') === 'utf8' ? 'utf8' : 'buffer',\n\t\t\tdecode: this.options.decode,\n\t\t\tenv: this.buildEnv(options.env),\n\t\t\tquiet: errorHandling === 'ignore',\n\t\t\tspawn: this.options.spawn,\n\t\t};\n\n\t\t// A run fed its own stdin or per-call env is never shared: the same argv can answer differently for\n\t\t// each (a temporary index through `GIT_INDEX_FILE`, config injected through `GIT_CONFIG_*`). Nor is one\n\t\t// carrying a retry hook, since the check it makes is that caller's own.\n\t\tconst unshared =\n\t\t\toptions?.stdin != null ||\n\t\t\t(options?.env != null && Object.keys(options.env).length > 0) ||\n\t\t\tbeforeIndexLockRetry != null;\n\t\tconst cacheKey = `${correlationKey !== undefined ? `${correlationKey}:` : ''}${\n\t\t\tunshared ? `${unsharedRunCounter.next()}:` : ''\n\t\t}${cancellation != null ? `${getAbortSignalId(cancellation)}:` : ''}${gitCommand}`;\n\n\t\t// When the subprocess actually started — `start` includes GitQueue wait, which is congestion rather\n\t\t// than anything the repository did. Stays undefined for a dedup rider or a command aborted while queued.\n\t\tlet execStart: ReturnType<typeof hrtime> | undefined;\n\t\t// What the caller's retry hook threw. It is the caller's own failure, so it must reach them as thrown\n\t\t// rather than be classified like a git failure below.\n\t\tlet hookFailure: { error: unknown } | undefined;\n\t\tlet waiting;\n\t\tlet promise: Promise<RunResult<string | Buffer>>;\n\t\tconst pending = this.pendingCommands.get(cacheKey);\n\t\tif (pending == null) {\n\t\t\twaiting = false;\n\n\t\t\t// Create a deferred promise and store it immediately to prevent duplicate commands\n\t\t\t// Note: the cancellation signal is part of the dedup key — calls with different AbortSignals are not deduplicated\n\t\t\tconst deferred = defer<RunResult<string | Buffer>>();\n\t\t\tpromise = deferred.promise;\n\t\t\tconst command: PendingCommand = {\n\t\t\t\tcwd: options.cwd,\n\t\t\t\tpromise: promise,\n\t\t\t\tspawned: false,\n\t\t\t\tspawnListeners: onSpawn != null ? [onSpawn] : [],\n\t\t\t};\n\t\t\tthis.pendingCommands.set(cacheKey, command);\n\n\t\t\t// A write to the index takes `index.lock` and fails at once if another process holds it, so these\n\t\t\t// runs queue behind one another per checkout and retry briefly when something outside still beats\n\t\t\t// them to it. A temporary index (`GIT_INDEX_FILE`) has a lock of its own, so it never joins the order.\n\t\t\tconst writesIndex = isIndexWriteCommand(args);\n\t\t\tconst checkoutKey =\n\t\t\t\twritesIndex && options.cwd != null && runOpts.env?.GIT_INDEX_FILE == null\n\t\t\t\t\t? this.resolveNotifyPath(options.cwd, leadingCommand(args).pathOverride)\n\t\t\t\t\t: undefined;\n\n\t\t\t// Fixes https://github.com/gitkraken/vscode-gitlens/issues/73 & https://github.com/gitkraken/vscode-gitlens/issues/161\n\t\t\t// See https://stackoverflow.com/questions/4144417/how-to-handle-asian-characters-in-file-names-in-git-on-os-x\n\t\t\targs.unshift('-c', 'core.quotepath=false', '-c', 'color.ui=false', ...(configs ?? emptyArray));\n\n\t\t\tif (process.platform === 'win32') {\n\t\t\t\targs.unshift('-c', 'core.longpaths=true');\n\t\t\t}\n\n\t\t\tif (cancellation != null) {\n\t\t\t\trunOpts.cancellation = cancellation;\n\t\t\t}\n\n\t\t\t// Determine command priority:\n\t\t\t// Priority resolution:\n\t\t\t// 1. Explicit priority from options (highest precedence)\n\t\t\t// 2. Inferred from command type (only downgrades expensive commands to Background)\n\t\t\tconst priority = options.priority ?? inferGitCommandPriority(args);\n\n\t\t\t// Execute through the queue (interactive/normal run immediately, background is throttled)\n\t\t\tconst gitPath = await this.path();\n\t\t\tconst spawnQueued = () =>\n\t\t\t\tthis._queue.run(\n\t\t\t\t\tpriority,\n\t\t\t\t\t() => {\n\t\t\t\t\t\texecStart = hrtime();\n\t\t\t\t\t\t// A lock retry spawns again, but the run has already started\n\t\t\t\t\t\tif (!command.spawned) {\n\t\t\t\t\t\t\tcommand.spawned = true;\n\t\t\t\t\t\t\tnotifySpawned(command.spawnListeners.splice(0));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn this._runSpawn<T>(gitPath, args, encoding ?? 'utf8', runOpts);\n\t\t\t\t\t},\n\t\t\t\t\tcancellation,\n\t\t\t\t);\n\t\t\t// The retry wraps the spawn itself, before any `errors` mode turns a failure into a result or a\n\t\t\t// throw, because only the raw `RunError` carries the stderr that says the lock was held. It re-queues\n\t\t\t// each attempt, so waiting between them doesn't hold a queue slot.\n\t\t\t// A config write likewise fails at once on a held `<file>.lock`. Reads never produce that failure, so\n\t\t\t// the retry costs them nothing, and one wrap covers both `errors` modes.\n\t\t\tconst beforeRetry =\n\t\t\t\tbeforeIndexLockRetry != null\n\t\t\t\t\t? async (lockError: Error) => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait beforeIndexLockRetry(lockError);\n\t\t\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t\t\t// The lock error thrown back only declines the retry, leaving the lock failure as the result\n\t\t\t\t\t\t\t\tif (ex !== lockError) {\n\t\t\t\t\t\t\t\t\thookFailure = { error: ex };\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthrow ex;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\t\t\tconst spawnWithRetry = writesIndex\n\t\t\t\t? () => retryWhileIndexLocked(spawnQueued, cancellation, beforeRetry)\n\t\t\t\t: isConfigCommand(args)\n\t\t\t\t\t? () => retryWhileConfigLocked(spawnQueued, cancellation)\n\t\t\t\t\t: spawnQueued;\n\t\t\tvoid (\n\t\t\t\tcheckoutKey != null\n\t\t\t\t\t? this._indexWrites.run(checkoutKey, cancellation, spawnWithRetry)\n\t\t\t\t\t: spawnWithRetry()\n\t\t\t)\n\t\t\t\t.then(deferred.fulfill, (e: unknown) => deferred.cancel(e instanceof Error ? e : new Error(String(e))))\n\t\t\t\t.finally(() => {\n\t\t\t\t\t// A clear may have dropped this run and a later identical call registered its own under the key\n\t\t\t\t\tif (this.pendingCommands.get(cacheKey)?.promise === deferred.promise) {\n\t\t\t\t\t\tthis.pendingCommands.delete(cacheKey);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(() => {});\n\t\t} else {\n\t\t\twaiting = true;\n\t\t\tpromise = pending.promise;\n\t\t\tif (onSpawn != null) {\n\t\t\t\tif (pending.spawned) {\n\t\t\t\t\tnotifySpawned([onSpawn]);\n\t\t\t\t} else {\n\t\t\t\t\tpending.spawnListeners.push(onSpawn);\n\t\t\t\t}\n\t\t\t}\n\t\t\tLogger.trace(`${formatLoggableScopeBlock('GIT')} ${gitCommand} \\u00b7 awaiting existing call...`);\n\t\t}\n\n\t\t// Placed HERE, not at the top of the method — every path from this point flows through the\n\t\t// `finally` below, so the active count can't leak if setup (e.g. locating git) throws.\n\t\tthis.beginActiveCommand();\n\n\t\tlet exception: Error | undefined;\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await promise;\n\t\t\t// A normal `runSpawn` only resolves on a clean exit — `code !== 0 || signal` rejects — but the\n\t\t\t// `exitCodeOnly` overload resolves unconditionally, INCLUDING for a signalled run (no code, partial\n\t\t\t// or absent stdout). Coercing that to `0` would report a killed command as a clean success, so\n\t\t\t// classify it as the failure it is.\n\t\t\tif (result.exitCode == null) {\n\t\t\t\t// SIGTERM groups with cancellations here exactly as it does on the reject path — `failed`/`signal`\n\t\t\t\t// is for every OTHER signal. Only `exitCodeOnly` reaches this: a native spawn `timeout` fires\n\t\t\t\t// `close(null, 'SIGTERM')` with no `error` event, so it resolves instead of rejecting (a caller\n\t\t\t\t// abort never does — `'error'` rejects first). Throwing hands it to the catch below, which owns\n\t\t\t\t// the ABORTED log and the `onAborted` hook — neither of which a branch here would fire.\n\t\t\t\tif (result.signal === 'SIGTERM') {\n\t\t\t\t\tthrow new CancelledRunError(\n\t\t\t\t\t\tgitCommand,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tresult.signal,\n\t\t\t\t\t\tresult.killed ? 'timeout' : 'unknown',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tstdout: result.stdout,\n\t\t\t\t\tstderr: result.stderr,\n\t\t\t\t\tcompletion: {\n\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t\treason: result.signal != null ? 'signal' : 'unstarted',\n\t\t\t\t\t\terror: new Error(\n\t\t\t\t\t\t\t`Command terminated without an exit code${result.signal != null ? ` (${result.signal})` : ''}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tstdout: result.stdout,\n\t\t\t\tstderr: result.stderr,\n\t\t\t\texitCode: result.exitCode,\n\t\t\t\tcompletion: { status: 'exited', code: result.exitCode },\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tif (hookFailure != null) {\n\t\t\t\texception =\n\t\t\t\t\thookFailure.error instanceof Error ? hookFailure.error : new Error(String(hookFailure.error));\n\t\t\t\tif (typeof hookFailure.error === 'object' && hookFailure.error != null) {\n\t\t\t\t\trunHookFailures.add(hookFailure.error);\n\t\t\t\t}\n\n\t\t\t\tthrow hookFailure.error;\n\t\t\t}\n\n\t\t\tif (expectedExitCodes?.length && ex instanceof RunError && !(ex instanceof CancelledRunError)) {\n\t\t\t\tconst code = toExitCode(ex.code);\n\t\t\t\tif (code != null && expectedExitCodes.includes(code)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstdout: ex.stdout,\n\t\t\t\t\t\tstderr: ex.stderr,\n\t\t\t\t\t\texitCode: code,\n\t\t\t\t\t\tcompletion: { status: 'exited', code: code },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet cancellationReason: GitRunCancellation = 'unknown';\n\t\t\tif (ex instanceof CancelledRunError) {\n\t\t\t\tconst duration = getDurationMilliseconds(start);\n\t\t\t\tconst timeout = runOpts.timeout ?? 0;\n\t\t\t\tcancellationReason =\n\t\t\t\t\tex.reason !== 'unknown' ? ex.reason : cancellation?.aborted ? 'aborted' : 'unknown';\n\t\t\t\tconst reason = cancellationReason === 'aborted' ? 'cancellation' : cancellationReason;\n\n\t\t\t\t// A stalled event loop can leave a command looking timed out when it merely never got its exit\n\t\t\t\t// event delivered in time \\u2014 surface the same signal here so it isn't misread as a real timeout.\n\t\t\t\tconst loopDelayAnnotation = this.formatEventLoopDelayAnnotation(startEpochMs);\n\t\t\t\tconst loopDelayText = loopDelayAnnotation != null ? ` \\u00b7 ${loopDelayAnnotation}` : '';\n\n\t\t\t\tLogger.warn(\n\t\t\t\t\t`${formatLoggableScopeBlock('GIT')} ${gitCommand} \\u00b7 ABORTED after ${duration}ms (${reason})${loopDelayText}`,\n\t\t\t\t);\n\t\t\t\tthis.options.hooks?.onAborted?.({\n\t\t\t\t\toperation: gitCommand,\n\t\t\t\t\treason: reason,\n\t\t\t\t\tduration: duration,\n\t\t\t\t\ttimeout: timeout,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (errorHandling === 'ignore') {\n\t\t\t\tif (ex instanceof RunError) {\n\t\t\t\t\tconst code = toExitCode(ex.code);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstdout: ex.stdout,\n\t\t\t\t\t\tstderr: ex.stderr,\n\t\t\t\t\t\t...(code != null ? { exitCode: code } : {}),\n\t\t\t\t\t\tcompletion:\n\t\t\t\t\t\t\tex instanceof CancelledRunError\n\t\t\t\t\t\t\t\t? { status: 'cancelled', reason: cancellationReason, error: ex }\n\t\t\t\t\t\t\t\t: code != null\n\t\t\t\t\t\t\t\t\t? { status: 'exited', code: code }\n\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t\t\t\t\t\t\t// A signal means it ran and was killed (partial `stdout` may exist);\n\t\t\t\t\t\t\t\t\t\t\t// no signal and no numeric code means it never got that far.\n\t\t\t\t\t\t\t\t\t\t\treason: ex.signal != null ? 'signal' : 'unstarted',\n\t\t\t\t\t\t\t\t\t\t\terror: ex,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// No cancellation branch here: `CancelledRunError extends RunError`, so reaching this at all\n\t\t\t\t// proves `ex` is neither.\n\t\t\t\treturn {\n\t\t\t\t\tstdout: '',\n\t\t\t\t\tstderr: undefined,\n\t\t\t\t\tcompletion: {\n\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t\t// No `RunError` means no process was ever spawned — a queue rejection or a\n\t\t\t\t\t\t// failure before `spawn` returned. (Not an untrusted workspace: `run` refuses\n\t\t\t\t\t\t// those up front, so they never reach this catch.)\n\t\t\t\t\t\treason: 'unstarted',\n\t\t\t\t\t\terror: ex instanceof Error ? ex : new Error(String(ex)),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// The queue refuses an already-aborted signal, or drops a command aborted while it waited, by\n\t\t\t// rejecting with the signal's own reason; that never reached a spawn, so it isn't a `RunError`,\n\t\t\t// and wrapping it as a `GitError` would make a cancellation read as the command failing.\n\t\t\tif (ex instanceof CancelledRunError) {\n\t\t\t\texception = new CancellationError(ex, cancellationReason);\n\t\t\t} else if (!(ex instanceof RunError) && cancellation?.aborted) {\n\t\t\t\texception = new CancellationError(ex instanceof Error ? ex : undefined, 'aborted');\n\t\t\t} else {\n\t\t\t\texception = new GitError(ex);\n\t\t\t}\n\t\t\tif (errorHandling === 'throw') throw exception;\n\n\t\t\t// Rethrows unless the message matches a `GitWarnings` pattern, in which case it logs and returns the\n\t\t\t// key that matched. Capture the error first — `exception` is cleared to keep it out of the `finally`\n\t\t\t// log, but the result still needs to carry it.\n\t\t\tconst swallowed = exception;\n\t\t\tconst warning = defaultExceptionHandler(exception, options.cwd, start);\n\t\t\texception = undefined;\n\t\t\t// The command did NOT produce this empty stdout — a warning was swallowed. Say so, or the caller\n\t\t\t// can't tell a genuinely empty answer (`noCommits`) from a read that never happened\n\t\t\t// (`notARepository`).\n\t\t\t//\n\t\t\t// The process DID exit though (a warning is only ever swallowed for a non-zero exit), so report the\n\t\t\t// code.\n\t\t\tconst code = toExitCode(swallowed instanceof GitError ? swallowed.exitCode : undefined);\n\n\t\t\t// No `stderr`: it belongs to the error here. The top-level field is the channel for runs that\n\t\t\t// completed WITHOUT one (`exited` carries no error, so a successful command's stderr has nowhere\n\t\t\t// else to go) — a swallowed warning always has a `GitError`, and it carries the stderr. Reading\n\t\t\t// `result?.stderr` would be dead anyway: `result` is only assigned on the non-throwing path.\n\t\t\treturn {\n\t\t\t\tstdout: '',\n\t\t\t\t...(code != null ? { exitCode: code } : {}),\n\t\t\t\tcompletion: { status: 'warned', warning: warning, error: swallowed },\n\t\t\t};\n\t\t} finally {\n\t\t\tthis.logGitCommandComplete(\n\t\t\t\tgitCommand,\n\t\t\t\texception,\n\t\t\t\tgetDurationMilliseconds(start),\n\t\t\t\t// 0 when the subprocess never started — there is no execution time to attribute. Also 0 for\n\t\t\t\t// GitLens's own maintenance work, which is slow by design and must not read as repo slowness.\n\t\t\t\texecStart == null || selfMaintenance ? 0 : getDurationMilliseconds(execStart),\n\t\t\t\twaiting,\n\t\t\t\toptions.cwd,\n\t\t\t\targs,\n\t\t\t\tslownessCategory,\n\t\t\t\tstartEpochMs,\n\t\t\t);\n\t\t\tthis.endActiveCommand();\n\t\t}\n\t}\n\n\tasync *stream(options: GitSpawnOptions, ...args: readonly (string | undefined)[]): AsyncGenerator<string> {\n\t\tif (this.options.isTrusted?.() === false) throw new WorkspaceUntrustedError();\n\n\t\tconst start = hrtime();\n\t\tconst startEpochMs = Date.now();\n\t\tconst streamId = uniqueCounterForStream.next();\n\n\t\tconst { configs, stdin, stdinEncoding, cancellation, encoding, slownessCategory, cwd, timeout } = options;\n\t\tconst runArgs = args.filter(a => a != null);\n\n\t\tconst spawnOpts: ProcessSpawnOptions = {\n\t\t\t// Unless provided, ignore stdin and leave default streams for stdout and stderr\n\t\t\tstdio: [stdin ? 'pipe' : 'ignore', null, null],\n\t\t\tcwd: cwd,\n\t\t\tenv: this.buildEnv(options.env),\n\t\t\t// 0 disables it, which the spawner contract spells as absent\n\t\t\ttimeout: timeout === 0 ? undefined : timeout,\n\t\t\tsignal: cancellation,\n\t\t};\n\n\t\tconst gitCommand = `(spawn) [${cwd}] git ${runArgs.join(' ')}`;\n\n\t\t// Fixes https://github.com/gitkraken/vscode-gitlens/issues/73 & https://github.com/gitkraken/vscode-gitlens/issues/161\n\t\t// See https://stackoverflow.com/questions/4144417/how-to-handle-asian-characters-in-file-names-in-git-on-os-x\n\t\trunArgs.unshift('-c', 'core.quotepath=false', '-c', 'color.ui=false', ...(configs ?? emptyArray));\n\n\t\tif (process.platform === 'win32') {\n\t\t\trunArgs.unshift('-c', 'core.longpaths=true');\n\t\t}\n\n\t\tconst command = await this.path();\n\t\tconst proc = (this.options.spawn ?? spawn)(command, runArgs, spawnOpts);\n\n\t\tif (stdin) {\n\t\t\tendStdin(proc.stdin, stdin, stdinEncoding);\n\t\t}\n\n\t\tlet exception: Error | undefined;\n\n\t\tconst promise = new Promise<void>((resolve, reject) => {\n\t\t\tconst stderrChunks: string[] = [];\n\t\t\tif (proc.stderr) {\n\t\t\t\tproc.stderr?.setEncoding('utf8');\n\t\t\t\tproc.stderr.on('data', chunk => stderrChunks.push(chunk));\n\t\t\t}\n\n\t\t\tproc.once('error', ex => {\n\t\t\t\tif (ex?.name === 'AbortError') return;\n\n\t\t\t\texception = new GitError(ex);\n\t\t\t});\n\t\t\tproc.once('close', (code, signal) => {\n\t\t\t\tif (code === 0) {\n\t\t\t\t\tresolve();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (signal === 'SIGTERM') {\n\t\t\t\t\t// If the caller aborted, just resolve\n\t\t\t\t\tif (cancellation?.aborted) {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t} else {\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew CancelledRunError(\n\t\t\t\t\t\t\t\tproc.spawnargs.join(' '),\n\t\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t\tcode ?? undefined,\n\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t\tproc.killed ? 'timeout' : 'unknown',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If the caller didn't read the complete stream, just resolve\n\t\t\t\tif (\n\t\t\t\t\tsignal === 'SIGPIPE' ||\n\t\t\t\t\tcode === 141 /* SIGPIPE */ ||\n\t\t\t\t\t(code === 128 && stderrChunks.some(c => c.includes('Connection reset by peer')))\n\t\t\t\t) {\n\t\t\t\t\tresolve();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst stderr = stderrChunks.join('').trim();\n\t\t\t\treject(\n\t\t\t\t\tnew GitError(\n\t\t\t\t\t\tnew RunError(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmessage: `Error (${code}): ${stderr || 'Unknown'}`,\n\t\t\t\t\t\t\t\tcmd: proc.spawnargs.join(' '),\n\t\t\t\t\t\t\t\tkilled: proc.killed,\n\t\t\t\t\t\t\t\tcode: proc.exitCode,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'',\n\t\t\t\t\t\t\tstderr,\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t});\n\t\t});\n\n\t\tlet cleanedUp = false;\n\t\tconst cleanup = () => {\n\t\t\tif (cleanedUp) return;\n\n\t\t\tcleanedUp = true;\n\n\t\t\ttry {\n\t\t\t\tproc.removeAllListeners();\n\t\t\t} catch {}\n\t\t\t// Streaming spawns directly, with no GitQueue wait to exclude. It isn't pure subprocess time\n\t\t\t// either — the generator applies backpressure, so a slow consumer stalls the pipe and inflates\n\t\t\t// this — but there's no separate signal to measure here.\n\t\t\tconst duration = getDurationMilliseconds(start);\n\t\t\tthis.logGitCommandComplete(\n\t\t\t\tgitCommand,\n\t\t\t\texception,\n\t\t\t\tduration,\n\t\t\t\tduration,\n\t\t\t\tfalse,\n\t\t\t\tcwd,\n\t\t\t\trunArgs,\n\t\t\t\tslownessCategory,\n\t\t\t\tstartEpochMs,\n\t\t\t\tstreamId,\n\t\t\t);\n\t\t\tthis.endActiveCommand();\n\t\t};\n\n\t\t// Placed HERE, not at the top of the method — every path from this point reaches `cleanup()`\n\t\t// (the `finally` below, or the generator-close return), so the active count can't leak if\n\t\t// setup (e.g. locating git) throws.\n\t\tthis.beginActiveCommand();\n\n\t\ttry {\n\t\t\tthis.logGitCommandStart(gitCommand, streamId);\n\n\t\t\ttry {\n\t\t\t\t// Only a host spawner can leave it out; reading no output as empty would pass for a clean answer\n\t\t\t\tif (proc.stdout == null) throw new Error(`'${command}' was spawned without a stdout pipe`);\n\n\t\t\t\tconst enc = encoding ?? 'utf8';\n\t\t\t\tif (enc === 'utf8' || enc === 'binary' || enc === 'buffer') {\n\t\t\t\t\tproc.stdout.setEncoding(enc === 'buffer' ? 'utf8' : enc);\n\t\t\t\t\tfor await (const chunk of proc.stdout) {\n\t\t\t\t\t\tyield chunk;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Non-UTF-8 encoding: collect raw buffers and decode at the end.\n\t\t\t\t\t// Streaming decode is unsafe because chunk boundaries can split\n\t\t\t\t\t// multi-byte sequences in the source encoding.\n\t\t\t\t\tconst decode = this.options.decode;\n\t\t\t\t\tif (decode == null) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Non-UTF-8 encoding '${enc}' requested for stream but no decode function configured`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst buffers: Buffer[] = [];\n\t\t\t\t\tfor await (const chunk of proc.stdout) {\n\t\t\t\t\t\tbuffers.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n\t\t\t\t\t}\n\t\t\t\t\tyield await decode(Buffer.concat(buffers), { encoding: enc });\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// This await MUST be in this inner finally block to ensure the child process close event completes\n\t\t\t\t// before we call removeAllListeners() in the outer finally. When consumers break early from the\n\t\t\t\t// async generator (e.g., reading only the first chunk), the git process receives SIGPIPE and triggers\n\t\t\t\t// the close handler asynchronously. Without awaiting here, removeAllListeners() would execute before\n\t\t\t\t// the close handler finishes, causing a race condition and potential resource leaks.\n\t\t\t\tawait promise;\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\texception = ex;\n\t\t\tthrow ex;\n\t\t} finally {\n\t\t\tcleanup();\n\t\t}\n\n\t\t// Ensure cleanup happens immediately when the generator is explicitly closed (e.g., via break or return)\n\t\t// This is called by JavaScript when the generator is abandoned, ensuring logGitCommand is called\n\t\t// synchronously rather than waiting for garbage collection.\n\t\t// oxlint-disable-next-line typescript/no-meaningless-void-operator\n\t\treturn void cleanup();\n\t}\n\n\t/**\n\t * Resolves the git dir (and common dir, for a linked worktree) of `cwd`.\n\t *\n\t * Resolves `undefined` when `cwd` is not in a repository: git reported so, or `cwd` doesn't exist. Any\n\t * other failure (unsafe ownership, a timeout or cancellation, a missing git binary) rejects.\n\t */\n\tasync rev_parse__git_dir(cwd: string): Promise<{ path: string; commonPath?: string } | undefined> {\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await this.run({ cwd: cwd, errors: 'throw' }, 'rev-parse', '--git-dir', '--git-common-dir');\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof GitError && GitWarnings.notARepository.test(ex.stderr ?? '')) return undefined;\n\t\t\t// A missing `cwd` fails the spawn itself (ENOENT) before git can say anything about it\n\t\t\tif (!(await fsExists(cwd))) return undefined;\n\t\t\tthrow ex;\n\t\t}\n\t\tif (!result.stdout) return undefined;\n\n\t\t// Keep trailing spaces which are part of the directory name\n\t\tlet [dotGitPath, commonDotGitPath] = result.stdout.split('\\n').map(r => r.trimStart());\n\n\t\t// Make sure to normalize: https://github.com/git-for-windows/git/issues/2478\n\n\t\tif (!isAbsolute(dotGitPath)) {\n\t\t\tdotGitPath = joinPaths(cwd, dotGitPath);\n\t\t}\n\t\tdotGitPath = normalizePath(dotGitPath);\n\n\t\tif (commonDotGitPath) {\n\t\t\tif (!isAbsolute(commonDotGitPath)) {\n\t\t\t\tcommonDotGitPath = joinPaths(cwd, commonDotGitPath);\n\t\t\t}\n\t\t\tcommonDotGitPath = normalizePath(commonDotGitPath);\n\n\t\t\treturn { path: dotGitPath, commonPath: commonDotGitPath !== dotGitPath ? commonDotGitPath : undefined };\n\t\t}\n\n\t\treturn { path: dotGitPath };\n\t}\n\n\tasync rev_parse__show_toplevel(cwd: string): Promise<[safe: true, repoPath: string] | [safe: false] | []> {\n\t\tlet result;\n\n\t\tif (this.options.isTrusted?.() === false) {\n\t\t\t// Check if the folder is a bare clone: if it has a file named HEAD && `rev-parse --show-cdup` is empty\n\t\t\tif (await fsExists(joinPaths(cwd, 'HEAD'))) {\n\t\t\t\ttry {\n\t\t\t\t\tresult = await this.run(\n\t\t\t\t\t\t{ cwd: cwd, errors: 'throw', configs: ['-C', cwd] },\n\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t'--show-cdup',\n\t\t\t\t\t);\n\t\t\t\t\tif (!result.stdout.trim()) {\n\t\t\t\t\t\tLogger.warn(`Skipping (untrusted workspace); bare clone repository detected in '${cwd}'`);\n\t\t\t\t\t\treturn emptyArray as [];\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// If this throws, we should be good to open the repo (e.g. HEAD doesn't exist)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tresult = await this.run({ cwd: cwd, errors: 'throw' }, 'rev-parse', '--show-toplevel');\n\t\t\t// Make sure to normalize: https://github.com/git-for-windows/git/issues/2478\n\t\t\t// Keep trailing spaces which are part of the directory name\n\t\t\treturn !result.stdout\n\t\t\t\t? (emptyArray as [])\n\t\t\t\t: [true, normalizePath(result.stdout.trimStart().replace(trailingNewlineRegex, ''))];\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof WorkspaceUntrustedError) return emptyArray as [];\n\t\t\tif (!(ex instanceof GitError)) throw ex;\n\n\t\t\tconst unsafeMatch = GitErrors.unsafeRepository.exec(ex.stderr ?? '');\n\t\t\tif (unsafeMatch != null) {\n\t\t\t\tLogger.warn(\n\t\t\t\t\t`Skipping; unsafe repository detected in '${unsafeMatch[1] || unsafeMatch[2]}'; run '${\n\t\t\t\t\t\tunsafeMatch[3]\n\t\t\t\t\t}' to allow it`,\n\t\t\t\t);\n\t\t\t\treturn [false];\n\t\t\t}\n\n\t\t\tconst inDotGit = GitWarnings.mustRunInWorkTree.test(ex.stderr ?? '');\n\t\t\t// Check if we are in a bare clone\n\t\t\tif (inDotGit && this.options.isTrusted?.() !== false) {\n\t\t\t\tresult = await this.run({ cwd: cwd, errors: 'ignore' }, 'rev-parse', '--is-bare-repository');\n\t\t\t\tif (result.stdout.trim() === 'true') {\n\t\t\t\t\tconst result = await this.rev_parse__git_dir(cwd).catch(() => undefined);\n\t\t\t\t\tconst repoPath = result?.commonPath ?? result?.path;\n\t\t\t\t\tif (repoPath?.length) return [true, repoPath];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (inDotGit || (ex.original as NodeJS.ErrnoException)?.code === 'ENOENT') {\n\t\t\t\t// If the `cwd` doesn't exist, walk backward to see if any parent folder exists\n\t\t\t\tlet exists = inDotGit ? false : await fsExists(cwd);\n\t\t\t\tif (!exists) {\n\t\t\t\t\tdo {\n\t\t\t\t\t\tconst parent = dirname(cwd);\n\t\t\t\t\t\tif (parent === cwd || parent.length === 0) return emptyArray as [];\n\n\t\t\t\t\t\tcwd = parent;\n\t\t\t\t\t\texists = await fsExists(cwd);\n\t\t\t\t\t} while (!exists);\n\n\t\t\t\t\treturn this.rev_parse__show_toplevel(cwd);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn emptyArray as [];\n\t\t}\n\t}\n\n\tprivate logGitCommandStart(command: string, id: number): void {\n\t\tLogger.info(`${formatLoggableScopeBlock(`GIT:\\u2192${id}`)} ${command} \\u00b7 starting...`);\n\t\tthis.options.logger?.info(`${formatLoggableScopeBlock(`\\u2192${id}`, '')} ${command} \\u2022 starting...`);\n\t}\n\n\tprivate logGitCommandComplete(\n\t\tcommand: string,\n\t\tex: Error | undefined,\n\t\tduration: number,\n\t\t/** Subprocess-only duration (excludes GitQueue wait); 0 when it never ran. */\n\t\texecDuration: number,\n\t\twaiting: boolean,\n\t\tcwd: string | undefined,\n\t\targs: readonly (string | undefined)[] | undefined,\n\t\tslownessCategory: GitHealthSlownessCategory | undefined,\n\t\tstartEpochMs: number,\n\t\tid?: number,\n\t): void {\n\t\tconst slow = duration > slowCallWarningThreshold;\n\n\t\tconst annotations: string[] = [];\n\t\tif (slow) {\n\t\t\tannotations.push('slow');\n\t\t}\n\n\t\tif (waiting) {\n\t\t\tannotations.push('waiting');\n\t\t} else if (execDuration > 0) {\n\t\t\t// Dedup riders (`waiting`) and never-started commands (`execDuration === 0`) have no queue\n\t\t\t// wait of their own to report.\n\t\t\tconst queued = duration - execDuration;\n\t\t\tif (queued >= queueWaitAnnotationThreshold) {\n\t\t\t\tannotations.push(`queued ${queued}ms`);\n\t\t\t}\n\t\t}\n\n\t\t// `hrtime` spans don't correlate with the monitor's wall-clock ring, so the lookup needs the\n\t\t// command's own start time — only worth measuring once the command is already slow. Whole-call\n\t\t// window on purpose: the annotation explains the TOTAL duration this log line reports.\n\t\tif (slow) {\n\t\t\tconst loopDelayAnnotation = this.formatEventLoopDelayAnnotation(startEpochMs);\n\t\t\tif (loopDelayAnnotation != null) {\n\t\t\t\tannotations.push(loopDelayAnnotation);\n\t\t\t}\n\t\t}\n\n\t\tconst status = annotations.length > 0 ? ` (${annotations.join(', ')})` : '';\n\n\t\t// The health signal is gated on the SUBPROCESS time, not the total: time spent queued behind other\n\t\t// git work is congestion, not repository slowness, and counting it would let a busy queue (including\n\t\t// our own background maintenance holding slots) manufacture the evidence that recommends more\n\t\t// maintenance. Logging keeps the total — the wait is exactly what you want to see when diagnosing.\n\t\t//\n\t\t// A deduplicated rider (`waiting`) shares the executed command's duration, so counting it too\n\t\t// would double-count a single slow subprocess — fire only for the command that actually ran.\n\t\t// Guarded: this runs inside the command's `finally`, so a hook throw would otherwise replace\n\t\t// the command's real result/error for the caller.\n\t\tif (execDuration > slowCallWarningThreshold && !waiting) {\n\t\t\t// Scoped to the SUBPROCESS window, matching the hook's `duration`: `duration - execDuration`\n\t\t\t// is the queue wait, and a stall while queued is congestion, not the command's own signal\n\t\t\t// (same reasoning as the `execDuration` gate above). The subprocess ends at log time, so it\n\t\t\t// started `duration - execDuration` after the call did.\n\t\t\tconst execEventLoopDelay = this._eventLoopMonitor.maxDelaySince(startEpochMs + (duration - execDuration));\n\t\t\ttry {\n\t\t\t\tthis.options.hooks?.onSlowCommand?.({\n\t\t\t\t\toperation: args != null ? getPrimaryGitCommand(args) : undefined,\n\t\t\t\t\tcwd: cwd,\n\t\t\t\t\tduration: execDuration,\n\t\t\t\t\teventLoopDelay: execEventLoopDelay,\n\t\t\t\t\tslownessCategory: slownessCategory,\n\t\t\t\t});\n\t\t\t} catch {}\n\t\t}\n\n\t\tif (ex != null) {\n\t\t\tLogger.error(\n\t\t\t\tundefined,\n\t\t\t\t`${formatLoggableScopeBlock(id ? `GIT:\\u2190${id}` : 'GIT')} ${command} \\u00b7 ${\n\t\t\t\t\tisCancellationError(ex)\n\t\t\t\t\t\t? 'cancelled'\n\t\t\t\t\t\t: (ex.message || String(ex) || '')\n\t\t\t\t\t\t\t\t.trim()\n\t\t\t\t\t\t\t\t.replace(/fatal:\\s*/g, '')\n\t\t\t\t\t\t\t\t.replace(/\\r?\\n|\\r/g, ' \\u00b7 ')\n\t\t\t\t} [${duration}ms]${status}`,\n\t\t\t);\n\t\t} else if (slow) {\n\t\t\tLogger.warn(\n\t\t\t\t`${formatLoggableScopeBlock(id ? `GIT:\\u2190${id}` : 'GIT', `*${duration}ms`)} ${command} [*${duration}ms]${status}`,\n\t\t\t);\n\t\t} else {\n\t\t\tLogger.info(\n\t\t\t\t`${formatLoggableScopeBlock(id ? `GIT:\\u2190${id}` : 'GIT', `${duration}ms`)} ${command} [${duration}ms]${status}`,\n\t\t\t);\n\t\t}\n\n\t\tconst logMessage = `${formatLoggableScopeBlock(\n\t\t\t`${id ? `\\u2190${id}` : ''}${slow ? '*' : ''}`,\n\t\t\t`${duration}ms`,\n\t\t)} ${command}${status}`;\n\t\tif (ex != null) {\n\t\t\tthis.options.logger?.error(`${logMessage} \\u2022 FAILED\\n${String(ex)}`);\n\t\t} else {\n\t\t\tthis.options.logger?.info(`${logMessage} \\u2022 completed`);\n\t\t}\n\t}\n}\n\n/**\n * Swallows an error whose message matches a known-benign {@link GitWarnings} pattern, returning WHICH one\n * matched so the caller can record it — the distinction matters, since `noCommits` is a real answer while\n * `notARepository` is a failed read. Rethrows anything else.\n */\nexport function defaultExceptionHandler(\n\tex: Error,\n\tcwd: string | undefined,\n\tstart?: [number, number],\n): GitWarningKey | undefined {\n\tif (isCancellationError(ex)) throw ex;\n\n\tconst msg = ex.message || ex.toString();\n\tif (msg) {\n\t\tconst warning = getGitWarning(ex);\n\t\tif (warning != null) {\n\t\t\tconst duration = start !== undefined ? ` [${getDurationMilliseconds(start)}ms]` : '';\n\t\t\tLogger.warn(\n\t\t\t\t`[${cwd}] Git ${msg\n\t\t\t\t\t.trim()\n\t\t\t\t\t.replace(/fatal:\\s*/g, '')\n\t\t\t\t\t.replace(/\\r?\\n|\\r/g, ' \\u00b7 ')}${duration}`,\n\t\t\t);\n\t\t\treturn warning;\n\t\t}\n\n\t\tconst match = GitErrors.badRevision.exec(msg);\n\t\tif (match != null) {\n\t\t\tconst [, ref] = match;\n\n\t\t\t// Since looking up a ref with ^3 (e.g. looking for untracked files in a stash) can error on some versions of git just ignore it\n\t\t\t// Swallowed, but it matched no `GitWarnings` entry — `undefined` records \"unclassified\", which\n\t\t\t// callers must treat as \"not a real answer\" exactly like any warning they don't whitelist.\n\t\t\tif (ref?.endsWith('^3')) return undefined;\n\t\t}\n\t}\n\n\tthrow ex;\n}\n"],"mappings":"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"}
|
|
@@ -82,7 +82,7 @@ export declare class ConfigGitSubProvider implements GitConfigSubProvider {
|
|
|
82
82
|
private readonly _gkConfigReconciles;
|
|
83
83
|
/**
|
|
84
84
|
* The latest pending `setGkConfig` write of each `commonPath\0key`. A call writing the same value with the same
|
|
85
|
-
*
|
|
85
|
+
* invalidation and error options joins it; any other call chains after it, so one key's writes land in call order. Cleared on settle.
|
|
86
86
|
*/
|
|
87
87
|
private readonly _pendingGkConfigWrites;
|
|
88
88
|
/** Writes each `.git/gk/config` one at a time — concurrent `git config` writes fail on its lock */
|
|
@@ -127,7 +127,10 @@ export declare class ConfigGitSubProvider implements GitConfigSubProvider {
|
|
|
127
127
|
* Uses commonPath for worktrees so all worktrees share the same data.
|
|
128
128
|
*/
|
|
129
129
|
private getGkConfigPath;
|
|
130
|
-
getGkConfig(repoPath: string, key: GkConfigKeys | DeprecatedGkConfigKeys
|
|
130
|
+
getGkConfig(repoPath: string, key: GkConfigKeys | DeprecatedGkConfigKeys, options?: {
|
|
131
|
+
throwOnError?: boolean;
|
|
132
|
+
}): Promise<string | undefined>;
|
|
133
|
+
private getGkConfigStrict;
|
|
131
134
|
getGkConfigRegex(repoPath: string, pattern: string): Promise<Map<string, string>>;
|
|
132
135
|
/**
|
|
133
136
|
* Reads the entire `.git/gk/config` in one `git config --get-regexp` and caches the parsed map
|
|
@@ -147,6 +150,7 @@ export declare class ConfigGitSubProvider implements GitConfigSubProvider {
|
|
|
147
150
|
private getGkConfigRegexCore;
|
|
148
151
|
setGkConfig(repoPath: string, key: GkConfigKeys | DeprecatedGkConfigKeys, value: string | undefined, options?: {
|
|
149
152
|
skipInvalidation?: readonly GkConfigInvalidationTarget[];
|
|
153
|
+
throwOnError?: boolean;
|
|
150
154
|
}): Promise<void>;
|
|
151
155
|
private setGkConfigCore;
|
|
152
156
|
removeGkConfigBranchSection(repoPath: string, ref: string): Promise<void>;
|