@gitkraken/core-gitlens 0.9.5 → 0.9.7
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 +19 -1
- package/dist/git/cache.d.ts +8 -0
- package/dist/git/cache.js +14 -0
- package/dist/git/cache.js.map +1 -1
- package/dist/git/features.d.ts +1 -1
- package/dist/git/features.js +2 -0
- package/dist/git/features.js.map +1 -1
- package/dist/git/models/pullRequest.d.ts +7 -2
- package/dist/git/models/pullRequest.js.map +1 -1
- package/dist/git/providers/commits.d.ts +36 -0
- package/dist/git-cli/exec/exec.d.ts +2 -2
- package/dist/git-cli/exec/exec.js +2 -2
- package/dist/git-cli/exec/git.js +2 -2
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/providers/commits.d.ts +30 -0
- package/dist/git-cli/providers/commits.js +203 -0
- package/dist/git-cli/providers/commits.js.map +1 -1
- package/dist/plus/integrations/providers/models.js +1 -1
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/utils/env/node/exec.d.ts +8 -0
- package/dist/utils/env/node/exec.js +15 -6
- package/dist/utils/env/node/exec.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commits.js","names":["chunk","chunkArray"],"sources":["../../../../git-cli/src/providers/commits.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { SigningError } from '@gitlens/git/errors.js';\nimport type { GitBlame } from '@gitlens/git/models/blame.js';\nimport type { GitStashCommit } from '@gitlens/git/models/commit.js';\nimport { GitCommit, GitCommitIdentity } from '@gitlens/git/models/commit.js';\nimport type { GitDiffFilter, ParsedGitDiffHunks } from '@gitlens/git/models/diff.js';\nimport { GitFileChange } from '@gitlens/git/models/fileChange.js';\nimport type { GitFileStatus } from '@gitlens/git/models/fileStatus.js';\nimport type { GitLog } from '@gitlens/git/models/log.js';\nimport type { GitReflog } from '@gitlens/git/models/reflog.js';\nimport type { GitRevisionRange } from '@gitlens/git/models/revision.js';\nimport type { SearchQuery, SearchQueryFilters } from '@gitlens/git/models/search.js';\nimport type { CommitSignature, SigningFormat, SshSignedCommit } from '@gitlens/git/models/signature.js';\nimport type { GitUser } from '@gitlens/git/models/user.js';\nimport type {\n\tGitCommitReachability,\n\tGitCommitsSubProvider,\n\tGitLogForPathOptions,\n\tGitLogOptions,\n\tGitLogShasOptions,\n\tGitRefExclusions,\n\tGitSearchCommitsOptions,\n\tIncomingActivityOptions,\n\tLeftRightCommitCountResult,\n\tSearchCommitsResult,\n} from '@gitlens/git/providers/commits.js';\nimport type { DiffRange } from '@gitlens/git/providers/types.js';\nimport type { GitCommandPriority } from '@gitlens/git/run.types.js';\nimport { createUncommittedChangesCommit } from '@gitlens/git/utils/commit.utils.js';\nimport { isRevisionRange, isSha, isUncommitted, isUncommittedStaged } from '@gitlens/git/utils/revision.utils.js';\nimport { parseSearchQueryGitCommand } from '@gitlens/git/utils/search.utils.js';\nimport { compareReachableRefs } from '@gitlens/git/utils/sorting.js';\nimport { isUserMatch } from '@gitlens/git/utils/user.utils.js';\nimport { chunk as chunkArray } from '@gitlens/utils/array.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { debug, trace } from '@gitlens/utils/decorators/log.js';\nimport { createDisposable } from '@gitlens/utils/disposable.js';\nimport { filterMap, findLast, first, join, last, some } from '@gitlens/utils/iterable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { isFolderGlob, normalizePath, splitPath, stripFolderGlob } from '@gitlens/utils/path.js';\nimport type { CacheController } from '@gitlens/utils/promiseCache.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport { escapeRegex, iterateByDelimiter } from '@gitlens/utils/string.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fileUri, joinUriPath, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult, GitRunOptions } from '../exec/exec.types.js';\nimport type { Git, GitError } from '../exec/git.js';\nimport { classifySigningError, gitConfigsLog, gitConfigsLogWithFiles, GitErrors } from '../exec/git.js';\nimport type {\n\tCommitsInFileRangeLogParser,\n\tCommitsLogParser,\n\tCommitsWithFilesLogParser,\n\tParsedCommit,\n} from '../parsers/logParser.js';\nimport {\n\tgetCommitsLogParser,\n\tgetShaAndDatesLogParser,\n\tgetShaAndFilesAndStatsLogParser,\n\tgetShaLogParser,\n} from '../parsers/logParser.js';\nimport { getReflogParser, parseGitRefLog } from '../parsers/reflogParser.js';\nimport { parseSignatureOutput, signatureFormat } from '../parsers/signatureParser.js';\nimport {\n\textractCommitterFromCommitObject,\n\textractSshPublicKeyFromCommitObject,\n} from '../parsers/sshSignatureParser.js';\nimport { createCommitFileset } from './commitFilesetUtils.js';\nimport { convertStashesToStdin } from './stash.js';\n\nconst emptyPromise: Promise<GitBlame | ParsedGitDiffHunks | GitLog | undefined> = Promise.resolve(undefined);\nconst reflogCommands = ['merge', 'pull'];\n/** Keeps `filterUnpublishedShas` well inside Windows' ~32K command-line cap (40 hex chars + separator each). */\nconst maxShasPerRevListSpawn = 500;\n\nconst refExclusionNamespaces = [\n\t['branches', 'refs/heads/', '--branches'],\n\t['remotes', 'refs/remotes/', '--remotes'],\n\t['tags', 'refs/tags/', '--tags'],\n] as const;\n\n/**\n * Each `except` entry is emitted in its short form right before its own namespace's pseudo-ref: git matches\n * `--exclude` against the short name and applies it only to the next pseudo-ref, so `--exclude=refs/heads/x\n * --branches` excludes nothing.\n */\nfunction getRefExclusionArgs(excluding: GitRefExclusions | undefined): string[] {\n\tif (excluding == null) return [];\n\n\tconst args: string[] = [];\n\tfor (const [key, prefix, flag] of refExclusionNamespaces) {\n\t\tif (!excluding[key]) continue;\n\n\t\tfor (const ref of excluding.except ?? []) {\n\t\t\tif (ref.startsWith(prefix)) {\n\t\t\t\targs.push(`--exclude=${ref.slice(prefix.length)}`);\n\t\t\t}\n\t\t}\n\t\targs.push(flag);\n\t}\n\n\tif (excluding.refs?.length) {\n\t\targs.push(...excluding.refs);\n\t}\n\n\treturn args.length ? ['--not', ...args] : [];\n}\n\nfunction getRefExclusionsKey(excluding: GitRefExclusions): string {\n\tconst { branches, remotes, tags, refs, except } = excluding;\n\treturn JSON.stringify([branches, remotes, tags, refs, except]);\n}\n\nfunction getCommitCountKey(rev: string, excluding: GitRefExclusions | undefined): string {\n\tif (excluding == null) return rev;\n\n\treturn `${rev}\\0${getRefExclusionsKey(excluding)}`;\n}\n\nexport class CommitsGitSubProvider implements GitCommitsSubProvider {\n\tconstructor(\n\t\tprivate readonly context: GitServiceContext,\n\t\tprivate readonly git: Git,\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: CliGitProviderInternal,\n\t) {}\n\n\t/**\n\t * Creates a commit object from a tree via `commit-tree`, with explicit (zero or more) parents and an\n\t * optional explicit author/committer — e.g. for merge commits assembled from multiple parents, or a\n\t * commit authored on behalf of someone else. Writes the commit object only; it updates no ref, so the\n\t * result is unreachable until a caller points a branch/ref at it. Fires no ref-change hooks — an\n\t * unreachable object changes no ref, so there's nothing for a cache or watcher to invalidate yet.\n\t */\n\t@debug()\n\tasync createCommitFromTree(\n\t\trepoPath: string,\n\t\ttree: string,\n\t\toptions: {\n\t\t\tparents: string[];\n\t\t\tmessage: string;\n\t\t\tauthor?: { name: string; email: string; date?: Date | string };\n\t\t\tcommitter?: { name: string; email: string; date?: Date | string };\n\t\t\tsign?: boolean;\n\t\t\tsource?: unknown;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<string> {\n\t\tconst args = ['commit-tree', tree];\n\t\tfor (const parent of options.parents) {\n\t\t\targs.push('-p', parent);\n\t\t}\n\n\t\tlet format: SigningFormat = 'gpg';\n\t\tif (options.sign) {\n\t\t\tconst signingConfig = await this.provider.config.getSigningConfig?.(repoPath);\n\t\t\tformat = signingConfig?.format ?? 'gpg';\n\t\t\targs.push('-S');\n\t\t}\n\t\targs.push('-F', '-');\n\n\t\tconst env: Record<string, string> = {};\n\t\tif (options.author) {\n\t\t\tenv.GIT_AUTHOR_NAME = options.author.name;\n\t\t\tenv.GIT_AUTHOR_EMAIL = options.author.email;\n\t\t\tif (options.author.date != null) {\n\t\t\t\tenv.GIT_AUTHOR_DATE =\n\t\t\t\t\ttypeof options.author.date === 'string' ? options.author.date : options.author.date.toISOString();\n\t\t\t}\n\t\t}\n\t\tif (options.committer) {\n\t\t\tenv.GIT_COMMITTER_NAME = options.committer.name;\n\t\t\tenv.GIT_COMMITTER_EMAIL = options.committer.email;\n\t\t\tif (options.committer.date != null) {\n\t\t\t\tenv.GIT_COMMITTER_DATE =\n\t\t\t\t\ttypeof options.committer.date === 'string'\n\t\t\t\t\t\t? options.committer.date\n\t\t\t\t\t\t: options.committer.date.toISOString();\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\terrors: 'throw',\n\t\t\t\t\tenv: env,\n\t\t\t\t\t// `-F -` stores the message byte-for-byte, where `-m` terminates it with a newline —\n\t\t\t\t\t// keep that, or the same inputs write a different commit object.\n\t\t\t\t\tstdin:\n\t\t\t\t\t\t!options.message || options.message.endsWith('\\n') ? options.message : `${options.message}\\n`,\n\t\t\t\t\tstdinEncoding: 'utf8',\n\t\t\t\t},\n\t\t\t\t...args,\n\t\t\t);\n\t\t\tconst sha = result.stdout.trim();\n\n\t\t\tif (options.sign) {\n\t\t\t\tthis.context.hooks?.commits?.onSigned?.(format, options.source);\n\t\t\t}\n\n\t\t\treturn sha;\n\t\t} catch (ex) {\n\t\t\tif (options.sign) {\n\t\t\t\tconst reason = classifySigningError(ex);\n\t\t\t\tif (reason != null) {\n\t\t\t\t\tthis.context.hooks?.commits?.onSigningFailed?.(reason, format, options.source);\n\t\t\t\t\tthrow new SigningError(\n\t\t\t\t\t\t{ reason: reason, gitCommand: { repoPath: repoPath, args: ['commit-tree'] } },\n\t\t\t\t\t\tex as GitError,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getCommit(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<GitCommit | undefined> {\n\t\tif (isUncommitted(rev, true)) {\n\t\t\treturn createUncommittedChangesCommit(\n\t\t\t\trepoPath,\n\t\t\t\trev,\n\t\t\t\tnew Date(),\n\t\t\t\tawait this.provider.config.getCurrentUser(repoPath),\n\t\t\t);\n\t\t}\n\n\t\tconst log = await this.getLogCore(repoPath, rev, { limit: 1 }, cancellation);\n\t\tif (log == null) return undefined;\n\n\t\treturn log.commits.get(rev) ?? first(log.commits.values());\n\t}\n\n\t@debug({ exit: true })\n\tgetCommitCount(\n\t\trepoPath: string,\n\t\trev: string,\n\t\toptions?: { excluding?: GitRefExclusions },\n\t\tcancellation?: AbortSignal,\n\t): Promise<number | undefined> {\n\t\tconst excludeArgs = getRefExclusionArgs(options?.excluding);\n\n\t\treturn this.cache.commitCount.getOrCreate(\n\t\t\trepoPath,\n\t\t\tgetCommitCountKey(rev, options?.excluding),\n\t\t\tasync (cacheable, signal) => {\n\t\t\t\t// Bind the shared spawn to the aggregate `signal` (fires only when ALL current callers\n\t\t\t\t// abort), not this-caller's `cancellation` — otherwise a superseded caller's abort would\n\t\t\t\t// kill the shared command and reject concurrent riders that never cancelled.\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: signal ?? cancellation, errors: 'ignore' },\n\t\t\t\t\t'rev-list',\n\t\t\t\t\t'--count',\n\t\t\t\t\trev,\n\t\t\t\t\t...excludeArgs,\n\t\t\t\t\t'--',\n\t\t\t\t);\n\t\t\t\tif (result.completion.status === 'cancelled' || signal?.aborted) {\n\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t}\n\n\t\t\t\t// `errors: 'ignore'` turns a failed run (unknown rev, a transient `index.lock`) into an\n\t\t\t\t// empty stdout rather than a throw. That's indistinguishable from a real answer here, so\n\t\t\t\t// don't let it become a cached one — this entry has a sliding hour-long TTL, and repeated\n\t\t\t\t// access would keep a transient failure alive indefinitely. The pre-cache implementation\n\t\t\t\t// simply retried on the next call; invalidating restores that.\n\t\t\t\t//\n\t\t\t\t// BOTH conditions, not either alone. `exitCode !== 0` catches \"git ran and said no\" (a bad\n\t\t\t\t// rev exits 128); `status !== 'exited'` catches \"git never answered\" — a queue rejection or\n\t\t\t\t// spawn failure (no exit code at all), or a swallowed `GitWarnings` match, which carries git's\n\t\t\t\t// real code and so can slip past the exit-code test on its own.\n\t\t\t\tif (result.completion.status !== 'exited' || result.exitCode !== 0) {\n\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tconst data = result.stdout.trim();\n\t\t\t\tif (!data) return undefined;\n\n\t\t\t\tconst count = parseInt(data, 10);\n\t\t\t\treturn isNaN(count) ? undefined : count;\n\t\t\t},\n\t\t\t{ cancellation: cancellation },\n\t\t);\n\t}\n\n\t@debug({ exit: true })\n\tasync hasUnpublishedCommits(\n\t\trepoPath: string,\n\t\trev: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean | undefined> {\n\t\t// `<rev> --not --remotes` = commits reachable from `rev` but not from any remote-tracking ref.\n\t\t// `--max-count=1` early-exits at the first such commit, so this is a presence probe, not a count.\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t'rev-list',\n\t\t\t'--max-count=1',\n\t\t\trev,\n\t\t\t'--not',\n\t\t\t'--remotes',\n\t\t\t'--',\n\t\t);\n\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\tthrow new CancellationError();\n\t\t}\n\n\t\treturn result.stdout.trim().length > 0;\n\t}\n\n\t@debug({\n\t\targs: (repoPath, shas) => ({ repoPath: repoPath, shas: `${shas.length} value(s)` }),\n\t\texit: r => `${r.size} unpublished`,\n\t})\n\tasync filterUnpublishedShas(\n\t\trepoPath: string,\n\t\tshas: readonly string[],\n\t\toptions?: { priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<Set<string>> {\n\t\tconst unpublished = new Set<string>();\n\t\tif (!shas.length) return unpublished;\n\n\t\t// One walk answers every sha: `<shas…> --not --remotes` yields the commits reachable from any of them\n\t\t// but not from any remote-tracking ref, so a sha is unpublished exactly when it appears in the output.\n\t\t// Callers pass tips from sibling worktrees — safe from a single `cwd` because the object store and\n\t\t// `refs/remotes` are shared across a repo's worktrees (unlike the index/working tree, which are not).\n\t\t//\n\t\t// NOT `--no-walk`: it \"has no effect if a range is specified\", and `--not --remotes` makes this a range,\n\t\t// so it would silently walk anyway and return the whole unpublished history instead of just these tips.\n\t\t// The walk is bounded by divergence from the remotes, not by repo size; callers skip this entirely when\n\t\t// the repo has no remotes (where every local commit would qualify).\n\t\t// Chunked so a repo with a very large number of worktrees can't overflow the platform's argument\n\t\t// limit (Windows' `CreateProcess` caps the whole command line at ~32K characters).\n\t\t// Deliberately NOT `errors: 'ignore'`: this answers for EVERY sha at once, so a swallowed failure\n\t\t// would return an empty set the caller can't distinguish from \"nothing is unpublished\", publishing a\n\t\t// confident `hasUnpushed: false` across every worktree in the batch. Letting it throw degrades the\n\t\t// caller to \"unknown\", which omits the field and leaves the client's last-known value in place.\n\t\tfor (const chunk of chunkArray([...shas], maxShasPerRevListSpawn)) {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t\t},\n\t\t\t\t'rev-list',\n\t\t\t\t...chunk,\n\t\t\t\t'--not',\n\t\t\t\t'--remotes',\n\t\t\t\t'--',\n\t\t\t);\n\t\t\t// Anything but a clean exit leaves empty stdout, which this function would otherwise read as\n\t\t\t// \"every sha is published\" — publishing a definite, wrong `hasUnpushed: false` for the whole\n\t\t\t// batch. Dropping `errors: 'ignore'` was not enough on its own: a stderr matching `GitWarnings`\n\t\t\t// (a repo path that briefly vanished, an unknown rev) is swallowed by the default handler and\n\t\t\t// resolves rather than throwing. Rethrow so the caller degrades to \"unknown\".\n\t\t\tif (result.completion.status !== 'exited') throw result.completion.error;\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\tconst candidates = new Set(chunk);\n\t\t\tfor (const line of iterateByDelimiter(result.stdout, '\\n')) {\n\t\t\t\tconst sha = line.trim();\n\t\t\t\t// The walk emits ancestors too; keep only the tips we were asked about.\n\t\t\t\tif (sha.length && candidates.has(sha)) {\n\t\t\t\t\tunpublished.add(sha);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn unpublished;\n\t}\n\n\t@debug({ exit: true })\n\tasync getCommitDates(\n\t\trepoPath: string,\n\t\trev: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<{ authorDate: Date; committerDate: Date } | undefined> {\n\t\tconst parser = getShaAndDatesLogParser();\n\t\tconst result = await this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\terrors: 'ignore',\n\t\t\t\t// Why: full SHAs identify immutable commits (5-min TTL is safe). Non-SHA refs rely on\n\t\t\t\t// gitResults being cleared on 'head'/'heads'/'remotes' events; the 60s TTL is the\n\t\t\t\t// failsafe for watcher latency / web (no fs watcher).\n\t\t\t\tcaching: {\n\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\toptions: { accessTTL: isSha(rev) ? 5 * 60 * 1000 : 60 * 1000 },\n\t\t\t\t},\n\t\t\t},\n\t\t\t'log',\n\t\t\t'-1',\n\t\t\t...parser.arguments,\n\t\t\trev,\n\t\t);\n\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) return undefined;\n\n\t\tfor (const entry of parser.parse(result.stdout)) {\n\t\t\tconst authorSeconds = Number(entry.authorDate);\n\t\t\tconst committerSeconds = Number(entry.committerDate);\n\t\t\tif (!Number.isFinite(authorSeconds) || !Number.isFinite(committerSeconds)) return undefined;\n\t\t\treturn {\n\t\t\t\tauthorDate: new Date(authorSeconds * 1000),\n\t\t\t\tcommitterDate: new Date(committerSeconds * 1000),\n\t\t\t};\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t@debug()\n\tasync getCommitFiles(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<GitFileChange[]> {\n\t\tconst parser = getShaAndFilesAndStatsLogParser();\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsLog },\n\t\t\t'log',\n\t\t\t...parser.arguments,\n\t\t\t'-n1',\n\t\t\trev && !isUncommittedStaged(rev) ? rev : undefined,\n\t\t\t'--',\n\t\t);\n\n\t\tconst repoUri = fileUri(normalizePath(repoPath));\n\t\tconst files = first(parser.parse(result.stdout))?.files.map(\n\t\t\tf =>\n\t\t\t\tnew GitFileChange(\n\t\t\t\t\trepoPath,\n\t\t\t\t\tf.path,\n\t\t\t\t\tf.status as GitFileStatus,\n\t\t\t\t\tjoinUriPath(repoUri, normalizePath(f.path)),\n\t\t\t\t\tf.originalPath,\n\t\t\t\t\tf.originalPath != null ? joinUriPath(repoUri, normalizePath(f.originalPath)) : undefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{ additions: f.additions, deletions: f.deletions, changes: 0 },\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\tf.mode,\n\t\t\t\t\tf.oid ? { oid: f.oid, previousOid: f.previousOid } : undefined,\n\t\t\t\t),\n\t\t);\n\n\t\treturn files ?? [];\n\t}\n\n\t@debug()\n\tasync getCommitForFile(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev?: string | undefined,\n\t\toptions?: { firstIfNotFound?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitCommit | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst [relativePath, root] = splitPath(toFsPath(pathOrUri), repoPath);\n\n\t\ttry {\n\t\t\tconst log = await this.getLogForPath(root, relativePath, rev, { limit: 1 }, cancellation);\n\t\t\tif (log == null) return undefined;\n\n\t\t\tlet commit;\n\t\t\tif (rev) {\n\t\t\t\tcommit = log.commits.get(rev);\n\t\t\t\tif (commit == null && !options?.firstIfNotFound) {\n\t\t\t\t\t// If the ref isn't a valid sha we will never find it, so let it fall through so we return the first\n\t\t\t\t\tif (isSha(rev) || isUncommitted(rev)) return undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn commit ?? first(log.commits.values());\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug()\n\tgetCommitReachability(\n\t\trepoPath: string,\n\t\trev: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitCommitReachability | undefined> {\n\t\tif (repoPath == null || isUncommitted(rev)) return Promise.resolve(undefined);\n\n\t\tconst scope = getScopedLogger();\n\n\t\tconst getCore = async (cacheable?: CacheController) => {\n\t\t\ttry {\n\t\t\t\t// Use for-each-ref with %(HEAD) to mark current branch with *\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t'for-each-ref',\n\t\t\t\t\t'--contains',\n\t\t\t\t\trev,\n\t\t\t\t\t'--format=%(HEAD)%(refname)',\n\t\t\t\t\t'--sort=-version:refname',\n\t\t\t\t\t'--sort=-committerdate',\n\t\t\t\t\t'--sort=-HEAD',\n\t\t\t\t\t'refs/heads/',\n\t\t\t\t\t'refs/remotes/',\n\t\t\t\t\t'refs/tags/',\n\t\t\t\t);\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\tconst refs: GitCommitReachability['refs'] = [];\n\n\t\t\t\t// Parse branches from refs/heads/ and refs/remotes/\n\t\t\t\tif (result?.stdout) {\n\t\t\t\t\tconst lines = result.stdout.split('\\n');\n\n\t\t\t\t\tfor (let line of lines) {\n\t\t\t\t\t\tline = line.trim();\n\t\t\t\t\t\tif (!line) continue;\n\n\t\t\t\t\t\t// %(HEAD) outputs '*' for current branch, ' ' for others\n\t\t\t\t\t\tconst isCurrent = line.startsWith('*');\n\t\t\t\t\t\tconst refname = isCurrent ? line.substring(1) : line; // Skip the HEAD marker\n\n\t\t\t\t\t\t// Skip HEADs\n\t\t\t\t\t\tif (refname.endsWith('/HEAD')) continue;\n\n\t\t\t\t\t\tif (refname.startsWith('refs/heads/')) {\n\t\t\t\t\t\t\t// Remove 'refs/heads/'\n\t\t\t\t\t\t\tconst name = refname.substring(11);\n\t\t\t\t\t\t\trefs.push({\n\t\t\t\t\t\t\t\trefType: 'branch',\n\t\t\t\t\t\t\t\tname: name,\n\t\t\t\t\t\t\t\tremote: false,\n\t\t\t\t\t\t\t\tcurrent: isCurrent,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (refname.startsWith('refs/remotes/')) {\n\t\t\t\t\t\t\t// Remove 'refs/remotes/'\n\t\t\t\t\t\t\trefs.push({ refType: 'branch', name: refname.substring(13), remote: true });\n\t\t\t\t\t\t} else if (refname.startsWith('refs/tags/')) {\n\t\t\t\t\t\t\t// Remove 'refs/tags/'\n\t\t\t\t\t\t\trefs.push({ refType: 'tag', name: refname.substring(10) });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// git already returns sorted by -HEAD, -committerdate, -version:refname;\n\t\t\t\t// compareReachableRefs refines by current-first / local-before-remote / tag-version.\n\t\t\t\trefs.sort(compareReachableRefs);\n\n\t\t\t\treturn { refs: refs };\n\t\t\t} catch (ex) {\n\t\t\t\tcacheable?.invalidate();\n\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\tdebugger;\n\t\t\t\tscope?.error(ex);\n\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t};\n\n\t\treturn this.cache.reachability.getOrCreate(repoPath, rev, getCore);\n\t}\n\n\t@debug()\n\tasync getIncomingActivity(\n\t\trepoPath: string,\n\t\toptions?: IncomingActivityOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitReflog | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst cfg = this.context.config;\n\t\tconst parser = getReflogParser();\n\t\tconst args = ['--walk-reflogs', ...parser.arguments, '--date=iso8601'];\n\n\t\tconst ordering = options?.ordering ?? cfg?.commits.ordering;\n\t\tif (ordering) {\n\t\t\targs.push(`--${ordering}-order`);\n\t\t}\n\n\t\tif (options?.all) {\n\t\t\targs.push('--all');\n\t\t}\n\n\t\t// Pass a much larger limit to reflog, because we aggregate the data and we won't know how many lines we'll need\n\t\tconst limit = (options?.limit ?? cfg?.commits.maxItems ?? 0) * 100;\n\t\tif (limit) {\n\t\t\targs.push(`-n${limit}`);\n\t\t}\n\n\t\tif (options?.skip) {\n\t\t\targs.push(`--skip=${options.skip}`);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsLog, priority: 'background' },\n\t\t\t\t'log',\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tconst reflog = parseGitRefLog(parser, result.stdout, repoPath, reflogCommands, limit, limit * 100);\n\t\t\tif (reflog?.hasMore) {\n\t\t\t\treflog.more = this.getReflogMoreFn(reflog, options);\n\t\t\t}\n\n\t\t\treturn reflog;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate getReflogMoreFn(\n\t\treflog: GitReflog,\n\t\toptions?: IncomingActivityOptions,\n\t): (limit: number) => Promise<GitReflog> {\n\t\treturn async (limit: number | undefined) => {\n\t\t\tlimit = limit ?? 0;\n\n\t\t\tconst moreLog = await this.getIncomingActivity(reflog.repoPath, {\n\t\t\t\t...options,\n\t\t\t\tlimit: limit,\n\t\t\t\tskip: reflog.total,\n\t\t\t});\n\t\t\tif (moreLog == null) {\n\t\t\t\t// If we can't find any more, assume we have everything\n\t\t\t\treturn { ...reflog, hasMore: false, more: undefined };\n\t\t\t}\n\n\t\t\tconst mergedLog: GitReflog = {\n\t\t\t\trepoPath: reflog.repoPath,\n\t\t\t\trecords: [...reflog.records, ...moreLog.records],\n\t\t\t\tcount: reflog.count + moreLog.count,\n\t\t\t\ttotal: reflog.total + moreLog.total,\n\t\t\t\tlimit: (reflog.limit ?? 0) + limit,\n\t\t\t\thasMore: moreLog.hasMore,\n\t\t\t};\n\t\t\tif (mergedLog.hasMore) {\n\t\t\t\tmergedLog.more = this.getReflogMoreFn(mergedLog, options);\n\t\t\t}\n\n\t\t\treturn mergedLog;\n\t\t};\n\t}\n\n\t@debug({ exit: true })\n\tgetInitialCommitSha(repoPath: string, cancellation?: AbortSignal): Promise<string | undefined> {\n\t\t// Initial commit SHA is shared across all worktrees\n\t\treturn this.cache.getInitialCommitSha(repoPath, async commonPath => {\n\t\t\ttry {\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: commonPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t'rev-list',\n\t\t\t\t\t`--max-parents=0`,\n\t\t\t\t\t'HEAD',\n\t\t\t\t\t'--',\n\t\t\t\t);\n\t\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t}\n\n\t\t\t\treturn result.stdout.trim().split('\\n')?.[0];\n\t\t\t} catch (ex) {\n\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t});\n\t}\n\n\t@debug()\n\tasync getLeftRightCommitCount(\n\t\trepoPath: string,\n\t\trange: GitRevisionRange,\n\t\toptions?: { authors?: GitUser[]; excludeMerges?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<LeftRightCommitCountResult | undefined> {\n\t\tconst authors = options?.authors?.length\n\t\t\t? options.authors.map(a => `--author=^${escapeRegex(a.name ?? '')} <${escapeRegex(a.email ?? '')}>$`)\n\t\t\t: [];\n\n\t\tconst run = async (): Promise<LeftRightCommitCountResult | undefined> => {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t'rev-list',\n\t\t\t\t'--left-right',\n\t\t\t\t'--count',\n\t\t\t\t...authors,\n\t\t\t\toptions?.excludeMerges ? '--no-merges' : undefined,\n\t\t\t\trange,\n\t\t\t\t'--',\n\t\t\t);\n\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\tthrow new CancellationError();\n\t\t\t}\n\t\t\tif (!result.stdout) return undefined;\n\n\t\t\tconst parts = result.stdout.split('\\t');\n\t\t\tif (parts.length !== 2) return undefined;\n\n\t\t\tconst [left, right] = parts;\n\t\t\tconst counts = {\n\t\t\t\tleft: parseInt(left, 10),\n\t\t\t\tright: parseInt(right, 10),\n\t\t\t};\n\n\t\t\tif (isNaN(counts.left) || isNaN(counts.right)) return undefined;\n\n\t\t\treturn counts;\n\t\t};\n\n\t\t// Author-filtered calls are one-off (e.g. \"who made these commits\") with low re-hit\n\t\t// rate; skip the cache to protect its capacity for the hot no-author merge-target path.\n\t\tif (authors.length > 0) return run();\n\n\t\t// Cache key: range + excludeMerges. RepositoryChange events affecting branches/remotes\n\t\t// invalidate this cache via clearCaches('branches').\n\t\tconst cacheKey = `${range}\\x1f${options?.excludeMerges ? 'no-merges' : ''}`;\n\t\treturn this.cache.leftRightCommitCount.getOrCreate(repoPath, cacheKey, run);\n\t}\n\n\t@debug()\n\tasync getLog(\n\t\trepoPath: string,\n\t\trev?: string | undefined,\n\t\toptions?: GitLogOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitLog | undefined> {\n\t\treturn this.getLogCore(repoPath, rev, options, cancellation);\n\t}\n\n\t@trace({ args: (repoPath, rev) => ({ repoPath: repoPath, rev: rev }), exit: true })\n\tprivate async getLogCore(\n\t\trepoPath: string,\n\t\trev?: string | undefined,\n\t\toptions?: GitLogOptions & {\n\t\t\tpath?: { pathspec: string; filters?: GitDiffFilter[]; range?: DiffRange; renames?: boolean };\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t\tadditionalArgs?: string[],\n\t): Promise<GitLog | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst currentUserPromise = this.provider.config.getCurrentUser(repoPath);\n\n\t\t\tconst cfg = this.context.config;\n\t\t\tconst limit = options?.limit ?? cfg?.commits.maxItems ?? 0;\n\t\t\tconst isSingleCommit = limit === 1;\n\n\t\t\tconst cfgIncludeFiles = options?.includeFiles ?? cfg?.commits.includeFileDetails?.(repoPath) ?? true;\n\t\t\tconst includeFiles = cfgIncludeFiles || isSingleCommit || Boolean(options?.path?.pathspec);\n\n\t\t\tconst parser = getCommitsLogParser(includeFiles, Boolean(options?.path?.pathspec && options?.path?.range));\n\t\t\tconst args = ['log', ...parser.arguments];\n\n\t\t\tconst similarityThreshold = options?.similarityThreshold ?? cfg?.commits.similarityThreshold;\n\t\t\targs.push(`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`, '--use-mailmap');\n\n\t\t\tif (options?.all) {\n\t\t\t\targs.push('--all');\n\t\t\t\tif (options?.path?.pathspec) {\n\t\t\t\t\targs.push('--single-worktree');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst merges = options?.merges ?? true;\n\t\t\tif (merges) {\n\t\t\t\t// If we are are asking for a specific ref, ensure we return the merge commit files\n\t\t\t\tif (isSingleCommit) {\n\t\t\t\t\targs.push('-m');\n\t\t\t\t}\n\t\t\t\targs.push(merges === 'first-parent' ? '--first-parent' : '--no-min-parents');\n\t\t\t} else {\n\t\t\t\targs.push('--no-merges');\n\t\t\t}\n\n\t\t\tconst ordering = options?.ordering ?? cfg?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\tif (options?.authors?.length) {\n\t\t\t\targs.push(\n\t\t\t\t\t...options.authors.map(\n\t\t\t\t\t\ta => `--author=^${escapeRegex(a.name ?? '')} <${escapeRegex(a.email ?? '')}>$`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet overrideHasMore;\n\n\t\t\tif (options?.since) {\n\t\t\t\toverrideHasMore = true;\n\t\t\t\targs.push(`--since=\"${options.since}\"`);\n\t\t\t}\n\n\t\t\tif (options?.until) {\n\t\t\t\toverrideHasMore = true;\n\t\t\t\targs.push(`--until=\"${options.until}\"`);\n\t\t\t}\n\n\t\t\tif (additionalArgs?.length) {\n\t\t\t\targs.push(...additionalArgs);\n\t\t\t}\n\n\t\t\tif (limit > 0) {\n\t\t\t\toverrideHasMore = isSingleCommit ? false : undefined;\n\t\t\t\t// Add 1 to the limit so we can check if there are more commits\n\t\t\t\targs.push(`-n${isSingleCommit ? 1 : limit + 1}`);\n\t\t\t}\n\n\t\t\tlet stashes: ReadonlyMap<string, GitStashCommit> | undefined;\n\n\t\t\tif (!isSingleCommit && options?.stashes) {\n\t\t\t\tstashes =\n\t\t\t\t\ttypeof options.stashes === 'boolean'\n\t\t\t\t\t\t? (await this.provider.stash?.getStash(repoPath, { reachableFrom: rev }, cancellation))?.stashes\n\t\t\t\t\t\t: options.stashes;\n\t\t\t\tif (stashes?.size) {\n\t\t\t\t\trev ??= 'HEAD';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rev && !isUncommittedStaged(rev)) {\n\t\t\t\targs.push(rev);\n\t\t\t}\n\n\t\t\tlet pathspec: string | undefined;\n\t\t\tlet pathspecRange: `${number},${number}` | undefined;\n\n\t\t\tif (options?.path?.pathspec) {\n\t\t\t\tpathspec = options.path.pathspec;\n\t\t\t\tconst { filters, range, renames } = options.path;\n\n\t\t\t\tif (filters?.length) {\n\t\t\t\t\targs.push(`--diff-filter=${filters.join('')}`);\n\t\t\t\t}\n\n\t\t\t\tif (range != null) {\n\t\t\t\t\t// Git doesn't allow rename detection (`--follow`) if a range is used\n\n\t\t\t\t\tconst [start, end] = getGitStartEnd(range);\n\t\t\t\t\tpathspecRange = `${start},${end}`;\n\t\t\t\t\targs.push(`-L ${pathspecRange}:${pathspec}`, '--');\n\t\t\t\t} else {\n\t\t\t\t\tif (renames !== false) {\n\t\t\t\t\t\targs.push('--follow');\n\t\t\t\t\t}\n\t\t\t\t\targs.push('--', pathspec);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\targs.push('--');\n\t\t\t}\n\n\t\t\tconst currentUser = await currentUserPromise.catch(() => undefined);\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t// Only the eager, paged, multi-commit log measures the cost this evidence switches off — a\n\t\t\t// single-commit load and a pathspec-filtered log are cheap per numstat regardless of `includeFiles`.\n\t\t\tconst isEagerPagedFileLog = includeFiles && !isSingleCommit && !options?.path?.pathspec;\n\n\t\t\tconst cmdOpts: GitRunOptions = {\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\tconfigs: gitConfigsLogWithFiles,\n\t\t\t\t// Single-commit log serves user-initiated reads (commit details, hover, etc.).\n\t\t\t\t// Mirrors getCommitDates: full SHAs are immutable so a 5-min TTL is safe; non-SHA refs\n\t\t\t\t// rely on gitResults being cleared on head/heads/remotes events (60s is the failsafe\n\t\t\t\t// for watcher latency / web with no fs watcher).\n\t\t\t\t...(isSingleCommit && rev\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tcaching: {\n\t\t\t\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\t\t\t\toptions: { accessTTL: isSha(rev) ? 5 * 60 * 1000 : 60 * 1000 },\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\t\t...(isEagerPagedFileLog ? { slownessCategory: 'commitFiles' as const } : undefined),\n\t\t\t};\n\t\t\tlet { commits, count } = await parseCommits(\n\t\t\t\tparser,\n\t\t\t\tisSingleCommit ? this.git.run(cmdOpts, ...args) : this.git.stream(cmdOpts, ...args),\n\t\t\t\trepoPath,\n\t\t\t\tpathspec,\n\t\t\t\tlimit,\n\t\t\t\tundefined,\n\t\t\t\tcurrentUser,\n\t\t\t);\n\n\t\t\t// If we didn't find any history from the working tree, check to see if the file was renamed\n\t\t\tif (rev == null && pathspec && !commits.size) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpathspec,\n\t\t\t\t\tundefined,\n\t\t\t\t\tcancellation,\n\t\t\t\t);\n\t\t\t\tif (status?.originalPath != null) {\n\t\t\t\t\tpathspec = status.originalPath;\n\n\t\t\t\t\tif (pathspecRange) {\n\t\t\t\t\t\tconst index = args.findIndex(a => a.startsWith('-L '));\n\t\t\t\t\t\targs.splice(index, 1, `-L ${pathspecRange}:${pathspec}`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\targs.splice(args.length - 1, 1, pathspec);\n\t\t\t\t\t}\n\n\t\t\t\t\t({ commits, count } = await parseCommits(\n\t\t\t\t\t\tparser,\n\t\t\t\t\t\tisSingleCommit ? this.git.run(cmdOpts, ...args) : this.git.stream(cmdOpts, ...args),\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tpathspec,\n\t\t\t\t\t\tlimit,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tcurrentUser,\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Merge stashes in-memory rather than via `git log --stdin <stash>` — git would\n\t\t\t// walk each stash's parent chains and pull in pre-rebase ancestors that aren't\n\t\t\t// reachable from <rev>. Slot each stash directly above its first parent; stashes\n\t\t\t// whose parent isn't in the result (rebased away, or below the current limit) are\n\t\t\t// dropped — the Stashes view still surfaces them, and they reappear here if the\n\t\t\t// parent loads via \"Load more\".\n\t\t\tif (stashes?.size) {\n\t\t\t\t// `stashes` arrives in `git stash list` order (newest @{0} first), so per-parent\n\t\t\t\t// groups naturally land newest-first without an explicit sort\n\t\t\t\tconst stashesByParent = new Map<string, GitStashCommit[]>();\n\t\t\t\tfor (const stash of stashes.values()) {\n\t\t\t\t\tconst parentSha = stash.parents[0];\n\t\t\t\t\tif (parentSha == null || !commits.has(parentSha)) continue;\n\n\t\t\t\t\tconst group = stashesByParent.get(parentSha);\n\t\t\t\t\tif (group != null) {\n\t\t\t\t\t\tgroup.push(stash);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstashesByParent.set(parentSha, [stash]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (stashesByParent.size) {\n\t\t\t\t\tconst cap = limit > 0 ? limit + 1 : Number.POSITIVE_INFINITY;\n\t\t\t\t\tconst merged = new Map<string, GitCommit>();\n\t\t\t\t\touter: for (const c of commits.values()) {\n\t\t\t\t\t\tconst group = stashesByParent.get(c.sha);\n\t\t\t\t\t\tif (group != null) {\n\t\t\t\t\t\t\tfor (const s of group) {\n\t\t\t\t\t\t\t\tif (merged.size >= cap) break outer;\n\n\t\t\t\t\t\t\t\tmerged.set(s.sha, s);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (merged.size >= cap) break;\n\n\t\t\t\t\t\tmerged.set(c.sha, c);\n\t\t\t\t\t}\n\t\t\t\t\tcommits = merged;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst log: GitLog = {\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tcommits: commits,\n\t\t\t\tsha: isRevisionRange(rev) ? undefined : rev,\n\t\t\t\tcount: commits.size,\n\t\t\t\tlimit: limit,\n\t\t\t\thasMore: overrideHasMore ?? (limit > 0 && count > limit),\n\t\t\t};\n\n\t\t\tif (!isSingleCommit) {\n\t\t\t\tlog.query = (limit: number | undefined) =>\n\t\t\t\t\tthis.getLogCore(repoPath, rev, { ...options, limit: limit }, undefined, additionalArgs);\n\t\t\t\tif (log.hasMore) {\n\t\t\t\t\tlog.more = this.getLogCoreMoreFn(log, rev, options);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn log;\n\t\t} catch (ex) {\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t// Check if this is a \"bad object\" error due to a submodule's internal SHA\n\t\t\tconst pathspec = options?.path?.pathspec;\n\t\t\tif (rev && pathspec && ex instanceof Error && GitErrors.badObject.test(ex.message)) {\n\t\t\t\tconst tree = await this.provider.revision.getTreeEntryForRevision(repoPath, pathspec, 'HEAD');\n\t\t\t\tif (tree?.type === 'commit') {\n\t\t\t\t\t// It's a submodule - retry without the rev and without rename tracking\n\t\t\t\t\treturn this.getLogCore(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t{ ...options, path: { ...options.path, pathspec: pathspec, renames: false } },\n\t\t\t\t\t\tcancellation,\n\t\t\t\t\t\tadditionalArgs,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tdebugger;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate getLogCoreMoreFn(\n\t\tlog: GitLog,\n\t\trev: string | undefined,\n\t\toptions?: GitLogOptions & {\n\t\t\tpath?: { pathspec: string; filters?: GitDiffFilter[]; range?: DiffRange; renames?: boolean };\n\t\t},\n\t): (limit: number | { until: string } | undefined) => Promise<GitLog> {\n\t\treturn async (limit: number | { until: string } | undefined) => {\n\t\t\tconst moreUntil = limit != null && typeof limit === 'object' ? limit.until : undefined;\n\t\t\tlet moreLimit = typeof limit === 'number' ? limit : undefined;\n\n\t\t\tif (moreUntil && some(log.commits.values(), c => c.ref === moreUntil)) {\n\t\t\t\treturn log;\n\t\t\t}\n\n\t\t\tmoreLimit = moreLimit ?? 0;\n\n\t\t\t// If the log is for a range, then just get everything prior + more\n\t\t\tif (isRevisionRange(log.sha)) {\n\t\t\t\tconst moreLog = await this.getLogCore(log.repoPath, rev, {\n\t\t\t\t\t...options,\n\t\t\t\t\tlimit: moreLimit === 0 ? 0 : (options?.limit ?? 0) + moreLimit,\n\t\t\t\t});\n\t\t\t\t// If we can't find any more, assume we have everything\n\t\t\t\tif (moreLog == null) return { ...log, hasMore: false, more: undefined };\n\n\t\t\t\treturn moreLog;\n\t\t\t}\n\n\t\t\t// Stashes are not part of the normal commit history, so we need to find the last non-stash commit for the cursor\n\t\t\tconst lastCommit = findLast(log.commits.values(), c => !GitCommit.isStash(c)) ?? last(log.commits.values());\n\t\t\tconst sha = lastCommit?.ref;\n\n\t\t\t// Check to make sure the filename hasn't changed and if it has use the previous\n\t\t\tconst lastCommitFile = lastCommit?.anyFiles?.[0];\n\t\t\tif (options?.path?.pathspec && lastCommitFile != null) {\n\t\t\t\tconst path = lastCommitFile.originalPath ?? lastCommitFile.path;\n\t\t\t\tif (path !== options.path.pathspec) {\n\t\t\t\t\toptions = { ...options, path: { ...options.path, pathspec: path } };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we were asked for all refs, use the last commit timestamp (plus a second) as a cursor\n\t\t\tlet timestamp: number | undefined;\n\t\t\tif (options?.all) {\n\t\t\t\tconst date = lastCommit?.committer.date;\n\t\t\t\t// Git only allows 1-second precision, so round up to the nearest second\n\t\t\t\ttimestamp = date != null ? Math.ceil(date.getTime() / 1000) + 1 : undefined;\n\t\t\t}\n\n\t\t\tlet moreLogCount;\n\t\t\tlet queryLimit = moreUntil == null ? moreLimit : 0;\n\t\t\tdo {\n\t\t\t\tconst moreLog = await this.getLogCore(\n\t\t\t\t\tlog.repoPath,\n\t\t\t\t\ttimestamp ? rev : moreUntil == null ? `${sha}^` : `${moreUntil}^..${sha}^`,\n\t\t\t\t\t{\n\t\t\t\t\t\t...options,\n\t\t\t\t\t\tlimit: queryLimit,\n\t\t\t\t\t\t...(timestamp ? { until: timestamp } : undefined),\n\t\t\t\t\t},\n\t\t\t\t\tundefined,\n\t\t\t\t\ttimestamp ? ['--boundary'] : undefined,\n\t\t\t\t);\n\t\t\t\t// If we can't find any more, assume we have everything\n\t\t\t\tif (moreLog == null) return { ...log, hasMore: false, more: undefined };\n\n\t\t\t\tconst currentCount = log.commits.size;\n\t\t\t\tconst commits = new Map([...log.commits, ...moreLog.commits]);\n\n\t\t\t\tif (currentCount === commits.size && queryLimit !== 0) {\n\t\t\t\t\t// If we didn't find any new commits, we must have them all so return that we have everything\n\t\t\t\t\tif (moreLogCount === moreLog.commits.size) {\n\t\t\t\t\t\treturn { ...log, hasMore: false, more: undefined };\n\t\t\t\t\t}\n\n\t\t\t\t\tmoreLogCount = moreLog.commits.size;\n\t\t\t\t\tqueryLimit = queryLimit * 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (timestamp != null && sha != null && !moreLog.commits.has(sha)) {\n\t\t\t\t\tdebugger;\n\t\t\t\t}\n\n\t\t\t\tconst mergedLog: GitLog = {\n\t\t\t\t\trepoPath: log.repoPath,\n\t\t\t\t\tcommits: commits,\n\t\t\t\t\tsha: log.sha,\n\t\t\t\t\tcount: commits.size,\n\t\t\t\t\tlimit: moreUntil == null ? (log.limit ?? 0) + moreLimit : undefined,\n\t\t\t\t\thasMore: moreUntil == null ? moreLog.hasMore : true,\n\t\t\t\t\t// The oldest commit SHA of the previous page — the graph webview compares this\n\t\t\t\t\t// against its last displayed row to determine the merge point for appending new rows\n\t\t\t\t\tstartingCursor: sha,\n\t\t\t\t\tendingCursor: moreLog.endingCursor,\n\t\t\t\t\tpagedCommits: () => {\n\t\t\t\t\t\t// Remove any duplicates\n\t\t\t\t\t\tfor (const sha of log.commits.keys()) {\n\t\t\t\t\t\t\tmoreLog.commits.delete(sha);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn moreLog.commits;\n\t\t\t\t\t},\n\t\t\t\t\t// oxlint-disable-next-line no-loop-func\n\t\t\t\t\tquery: (limit: number | undefined) =>\n\t\t\t\t\t\tthis.getLogCore(log.repoPath, rev, { ...options, limit: limit }),\n\t\t\t\t};\n\t\t\t\tif (mergedLog.hasMore) {\n\t\t\t\t\tmergedLog.more = this.getLogCoreMoreFn(mergedLog, rev, options);\n\t\t\t\t}\n\n\t\t\t\treturn mergedLog;\n\t\t\t} while (true);\n\t\t};\n\t}\n\n\t@debug()\n\tasync getLogForPath(\n\t\trepoPath: string | undefined,\n\t\tpathOrUri: string | Uri,\n\t\trev?: string | undefined,\n\t\toptions?: GitLogForPathOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitLog | undefined> {\n\t\tif (repoPath == null) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\n\t\tif (repoPath != null && repoPath === relativePath) {\n\t\t\tthrow new Error(`Path cannot match the repository path; path=${relativePath}`);\n\t\t}\n\n\t\tconst cfg = this.context.config;\n\t\toptions = {\n\t\t\t...options,\n\t\t\tall: options?.all ?? cfg?.fileHistory?.showAllBranches,\n\t\t\tlimit: options?.limit ?? cfg?.commits.maxItems ?? 0,\n\t\t\tmerges: options?.merges ?? cfg?.fileHistory?.showMergeCommits,\n\t\t\tordering: options?.ordering ?? cfg?.commits.ordering ?? undefined,\n\t\t\trenames: options?.renames ?? cfg?.fileHistory?.followRenames,\n\t\t\tsimilarityThreshold: options?.similarityThreshold ?? cfg?.commits.similarityThreshold,\n\t\t};\n\n\t\tif (isFolderGlob(relativePath)) {\n\t\t\trelativePath = stripFolderGlob(relativePath);\n\t\t\toptions.isFolder = true;\n\t\t} else if (options.isFolder == null) {\n\t\t\tconst tree = await this.provider.revision.getTreeEntryForRevision(repoPath, relativePath, rev || 'HEAD');\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\tif (tree?.type === 'commit') {\n\t\t\t\t// It's a submodule — line ranges and rename tracking don't apply, and the rev may reference\n\t\t\t\t// the submodule's internal SHA which isn't valid in the parent repo\n\t\t\t\toptions.range = undefined;\n\t\t\t\toptions.renames = false;\n\t\t\t\t// rev = undefined;\n\t\t\t} else {\n\t\t\t\toptions.isFolder = tree?.type === 'tree';\n\t\t\t}\n\t\t}\n\n\t\t// Build cache key — only for non-folder, non-filtered queries\n\t\tlet cacheKey: string | undefined;\n\t\tif (\n\t\t\t!options.isFolder &&\n\t\t\toptions.authors == null &&\n\t\t\toptions.cursor == null &&\n\t\t\toptions.filters == null &&\n\t\t\toptions.range == null &&\n\t\t\toptions.since == null &&\n\t\t\toptions.until == null\n\t\t) {\n\t\t\tlet suffix = 'log';\n\t\t\tif (rev != null) {\n\t\t\t\tsuffix += `:${rev}`;\n\t\t\t}\n\t\t\tif (options.all) {\n\t\t\t\tsuffix += ':all';\n\t\t\t}\n\t\t\tif (options.limit) {\n\t\t\t\tsuffix += `:n${options.limit}`;\n\t\t\t}\n\t\t\tif (options.merges) {\n\t\t\t\tsuffix += `:merges=${options.merges}`;\n\t\t\t}\n\t\t\tif (options.ordering) {\n\t\t\t\tsuffix += `:ordering=${options.ordering}`;\n\t\t\t}\n\t\t\tif (options.renames) {\n\t\t\t\tsuffix += ':follow';\n\t\t\t}\n\t\t\tcacheKey = `${normalizePath(relativePath)}:${suffix}`;\n\t\t}\n\n\t\tif (cacheKey != null) {\n\t\t\t// Check for exact cache hit\n\t\t\tconst cached = this.cache.fileLog.get(repoPath, cacheKey);\n\t\t\tif (cached != null) {\n\t\t\t\tscope?.trace(`Cache hit: '${cacheKey}'`);\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\t// Subset optimization: if requesting partial log, check if whole-file log is cached\n\t\t\tif (rev != null || (options.limit != null && options.limit !== 0)) {\n\t\t\t\tconst baseKey = `${normalizePath(relativePath)}:log${options.renames ? ':follow' : ''}`;\n\t\t\t\tconst baseLog = this.cache.fileLog.get(repoPath, baseKey);\n\t\t\t\tif (baseLog != null) {\n\t\t\t\t\tif (rev == null) {\n\t\t\t\t\t\tscope?.trace(`Cache hit: ~'${cacheKey}'`);\n\t\t\t\t\t\treturn baseLog;\n\t\t\t\t\t}\n\n\t\t\t\t\tscope?.trace(`Cache ?: '${cacheKey}'`);\n\t\t\t\t\tconst log = await baseLog;\n\t\t\t\t\tif (log != null && !log.hasMore && log.commits.has(rev)) {\n\t\t\t\t\t\tscope?.trace(`Cache hit: '${cacheKey}'`);\n\n\t\t\t\t\t\t// Create a copy of the log starting at the requested commit\n\t\t\t\t\t\tlet skip = true;\n\t\t\t\t\t\tlet i = 0;\n\t\t\t\t\t\tconst limit = options.limit;\n\t\t\t\t\t\tconst commits = new Map(\n\t\t\t\t\t\t\tfilterMap<[string, GitCommit], [string, GitCommit]>(log.commits.entries(), ([sha, c]) => {\n\t\t\t\t\t\t\t\tif (skip) {\n\t\t\t\t\t\t\t\t\tif (sha !== rev) return undefined;\n\n\t\t\t\t\t\t\t\t\tskip = false;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\t\t\tif (limit != null && i > limit) {\n\t\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn [sha, c];\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst optsCopy = { ...options };\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...log,\n\t\t\t\t\t\t\tlimit: optsCopy.limit,\n\t\t\t\t\t\t\tcount: commits.size,\n\t\t\t\t\t\t\tcommits: commits,\n\t\t\t\t\t\t\tquery: (limit: number | undefined) =>\n\t\t\t\t\t\t\t\tthis.getLogForPath(repoPath, pathOrUri, rev, {\n\t\t\t\t\t\t\t\t\t...optsCopy,\n\t\t\t\t\t\t\t\t\tlimit: limit,\n\t\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}\n\t\t\t}\n\n\t\t\tscope?.trace(`Cache miss: '${cacheKey}'`);\n\n\t\t\treturn this.cache.fileLog.getOrCreate(\n\t\t\t\trepoPath,\n\t\t\t\tcacheKey,\n\t\t\t\t(_cacheable, signal) => this.getLogForPathCore(repoPath, relativePath, rev, options, signal),\n\t\t\t\t{ cancellation: cancellation },\n\t\t\t);\n\t\t}\n\n\t\treturn this.getLogForPathCore(repoPath, relativePath, rev, options, cancellation);\n\t}\n\n\tprivate async getLogForPathCore(\n\t\trepoPath: string,\n\t\tpath: string,\n\t\trev: string | undefined,\n\t\toptions: GitLogForPathOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitLog | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst tracked = await this.provider.isTrackedWithDetails(path, repoPath, rev);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tif (tracked == null) {\n\t\t\tscope?.debug(`Skipping log; '${path}' is not tracked`);\n\t\t\treturn emptyPromise as Promise<GitLog>;\n\t\t}\n\n\t\tconst relativePath = tracked.path;\n\t\tconst root = repoPath;\n\n\t\tconst log = await this.getLogCore(\n\t\t\troot,\n\t\t\trev,\n\t\t\t{\n\t\t\t\tall: options.all,\n\t\t\t\tauthors: options.authors,\n\t\t\t\tcursor: options.cursor,\n\t\t\t\tlimit: options.limit,\n\t\t\t\tmerges: options.merges,\n\t\t\t\tordering: options.ordering,\n\t\t\t\tsince: options.since,\n\t\t\t\tuntil: options.until,\n\t\t\t\tpath: {\n\t\t\t\t\tpathspec: relativePath,\n\t\t\t\t\tfilters: options.filters,\n\t\t\t\t\trange: options.range,\n\t\t\t\t\trenames: options.renames,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\n\t\treturn log;\n\t}\n\n\t@debug()\n\tasync getLogShas(\n\t\trepoPath: string,\n\t\trev?: string | undefined,\n\t\toptions?: GitLogShasOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<Iterable<string>> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst cfg = this.context.config;\n\t\toptions ??= {};\n\t\toptions.limit ??= cfg?.commits.maxItems ?? 0;\n\t\toptions.ordering ??= cfg?.commits.ordering ?? undefined;\n\t\toptions.similarityThreshold ??= cfg?.commits.similarityThreshold;\n\t\toptions.merges ??= true;\n\n\t\tconst getCore = async (): Promise<string[]> => {\n\t\t\ttry {\n\t\t\t\tconst parser = getShaLogParser();\n\t\t\t\tconst args = [...parser.arguments];\n\n\t\t\t\tif (options.all) {\n\t\t\t\t\targs.push(`--all`);\n\t\t\t\t}\n\n\t\t\t\tif (options.ordering) {\n\t\t\t\t\targs.push(`--${options.ordering}-order`);\n\t\t\t\t}\n\n\t\t\t\tif (options.limit) {\n\t\t\t\t\targs.push(`-n${options.limit}`);\n\t\t\t\t}\n\n\t\t\t\tif (options.since) {\n\t\t\t\t\targs.push(`--since=\"${options.since}\"`);\n\t\t\t\t}\n\n\t\t\t\tif (options.merges) {\n\t\t\t\t\targs.push(options.merges === 'first-parent' ? '--first-parent' : '--no-min-parents');\n\t\t\t\t} else {\n\t\t\t\t\targs.push('--no-merges');\n\t\t\t\t}\n\n\t\t\t\tif (options.reverse) {\n\t\t\t\t\targs.push('--reverse');\n\t\t\t\t}\n\n\t\t\t\tif (options.authors?.length) {\n\t\t\t\t\tif (!args.includes('--use-mailmap')) {\n\t\t\t\t\t\targs.push('--use-mailmap');\n\t\t\t\t\t}\n\t\t\t\t\targs.push(\n\t\t\t\t\t\t...options.authors.map(\n\t\t\t\t\t\t\ta => `--author=^${escapeRegex(a.name ?? '')} <${escapeRegex(a.email ?? '')}>$`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst pathspec =\n\t\t\t\t\toptions.pathOrUri != null ? this.provider.getRelativePath(options.pathOrUri, repoPath) : undefined;\n\t\t\t\tif (pathspec) {\n\t\t\t\t\tconst similarityThreshold = options.similarityThreshold;\n\t\t\t\t\targs.push(`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`);\n\t\t\t\t}\n\n\t\t\t\tconst excludeArgs = getRefExclusionArgs(options.excluding);\n\t\t\t\tif (rev && !isUncommittedStaged(rev)) {\n\t\t\t\t\targs.push(rev);\n\t\t\t\t} else if (excludeArgs.length) {\n\t\t\t\t\t// A bare `--not` lists nothing, so anchor the exclusion to HEAD\n\t\t\t\t\targs.push('HEAD');\n\t\t\t\t}\n\t\t\t\targs.push(...excludeArgs);\n\n\t\t\t\targs.push('--');\n\n\t\t\t\tif (pathspec) {\n\t\t\t\t\targs.push(pathspec);\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsLog },\n\t\t\t\t\t'log',\n\t\t\t\t\t...args,\n\t\t\t\t);\n\t\t\t\treturn [...parser.parse(result.stdout)];\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\tdebugger;\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\n\t\t// Cache simple queries (no pathspec, no authors) as these are on hot paths (e.g. getting unpublished commits)\n\t\tconst cacheable = !options.pathOrUri && !options.authors?.length && !options.reverse && !options.all;\n\n\t\tif (cacheable) {\n\t\t\treturn this.cache.logShas.getOrCreate(\n\t\t\t\trepoPath,\n\t\t\t\t`${rev ?? ''}:${options.ordering ?? ''}:${options.limit}:${options.merges}:${options.since ?? ''}${options.excluding == null ? '' : `:${getRefExclusionsKey(options.excluding)}`}`,\n\t\t\t\t() => getCore(),\n\t\t\t);\n\t\t}\n\n\t\treturn getCore();\n\t}\n\n\t@debug()\n\tasync getOldestUnpushedShaForPath(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\n\t\t\tconst parser = getShaLogParser();\n\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsLog },\n\t\t\t\t'log',\n\t\t\t\t...parser.arguments,\n\t\t\t\t'--follow',\n\t\t\t\t'--reverse',\n\t\t\t\t'@{u}..',\n\t\t\t\t'--',\n\t\t\t\trelativePath,\n\t\t\t);\n\t\t\treturn first(parser.parse(result.stdout));\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tdebugger;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug()\n\tasync hasCommitBeenPushed(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\tif (repoPath == null) return false;\n\n\t\treturn this.isAncestorOf(repoPath, rev, '@{u}', cancellation);\n\t}\n\n\t@debug()\n\tasync isAncestorOf(repoPath: string, rev1: string, rev2: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\tif (repoPath == null) return false;\n\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t'merge-base',\n\t\t\t'--is-ancestor',\n\t\t\trev1,\n\t\t\trev2,\n\t\t);\n\t\t// A cancelled check has no answer. `completion` now keeps that distinct from a real \"is an ancestor\"\n\t\t// result — the missing `exitCode` alone already makes the check below `false` — but callers branch on\n\t\t// `isCancellationError`, so this still has to throw rather than quietly answer \"no\".\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\treturn result.exitCode === 0;\n\t}\n\n\t@debug({\n\t\targs: (repoPath, s) => ({\n\t\t\trepoPath: repoPath,\n\t\t\tsearch: `[${s.matchAll ? 'A' : ''}${s.matchCase ? 'C' : ''}${s.matchRegex ? 'R' : ''}${\n\t\t\t\ts.matchWholeWord ? 'W' : ''\n\t\t\t}]: ${s.query.length > 500 ? `${s.query.substring(0, 500)}...` : s.query}`,\n\t\t}),\n\t})\n\tasync searchCommits(\n\t\trepoPath: string,\n\t\tsearch: SearchQuery,\n\t\toptions?: GitSearchCommitsOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<SearchCommitsResult> {\n\t\tconst scope = getScopedLogger();\n\n\t\tsearch = { matchAll: false, matchCase: false, matchRegex: true, matchWholeWord: false, ...search };\n\n\t\t// Pre-process natural language search queries via the host-provided hook\n\t\tif (\n\t\t\tsearch.naturalLanguage &&\n\t\t\t(typeof search.naturalLanguage !== 'object' || !search.naturalLanguage.processedQuery)\n\t\t) {\n\t\t\tsearch = (await this.context.searchQuery?.preprocessQuery?.(search, options?.source)) ?? search;\n\t\t}\n\n\t\t// The conversion failed — `search.query` is still the raw English sentence, not a query; running\n\t\t// it as an ERE would produce a regex error about text the user never wrote.\n\t\tif (typeof search.naturalLanguage === 'object' && search.naturalLanguage.error) {\n\t\t\treturn { search: search, log: undefined };\n\t\t}\n\n\t\ttry {\n\t\t\tconst cfg = this.context.config;\n\t\t\tconst currentUser = await this.provider.config.getCurrentUser(repoPath);\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\tconst parser = getCommitsLogParser(true);\n\n\t\t\tconst similarityThreshold = options?.similarityThreshold ?? cfg?.commits.similarityThreshold;\n\t\t\tconst args = [\n\t\t\t\t'log',\n\t\t\t\t...parser.arguments,\n\t\t\t\t`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`,\n\t\t\t\t'--use-mailmap',\n\t\t\t];\n\n\t\t\tconst { args: searchArgs, files, shas, filters } = parseSearchQueryGitCommand(search, currentUser);\n\t\t\t// Stash commits have 2-3 parents, so `--merges` matches them; excluded in parseCommits.\n\t\t\t// Derived from the args git actually runs rather than `filters.type`, since a multi-value\n\t\t\t// `type:` query (e.g. `type:merge type:tip`) leaves `--merges` in the args while\n\t\t\t// `filters.type` reflects only the last value parsed\n\t\t\tconst mergesOnly = searchArgs.includes('--merges');\n\n\t\t\tlet stashes: Map<string, GitStashCommit> | undefined;\n\t\t\tlet stdin: string | undefined;\n\n\t\t\tlet resolvedShas: Set<string> | undefined;\n\t\t\tif (shas?.size) {\n\t\t\t\tresolvedShas = await this.provider.revision.resolveShas(repoPath, shas, cancellation);\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\t\t\t// Short SHA(s) matched no commit: return empty (empty stdin to `--no-walk --stdin`\n\t\t\t\t// would return HEAD, so we must not fall through to git).\n\t\t\t\tif (!resolvedShas.size) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsearch: search,\n\t\t\t\t\t\tlog: {\n\t\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\t\tcommits: new Map(),\n\t\t\t\t\t\t\tsha: undefined,\n\t\t\t\t\t\t\tsearchFilters: filters,\n\t\t\t\t\t\t\tcount: 0,\n\t\t\t\t\t\t\tlimit: options?.limit ?? cfg?.search?.maxItems ?? 0,\n\t\t\t\t\t\t\thasMore: false,\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\tif (resolvedShas?.size) {\n\t\t\t\tstdin = join(resolvedShas, '\\n');\n\t\t\t\targs.push('--no-walk');\n\t\t\t} else if (!filters.refs) {\n\t\t\t\t// Don't include stashes when using ref: filter, as they would add unrelated commits\n\t\t\t\t// There *HAS* to be a better way to get git log to return stashes, but this is the best we've found\n\t\t\t\tconst converted = convertStashesToStdin(\n\t\t\t\t\tawait this.provider.stash?.getStash(repoPath, undefined, cancellation),\n\t\t\t\t);\n\t\t\t\tstashes = converted.stashes;\n\t\t\t\t// `--all` already surfaces refs/stash's tip on its own, so when merges-only there's no need\n\t\t\t\t// to walk the rest of the stash stack via stdin -- parseCommits still excludes any stash\n\t\t\t\t// sha that slips through via refs/stash\n\t\t\t\tstdin = mergesOnly ? undefined : converted.stdin;\n\t\t\t} else if (mergesOnly) {\n\t\t\t\t// `ref:` skips walking stashes into the results (they're unrelated to the ref), but a\n\t\t\t\t// stash's tip can still leak in via `--merges` if the ref reaches refs/stash -- fetch\n\t\t\t\t// stashes here purely so parseCommits can exclude them, without widening the walk via\n\t\t\t\t// stdin\n\t\t\t\tstashes = convertStashesToStdin(\n\t\t\t\t\tawait this.provider.stash?.getStash(repoPath, undefined, cancellation),\n\t\t\t\t).stashes;\n\t\t\t}\n\n\t\t\tif (stdin) {\n\t\t\t\targs.push('--stdin');\n\t\t\t}\n\n\t\t\tconst limit = options?.limit ?? cfg?.search?.maxItems ?? 0;\n\t\t\tif (limit && !shas?.size) {\n\t\t\t\targs.push(`-n${limit + 1}`);\n\t\t\t}\n\n\t\t\tconst ordering = options?.ordering ?? cfg?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\tif (options?.skip) {\n\t\t\t\targs.push(`--skip=${options.skip}`);\n\t\t\t}\n\n\t\t\t// Add the search args, but skip any shas (as they are already included in the stdin)\n\t\t\tfor (const arg of searchArgs) {\n\t\t\t\tif (shas?.has(arg) || args.includes(arg)) continue;\n\n\t\t\t\targs.push(arg);\n\t\t\t}\n\n\t\t\tconst pathspec = files?.join(' ');\n\t\t\tconst { commits, count, countStashChildCommits } = await parseCommits(\n\t\t\t\tparser,\n\t\t\t\tthis.git.stream(\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\t\tconfigs: ['-C', repoPath, ...gitConfigsLog],\n\t\t\t\t\t\tstdin: stdin,\n\t\t\t\t\t},\n\t\t\t\t\t...args,\n\t\t\t\t\t'--',\n\t\t\t\t\t...files,\n\t\t\t\t),\n\t\t\t\trepoPath,\n\t\t\t\tpathspec,\n\t\t\t\tlimit,\n\t\t\t\tstashes,\n\t\t\t\tcurrentUser,\n\t\t\t\tfilters,\n\t\t\t\tmergesOnly,\n\t\t\t);\n\n\t\t\tconst log: GitLog = {\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tcommits: commits,\n\t\t\t\tsha: undefined,\n\t\t\t\tsearchFilters: filters,\n\t\t\t\tcount: commits.size,\n\t\t\t\tlimit: limit,\n\t\t\t\thasMore: count - countStashChildCommits > commits.size,\n\t\t\t\tquery: (limit: number | undefined) =>\n\t\t\t\t\tthis.searchCommits(repoPath, search, { ...options, limit: limit }).then(r => r.log),\n\t\t\t};\n\n\t\t\tif (log.hasMore) {\n\t\t\t\tconst searchCommitsCore = (log: GitLog): ((limit: number | undefined) => Promise<GitLog>) => {\n\t\t\t\t\treturn async (limit: number | undefined) => {\n\t\t\t\t\t\tlimit = limit ?? 0;\n\n\t\t\t\t\t\tconst moreLog = (\n\t\t\t\t\t\t\tawait this.searchCommits(log.repoPath, search, {\n\t\t\t\t\t\t\t\t...options,\n\t\t\t\t\t\t\t\tlimit: limit,\n\t\t\t\t\t\t\t\tskip: log.count,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t).log;\n\t\t\t\t\t\t// If we can't find any more, assume we have everything\n\t\t\t\t\t\tif (moreLog == null) return { ...log, hasMore: false, more: undefined };\n\n\t\t\t\t\t\tconst commits = new Map([...log.commits, ...moreLog.commits]);\n\n\t\t\t\t\t\tconst mergedLog: GitLog = {\n\t\t\t\t\t\t\trepoPath: log.repoPath,\n\t\t\t\t\t\t\tcommits: commits,\n\t\t\t\t\t\t\tsha: log.sha,\n\t\t\t\t\t\t\tsearchFilters: filters,\n\t\t\t\t\t\t\tcount: commits.size,\n\t\t\t\t\t\t\tlimit: (log.limit ?? 0) + limit,\n\t\t\t\t\t\t\thasMore: moreLog.hasMore,\n\t\t\t\t\t\t\tquery: (limit: number | undefined) =>\n\t\t\t\t\t\t\t\tthis.searchCommits(log.repoPath, search, { ...options, limit: limit }).then(r => r.log),\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (mergedLog.hasMore) {\n\t\t\t\t\t\t\tmergedLog.more = searchCommitsCore(mergedLog);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn mergedLog;\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\tlog.more = searchCommitsCore(log);\n\t\t\t}\n\n\t\t\treturn { search: search, log: log };\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn { search: search, log: undefined };\n\t\t}\n\t}\n\n\t@debug()\n\tasync getCommitSignature(repoPath: string, sha: string): Promise<CommitSignature | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\terrors: 'ignore',\n\t\t\t\t\tcaching: {\n\t\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\t\toptions: { accessTTL: isSha(sha) ? 5 * 60 * 1000 : 60 * 1000 },\n\t\t\t\t\t},\n\t\t\t\t\tconfigs: gitConfigsLog,\n\t\t\t\t},\n\t\t\t\t'log',\n\t\t\t\t`--format=${signatureFormat}`,\n\t\t\t\t'-1',\n\t\t\t\tsha,\n\t\t\t);\n\n\t\t\tif (!result.stdout) return undefined;\n\n\t\t\treturn parseSignatureOutput(result.stdout);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug()\n\tasync isCommitSigned(repoPath: string, sha: string): Promise<boolean> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\terrors: 'ignore',\n\t\t\t\t\tcaching: {\n\t\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\t\toptions: { accessTTL: isSha(sha) ? 5 * 60 * 1000 : 60 * 1000 },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t'cat-file',\n\t\t\t\t'commit',\n\t\t\t\tsha,\n\t\t\t);\n\t\t\treturn /^gpgsig(-sha256)? /m.test(result.stdout);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getCommitsSshSigners(repoPath: string, shas: string[]): Promise<Map<string, SshSignedCommit>> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst result = new Map<string, SshSignedCommit>();\n\t\tif (shas.length === 0) return result;\n\n\t\ttry {\n\t\t\t// Read every commit object in a single `cat-file --batch` process (the SHAs are piped to stdin) rather than\n\t\t\t// spawning one `git` per commit — the embedded SSH signature and committer identity are then parsed from\n\t\t\t// each raw object, avoiding a separate (and far heavier) `git log` pass to enumerate identities.\n\t\t\tconst data = await this.git.run<Buffer>(\n\t\t\t\t{ cwd: repoPath, errors: 'ignore', stdin: `${shas.join('\\n')}\\n`, encoding: 'buffer' },\n\t\t\t\t'cat-file',\n\t\t\t\t'--batch',\n\t\t\t);\n\t\t\tparseCatFileBatchForSshSigners(data.stdout, new Set(shas), result);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Parses `git cat-file --batch` output, extracting the embedded SSH public key (if any) from each requested commit\n * object. Each record is `<sha> <type> <size>` LF `<content>` LF (or `<sha> missing` LF), and the object's bytes are\n * consumed using the header's `<size>` rather than scanned line-by-line — so a commit/tag body line that happens to\n * look like an object header can never be misread as a boundary. Operates on the raw `Buffer` because `<size>` counts\n * bytes, not decoded characters.\n *\n * Exported for unit testing.\n */\nexport function parseCatFileBatchForSshSigners(\n\tstdout: Buffer,\n\trequestedShas: Set<string>,\n\tout: Map<string, SshSignedCommit>,\n): void {\n\tconst headerRegex = /^([0-9a-f]{40,64}) (commit|tag|blob|missing)(?: (\\d+))?$/;\n\n\tlet offset = 0;\n\twhile (offset < stdout.length) {\n\t\tconst newline = stdout.indexOf(0x0a, offset);\n\t\tif (newline === -1) break;\n\n\t\tconst match = headerRegex.exec(stdout.toString('utf8', offset, newline));\n\t\toffset = newline + 1;\n\t\t// A missing object (or an unrecognizable header) has no content body following its header line.\n\t\tif (match == null || match[2] === 'missing') continue;\n\n\t\tconst sha = match[1];\n\t\tconst object = stdout.toString('utf8', offset, offset + Number(match[3]));\n\t\toffset += Number(match[3]) + 1; // consume the object's bytes and the trailing newline that separates records\n\n\t\tif (!requestedShas.has(sha)) continue;\n\n\t\tconst key = extractSshPublicKeyFromCommitObject(object);\n\t\tif (key == null) continue;\n\n\t\tconst committer = extractCommitterFromCommitObject(object);\n\t\tout.set(sha, { key: key, name: committer?.name, email: committer?.email });\n\t}\n}\n\nfunction toCommit(c: ParsedCommit, repoPath: string, pathspec: string | undefined, currentUser: GitUser | undefined) {\n\tconst message = c.message.trim();\n\tconst index = message.indexOf('\\n');\n\n\tconst isCurrentAuthor = isUserMatch(currentUser, c.author, c.authorEmail) || undefined;\n\tconst isCurrentCommitter = isUserMatch(currentUser, c.committer, c.committerEmail) || undefined;\n\n\treturn new GitCommit(\n\t\trepoPath,\n\t\tc.sha,\n\t\tnew GitCommitIdentity(\n\t\t\tc.author,\n\t\t\tc.authorEmail,\n\t\t\tnew Date(Number(c.authorDate) * 1000),\n\t\t\tundefined,\n\t\t\tisCurrentAuthor,\n\t\t),\n\t\tnew GitCommitIdentity(\n\t\t\tc.committer,\n\t\t\tc.committerEmail,\n\t\t\tnew Date(Number(c.committerDate) * 1000),\n\t\t\tundefined,\n\t\t\tisCurrentCommitter,\n\t\t),\n\t\tindex !== -1 ? message.substring(0, index) : message,\n\t\tc.parents?.split(' ') ?? [],\n\t\tmessage,\n\t\tcreateCommitFileset(c, repoPath, pathspec),\n\t\tc.stats,\n\t\tundefined,\n\t\tc.tips?.split(' '),\n\t);\n}\n\nfunction getGitStartEnd(range: DiffRange): [number, number] {\n\t// Library DiffRange is always 1-based, startLine <= endLine\n\treturn [range.startLine, range.endLine];\n}\n\nasync function parseCommits(\n\tparser: CommitsLogParser | CommitsWithFilesLogParser | CommitsInFileRangeLogParser,\n\tresultOrStream: Promise<GitResult> | AsyncGenerator<string>,\n\trepoPath: string,\n\tpathspec: string | undefined,\n\tlimit: number | undefined,\n\tstashes: Map<string, GitStashCommit> | undefined,\n\tcurrentUser: GitUser | undefined,\n\tsearchFilters?: SearchQueryFilters,\n\t// Stash commits have 2-3 parents, so `--merges` matches them; excluded below. Passed in by the\n\t// caller (derived from the args git actually runs) rather than re-derived from `searchFilters.type`\n\t// here, since a multi-value `type:` query (e.g. `type:merge type:tip`) leaves `--merges` in the\n\t// args while `searchFilters.type` reflects only the last value parsed\n\tmergesOnly: boolean = false,\n): Promise<{ commits: Map<string, GitCommit>; count: number; countStashChildCommits: number }> {\n\tlet count = 0;\n\tlet countStashChildCommits = 0;\n\tconst commits = new Map<string, GitCommit>();\n\n\tconst tipsOnly = searchFilters?.type === 'tip';\n\n\tif (resultOrStream instanceof Promise) {\n\t\tconst scope = getScopedLogger();\n\t\tconst result = await resultOrStream;\n\n\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\tif (stashes?.size) {\n\t\t\tconst allowFilteredFiles = searchFilters?.files ?? false;\n\t\t\tconst stashesOnly = searchFilters?.type === 'stash';\n\n\t\t\tfor (const c of parser.parse(result.stdout)) {\n\t\t\t\tif (stashesOnly && !stashes?.has(c.sha)) continue;\n\t\t\t\tif (mergesOnly && stashes?.has(c.sha)) continue;\n\t\t\t\tif (tipsOnly && !c.tips) continue;\n\n\t\t\t\tcount++;\n\t\t\t\tif (limit && count > limit) break;\n\n\t\t\t\tconst stash = stashes?.get(c.sha);\n\t\t\t\tif (stash != null) {\n\t\t\t\t\tif (commits.has(stash.sha)) {\n\t\t\t\t\t\tcountStashChildCommits++;\n\t\t\t\t\t} else if (allowFilteredFiles) {\n\t\t\t\t\t\tcommits.set(\n\t\t\t\t\t\t\tstash.sha,\n\t\t\t\t\t\t\tstash.with({\n\t\t\t\t\t\t\t\tfileset: {\n\t\t\t\t\t\t\t\t\t...createCommitFileset(c, repoPath, pathspec),\n\t\t\t\t\t\t\t\t\t// Add the full stash files back into the fileset\n\t\t\t\t\t\t\t\t\tfiles: stash.fileset?.files,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcommits.set(stash.sha, stash);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tcommits.set(c.sha, toCommit(c, repoPath, pathspec, currentUser));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const c of parser.parse(result.stdout)) {\n\t\t\t\tif (tipsOnly && !c.tips) continue;\n\n\t\t\t\tcount++;\n\t\t\t\tif (limit && count > limit) break;\n\n\t\t\t\tcommits.set(c.sha, toCommit(c, repoPath, pathspec, currentUser));\n\t\t\t}\n\t\t}\n\n\t\tsw?.stop({ suffix: ` created ${count} commits` });\n\n\t\treturn { commits: commits, count: count, countStashChildCommits: countStashChildCommits };\n\t}\n\n\tusing _streamDisposer = createDisposable(() => void resultOrStream.return?.(undefined));\n\n\tif (stashes?.size) {\n\t\tconst allowFilteredFiles = searchFilters?.files ?? false;\n\t\tconst stashesOnly = searchFilters?.type === 'stash';\n\n\t\tfor await (const c of parser.parseAsync(resultOrStream)) {\n\t\t\tif (stashesOnly && !stashes?.has(c.sha)) continue;\n\t\t\tif (mergesOnly && stashes?.has(c.sha)) continue;\n\t\t\tif (tipsOnly && !c.tips) continue;\n\n\t\t\tcount++;\n\t\t\tif (limit && count > limit) break;\n\n\t\t\tconst stash = stashes?.get(c.sha);\n\t\t\tif (stash != null) {\n\t\t\t\tif (commits.has(stash.sha)) {\n\t\t\t\t\tcountStashChildCommits++;\n\t\t\t\t} else if (allowFilteredFiles) {\n\t\t\t\t\tcommits.set(\n\t\t\t\t\t\tstash.sha,\n\t\t\t\t\t\tstash.with({\n\t\t\t\t\t\t\tfileset: {\n\t\t\t\t\t\t\t\t...createCommitFileset(c, repoPath, pathspec),\n\t\t\t\t\t\t\t\t// Add the full stash files back into the fileset\n\t\t\t\t\t\t\t\tfiles: stash.fileset?.files,\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} else {\n\t\t\t\t\tcommits.set(stash.sha, stash);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcommits.set(c.sha, toCommit(c, repoPath, pathspec, currentUser));\n\t\t}\n\t} else {\n\t\tfor await (const c of parser.parseAsync(resultOrStream)) {\n\t\t\tif (tipsOnly && !c.tips) continue;\n\n\t\t\tcount++;\n\t\t\tif (limit && count > limit) break;\n\n\t\t\tcommits.set(c.sha, toCommit(c, repoPath, pathspec, currentUser));\n\t\t}\n\t}\n\n\treturn { commits: commits, count: count, countStashChildCommits: countStashChildCommits };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"commits.js","names":["chunk","chunkArray"],"sources":["../../../../git-cli/src/providers/commits.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { SigningError } from '@gitlens/git/errors.js';\nimport type { GitBlame } from '@gitlens/git/models/blame.js';\nimport type { GitStashCommit } from '@gitlens/git/models/commit.js';\nimport { GitCommit, GitCommitIdentity } from '@gitlens/git/models/commit.js';\nimport type { GitDiffFilter, ParsedGitDiffHunks } from '@gitlens/git/models/diff.js';\nimport { GitFileChange } from '@gitlens/git/models/fileChange.js';\nimport type { GitFileStatus } from '@gitlens/git/models/fileStatus.js';\nimport type { GitLog } from '@gitlens/git/models/log.js';\nimport type { GitReflog } from '@gitlens/git/models/reflog.js';\nimport type { GitRevisionRange } from '@gitlens/git/models/revision.js';\nimport type { SearchQuery, SearchQueryFilters } from '@gitlens/git/models/search.js';\nimport type { CommitSignature, SigningFormat, SshSignedCommit } from '@gitlens/git/models/signature.js';\nimport type { GitUser } from '@gitlens/git/models/user.js';\nimport type {\n\tGitCommitReachability,\n\tGitCommitsSubProvider,\n\tGitLogForPathOptions,\n\tGitLogOptions,\n\tGitLogShasOptions,\n\tGitRefExclusions,\n\tGitSearchCommitsOptions,\n\tIncomingActivityOptions,\n\tLeftRightCommitCountResult,\n\tSearchCommitsResult,\n} from '@gitlens/git/providers/commits.js';\nimport type { DiffRange } from '@gitlens/git/providers/types.js';\nimport type { GitCommandPriority } from '@gitlens/git/run.types.js';\nimport { createUncommittedChangesCommit } from '@gitlens/git/utils/commit.utils.js';\nimport { isRevisionRange, isSha, isUncommitted, isUncommittedStaged } from '@gitlens/git/utils/revision.utils.js';\nimport { parseSearchQueryGitCommand } from '@gitlens/git/utils/search.utils.js';\nimport { compareReachableRefs } from '@gitlens/git/utils/sorting.js';\nimport { isUserMatch } from '@gitlens/git/utils/user.utils.js';\nimport { chunk as chunkArray } from '@gitlens/utils/array.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { debug, trace } from '@gitlens/utils/decorators/log.js';\nimport { createDisposable } from '@gitlens/utils/disposable.js';\nimport { filterMap, findLast, first, join, last, some } from '@gitlens/utils/iterable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { isFolderGlob, normalizePath, splitPath, stripFolderGlob } from '@gitlens/utils/path.js';\nimport type { CacheController } from '@gitlens/utils/promiseCache.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport { escapeRegex, iterateByDelimiter } from '@gitlens/utils/string.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fileUri, joinUriPath, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult, GitRunOptions } from '../exec/exec.types.js';\nimport type { Git, GitError } from '../exec/git.js';\nimport { classifySigningError, gitConfigsLog, gitConfigsLogWithFiles, GitErrors } from '../exec/git.js';\nimport type {\n\tCommitsInFileRangeLogParser,\n\tCommitsLogParser,\n\tCommitsWithFilesLogParser,\n\tParsedCommit,\n} from '../parsers/logParser.js';\nimport {\n\tgetCommitsLogParser,\n\tgetShaAndDatesLogParser,\n\tgetShaAndFilesAndStatsLogParser,\n\tgetShaLogParser,\n} from '../parsers/logParser.js';\nimport { getReflogParser, parseGitRefLog } from '../parsers/reflogParser.js';\nimport { parseSignatureOutput, signatureFormat } from '../parsers/signatureParser.js';\nimport {\n\textractCommitterFromCommitObject,\n\textractSshPublicKeyFromCommitObject,\n} from '../parsers/sshSignatureParser.js';\nimport { createCommitFileset } from './commitFilesetUtils.js';\nimport { convertStashesToStdin } from './stash.js';\n\nconst emptyPromise: Promise<GitBlame | ParsedGitDiffHunks | GitLog | undefined> = Promise.resolve(undefined);\nconst reflogCommands = ['merge', 'pull'];\n/** Keeps `filterUnpublishedShas` well inside Windows' ~32K command-line cap (40 hex chars + separator each). */\nconst maxShasPerRevListSpawn = 500;\nconst fullShaRegex = /^[0-9a-f]{40}$/;\n/** Bounds the diff text held in memory, and piped to `patch-id`, per `diff-tree` spawn. */\nconst maxCommitsPerPatchIdSpawn = 250;\n\n/**\n * Plumbing diff with every output knob pinned, so no user diff config can change what a patch id hashes.\n * `--full-index` is load-bearing: a binary change is hashed through its blob oids, which must be unabbreviated.\n * Plumbing still reads `diff.indentHeuristic`, which can slide a hunk, so the heuristic is named rather than defaulted.\n */\nconst patchIdDiffArgs = [\n\t'diff-tree',\n\t'-p',\n\t'--full-index',\n\t'--indent-heuristic',\n\t'--no-color',\n\t'--no-ext-diff',\n\t'--no-textconv',\n\t'--no-renames',\n] as const;\n\n/**\n * The other diff setting plumbing reads: a blank context line printed without its leading space is counted by\n * `patch-id` as neither side of the hunk, so the hunk never ends and the next file's header is hashed into it.\n */\nconst patchIdDiffConfigs = ['-c', 'diff.suppressBlankEmpty=false'] as const;\n\n/**\n * `GIT_DIFF_OPTS` overrides even an explicit `-U<n>`, changing the context lines a patch id hashes, so it is\n * unset. Literal pathspecs keep a caller's path from being read as a glob or pathspec magic.\n */\nconst patchIdEnv: Readonly<Record<string, string | undefined>> = {\n\tGIT_DIFF_OPTS: undefined,\n\tGIT_LITERAL_PATHSPECS: '1',\n};\n\n/**\n * The part of a patch id's cache key after its sha. Order and duplicates in `paths` never change the diff, so they\n * must not split the key, and the paths are hashed so a long list isn't held again by every cached commit.\n */\nfunction getPatchIdCacheKeySuffix(paths: readonly string[] | undefined, verbatim: boolean | undefined): string {\n\tconst mode = verbatim ? 'v' : 's';\n\tif (!paths?.length) return `\\0${mode}`;\n\n\treturn `\\0${mode}\\0${createHash('sha256')\n\t\t.update([...new Set(paths)].sort().join('\\0'))\n\t\t.digest('hex')}`;\n}\n\nconst refExclusionNamespaces = [\n\t['branches', 'refs/heads/', '--branches'],\n\t['remotes', 'refs/remotes/', '--remotes'],\n\t['tags', 'refs/tags/', '--tags'],\n] as const;\n\n/**\n * Each `except` entry is emitted in its short form right before its own namespace's pseudo-ref: git matches\n * `--exclude` against the short name and applies it only to the next pseudo-ref, so `--exclude=refs/heads/x\n * --branches` excludes nothing.\n */\nfunction getRefExclusionArgs(excluding: GitRefExclusions | undefined): string[] {\n\tif (excluding == null) return [];\n\n\tconst args: string[] = [];\n\tfor (const [key, prefix, flag] of refExclusionNamespaces) {\n\t\tif (!excluding[key]) continue;\n\n\t\tfor (const ref of excluding.except ?? []) {\n\t\t\tif (ref.startsWith(prefix)) {\n\t\t\t\targs.push(`--exclude=${ref.slice(prefix.length)}`);\n\t\t\t}\n\t\t}\n\t\targs.push(flag);\n\t}\n\n\tif (excluding.refs?.length) {\n\t\targs.push(...excluding.refs);\n\t}\n\n\treturn args.length ? ['--not', ...args] : [];\n}\n\nfunction getRefExclusionsKey(excluding: GitRefExclusions): string {\n\tconst { branches, remotes, tags, refs, except } = excluding;\n\treturn JSON.stringify([branches, remotes, tags, refs, except]);\n}\n\nfunction getCommitCountKey(rev: string, excluding: GitRefExclusions | undefined): string {\n\tif (excluding == null) return rev;\n\n\treturn `${rev}\\0${getRefExclusionsKey(excluding)}`;\n}\n\nexport class CommitsGitSubProvider implements GitCommitsSubProvider {\n\tconstructor(\n\t\tprivate readonly context: GitServiceContext,\n\t\tprivate readonly git: Git,\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: CliGitProviderInternal,\n\t) {}\n\n\t/**\n\t * Creates a commit object from a tree via `commit-tree`, with explicit (zero or more) parents and an\n\t * optional explicit author/committer — e.g. for merge commits assembled from multiple parents, or a\n\t * commit authored on behalf of someone else. Writes the commit object only; it updates no ref, so the\n\t * result is unreachable until a caller points a branch/ref at it. Fires no ref-change hooks — an\n\t * unreachable object changes no ref, so there's nothing for a cache or watcher to invalidate yet.\n\t */\n\t@debug()\n\tasync createCommitFromTree(\n\t\trepoPath: string,\n\t\ttree: string,\n\t\toptions: {\n\t\t\tparents: string[];\n\t\t\tmessage: string;\n\t\t\tauthor?: { name: string; email: string; date?: Date | string };\n\t\t\tcommitter?: { name: string; email: string; date?: Date | string };\n\t\t\tsign?: boolean;\n\t\t\tsource?: unknown;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<string> {\n\t\tconst args = ['commit-tree', tree];\n\t\tfor (const parent of options.parents) {\n\t\t\targs.push('-p', parent);\n\t\t}\n\n\t\tlet format: SigningFormat = 'gpg';\n\t\tif (options.sign) {\n\t\t\tconst signingConfig = await this.provider.config.getSigningConfig?.(repoPath);\n\t\t\tformat = signingConfig?.format ?? 'gpg';\n\t\t\targs.push('-S');\n\t\t}\n\t\targs.push('-F', '-');\n\n\t\tconst env: Record<string, string> = {};\n\t\tif (options.author) {\n\t\t\tenv.GIT_AUTHOR_NAME = options.author.name;\n\t\t\tenv.GIT_AUTHOR_EMAIL = options.author.email;\n\t\t\tif (options.author.date != null) {\n\t\t\t\tenv.GIT_AUTHOR_DATE =\n\t\t\t\t\ttypeof options.author.date === 'string' ? options.author.date : options.author.date.toISOString();\n\t\t\t}\n\t\t}\n\t\tif (options.committer) {\n\t\t\tenv.GIT_COMMITTER_NAME = options.committer.name;\n\t\t\tenv.GIT_COMMITTER_EMAIL = options.committer.email;\n\t\t\tif (options.committer.date != null) {\n\t\t\t\tenv.GIT_COMMITTER_DATE =\n\t\t\t\t\ttypeof options.committer.date === 'string'\n\t\t\t\t\t\t? options.committer.date\n\t\t\t\t\t\t: options.committer.date.toISOString();\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\terrors: 'throw',\n\t\t\t\t\tenv: env,\n\t\t\t\t\t// `-F -` stores the message byte-for-byte, where `-m` terminates it with a newline —\n\t\t\t\t\t// keep that, or the same inputs write a different commit object.\n\t\t\t\t\tstdin:\n\t\t\t\t\t\t!options.message || options.message.endsWith('\\n') ? options.message : `${options.message}\\n`,\n\t\t\t\t\tstdinEncoding: 'utf8',\n\t\t\t\t},\n\t\t\t\t...args,\n\t\t\t);\n\t\t\tconst sha = result.stdout.trim();\n\n\t\t\tif (options.sign) {\n\t\t\t\tthis.context.hooks?.commits?.onSigned?.(format, options.source);\n\t\t\t}\n\n\t\t\treturn sha;\n\t\t} catch (ex) {\n\t\t\tif (options.sign) {\n\t\t\t\tconst reason = classifySigningError(ex);\n\t\t\t\tif (reason != null) {\n\t\t\t\t\tthis.context.hooks?.commits?.onSigningFailed?.(reason, format, options.source);\n\t\t\t\t\tthrow new SigningError(\n\t\t\t\t\t\t{ reason: reason, gitCommand: { repoPath: repoPath, args: ['commit-tree'] } },\n\t\t\t\t\t\tex as GitError,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getCommit(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<GitCommit | undefined> {\n\t\tif (isUncommitted(rev, true)) {\n\t\t\treturn createUncommittedChangesCommit(\n\t\t\t\trepoPath,\n\t\t\t\trev,\n\t\t\t\tnew Date(),\n\t\t\t\tawait this.provider.config.getCurrentUser(repoPath),\n\t\t\t);\n\t\t}\n\n\t\tconst log = await this.getLogCore(repoPath, rev, { limit: 1 }, cancellation);\n\t\tif (log == null) return undefined;\n\n\t\treturn log.commits.get(rev) ?? first(log.commits.values());\n\t}\n\n\t@debug({ exit: true })\n\tgetCommitCount(\n\t\trepoPath: string,\n\t\trev: string,\n\t\toptions?: { excluding?: GitRefExclusions },\n\t\tcancellation?: AbortSignal,\n\t): Promise<number | undefined> {\n\t\tconst excludeArgs = getRefExclusionArgs(options?.excluding);\n\n\t\treturn this.cache.commitCount.getOrCreate(\n\t\t\trepoPath,\n\t\t\tgetCommitCountKey(rev, options?.excluding),\n\t\t\tasync (cacheable, signal) => {\n\t\t\t\t// Bind the shared spawn to the aggregate `signal` (fires only when ALL current callers\n\t\t\t\t// abort), not this-caller's `cancellation` — otherwise a superseded caller's abort would\n\t\t\t\t// kill the shared command and reject concurrent riders that never cancelled.\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: signal ?? cancellation, errors: 'ignore' },\n\t\t\t\t\t'rev-list',\n\t\t\t\t\t'--count',\n\t\t\t\t\trev,\n\t\t\t\t\t...excludeArgs,\n\t\t\t\t\t'--',\n\t\t\t\t);\n\t\t\t\tif (result.completion.status === 'cancelled' || signal?.aborted) {\n\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t}\n\n\t\t\t\t// `errors: 'ignore'` turns a failed run (unknown rev, a transient `index.lock`) into an\n\t\t\t\t// empty stdout rather than a throw. That's indistinguishable from a real answer here, so\n\t\t\t\t// don't let it become a cached one — this entry has a sliding hour-long TTL, and repeated\n\t\t\t\t// access would keep a transient failure alive indefinitely. The pre-cache implementation\n\t\t\t\t// simply retried on the next call; invalidating restores that.\n\t\t\t\t//\n\t\t\t\t// BOTH conditions, not either alone. `exitCode !== 0` catches \"git ran and said no\" (a bad\n\t\t\t\t// rev exits 128); `status !== 'exited'` catches \"git never answered\" — a queue rejection or\n\t\t\t\t// spawn failure (no exit code at all), or a swallowed `GitWarnings` match, which carries git's\n\t\t\t\t// real code and so can slip past the exit-code test on its own.\n\t\t\t\tif (result.completion.status !== 'exited' || result.exitCode !== 0) {\n\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tconst data = result.stdout.trim();\n\t\t\t\tif (!data) return undefined;\n\n\t\t\t\tconst count = parseInt(data, 10);\n\t\t\t\treturn isNaN(count) ? undefined : count;\n\t\t\t},\n\t\t\t{ cancellation: cancellation },\n\t\t);\n\t}\n\n\t@debug({ exit: true })\n\tasync hasUnpublishedCommits(\n\t\trepoPath: string,\n\t\trev: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean | undefined> {\n\t\t// `<rev> --not --remotes` = commits reachable from `rev` but not from any remote-tracking ref.\n\t\t// `--max-count=1` early-exits at the first such commit, so this is a presence probe, not a count.\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t'rev-list',\n\t\t\t'--max-count=1',\n\t\t\trev,\n\t\t\t'--not',\n\t\t\t'--remotes',\n\t\t\t'--',\n\t\t);\n\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\tthrow new CancellationError();\n\t\t}\n\n\t\treturn result.stdout.trim().length > 0;\n\t}\n\n\t@debug({\n\t\targs: (repoPath, shas) => ({ repoPath: repoPath, shas: `${shas.length} value(s)` }),\n\t\texit: r => `${r.size} unpublished`,\n\t})\n\tasync filterUnpublishedShas(\n\t\trepoPath: string,\n\t\tshas: readonly string[],\n\t\toptions?: { priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<Set<string>> {\n\t\tconst unpublished = new Set<string>();\n\t\tif (!shas.length) return unpublished;\n\n\t\t// One walk answers every sha: `<shas…> --not --remotes` yields the commits reachable from any of them\n\t\t// but not from any remote-tracking ref, so a sha is unpublished exactly when it appears in the output.\n\t\t// Callers pass tips from sibling worktrees — safe from a single `cwd` because the object store and\n\t\t// `refs/remotes` are shared across a repo's worktrees (unlike the index/working tree, which are not).\n\t\t//\n\t\t// NOT `--no-walk`: it \"has no effect if a range is specified\", and `--not --remotes` makes this a range,\n\t\t// so it would silently walk anyway and return the whole unpublished history instead of just these tips.\n\t\t// The walk is bounded by divergence from the remotes, not by repo size; callers skip this entirely when\n\t\t// the repo has no remotes (where every local commit would qualify).\n\t\t// Chunked so a repo with a very large number of worktrees can't overflow the platform's argument\n\t\t// limit (Windows' `CreateProcess` caps the whole command line at ~32K characters).\n\t\t// Deliberately NOT `errors: 'ignore'`: this answers for EVERY sha at once, so a swallowed failure\n\t\t// would return an empty set the caller can't distinguish from \"nothing is unpublished\", publishing a\n\t\t// confident `hasUnpushed: false` across every worktree in the batch. Letting it throw degrades the\n\t\t// caller to \"unknown\", which omits the field and leaves the client's last-known value in place.\n\t\tfor (const chunk of chunkArray([...shas], maxShasPerRevListSpawn)) {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t\t},\n\t\t\t\t'rev-list',\n\t\t\t\t...chunk,\n\t\t\t\t'--not',\n\t\t\t\t'--remotes',\n\t\t\t\t'--',\n\t\t\t);\n\t\t\t// Anything but a clean exit leaves empty stdout, which this function would otherwise read as\n\t\t\t// \"every sha is published\" — publishing a definite, wrong `hasUnpushed: false` for the whole\n\t\t\t// batch. Dropping `errors: 'ignore'` was not enough on its own: a stderr matching `GitWarnings`\n\t\t\t// (a repo path that briefly vanished, an unknown rev) is swallowed by the default handler and\n\t\t\t// resolves rather than throwing. Rethrow so the caller degrades to \"unknown\".\n\t\t\tif (result.completion.status !== 'exited') throw result.completion.error;\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\tconst candidates = new Set(chunk);\n\t\t\tfor (const line of iterateByDelimiter(result.stdout, '\\n')) {\n\t\t\t\tconst sha = line.trim();\n\t\t\t\t// The walk emits ancestors too; keep only the tips we were asked about.\n\t\t\t\tif (sha.length && candidates.has(sha)) {\n\t\t\t\t\tunpublished.add(sha);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn unpublished;\n\t}\n\n\t@debug({ exit: true })\n\tasync getCommitDates(\n\t\trepoPath: string,\n\t\trev: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<{ authorDate: Date; committerDate: Date } | undefined> {\n\t\tconst parser = getShaAndDatesLogParser();\n\t\tconst result = await this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\terrors: 'ignore',\n\t\t\t\t// Why: full SHAs identify immutable commits (5-min TTL is safe). Non-SHA refs rely on\n\t\t\t\t// gitResults being cleared on 'head'/'heads'/'remotes' events; the 60s TTL is the\n\t\t\t\t// failsafe for watcher latency / web (no fs watcher).\n\t\t\t\tcaching: {\n\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\toptions: { accessTTL: isSha(rev) ? 5 * 60 * 1000 : 60 * 1000 },\n\t\t\t\t},\n\t\t\t},\n\t\t\t'log',\n\t\t\t'-1',\n\t\t\t...parser.arguments,\n\t\t\trev,\n\t\t);\n\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) return undefined;\n\n\t\tfor (const entry of parser.parse(result.stdout)) {\n\t\t\tconst authorSeconds = Number(entry.authorDate);\n\t\t\tconst committerSeconds = Number(entry.committerDate);\n\t\t\tif (!Number.isFinite(authorSeconds) || !Number.isFinite(committerSeconds)) return undefined;\n\t\t\treturn {\n\t\t\t\tauthorDate: new Date(authorSeconds * 1000),\n\t\t\t\tcommitterDate: new Date(committerSeconds * 1000),\n\t\t\t};\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t@debug({\n\t\targs: (repoPath, revs, options) => ({\n\t\t\trepoPath: repoPath,\n\t\t\trevs: typeof revs === 'string' ? revs : `${revs.length} value(s)`,\n\t\t\toptions: options,\n\t\t}),\n\t\texit: r => (r != null ? `${r.size} patch id(s)` : 'unavailable'),\n\t})\n\tasync getCommitPatchIds(\n\t\trepoPath: string,\n\t\trevs: readonly string[] | GitRevisionRange,\n\t\toptions?: { paths?: readonly string[]; verbatim?: boolean; limit?: number },\n\t\tcancellation?: AbortSignal,\n\t): Promise<Map<string, string> | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif (options?.verbatim && !(await this.git.supports('git:patch-id:verbatim'))) return undefined;\n\n\t\ttry {\n\t\t\tconst shas = await this.resolvePatchIdCommitShas(repoPath, revs, options, cancellation);\n\t\t\tif (shas == null) return undefined;\n\n\t\t\tconst keySuffix = getPatchIdCacheKeySuffix(options?.paths, options?.verbatim);\n\t\t\tconst ids = new Map<string, string>();\n\t\t\tconst uncached: string[] = [];\n\t\t\tfor (const sha of shas) {\n\t\t\t\tconst cached = this.cache.patchIds.get(repoPath, `${sha}${keySuffix}`);\n\t\t\t\tif (cached == null) {\n\t\t\t\t\tuncached.push(sha);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst id = await cached;\n\t\t\t\tif (id != null) {\n\t\t\t\t\tids.set(sha, id);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// A shallow clone's boundary commits have parents that are merely not present, but `--root` would read them\n\t\t\t// as parentless, so their \"own change\" would be the whole tree. It is unknowable, so they are left out\n\t\t\t// and never cached, which also keeps a later deepening from finding a wrong ID cached.\n\t\t\tconst boundary = uncached.length ? await this.getShallowBoundary(repoPath, cancellation) : undefined;\n\t\t\tconst readable = boundary?.size ? uncached.filter(sha => !boundary.has(sha)) : uncached;\n\n\t\t\tconst diffArgs = await this.getPatchIdDiffArgs();\n\t\t\tfor (const batch of chunkArray(readable, maxCommitsPerPatchIdSpawn)) {\n\t\t\t\t// `diff-tree --stdin` silently prints nothing for an abbreviated sha, which is why callers' revisions are\n\t\t\t\t// resolved to full shas first. It prints nothing for a merge commit, or for a change that is empty after\n\t\t\t\t// `paths`, and `patch-id` then has no entry for it — which is the answer, so it is cached as such.\n\t\t\t\t// `--root` so a parentless commit's change is its whole tree rather than nothing.\n\t\t\t\tconst diff = await this.git.run<Buffer>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\t\tconfigs: patchIdDiffConfigs,\n\t\t\t\t\t\terrors: 'throw',\n\t\t\t\t\t\tencoding: 'buffer',\n\t\t\t\t\t\tenv: patchIdEnv,\n\t\t\t\t\t\tstdin: `${batch.join('\\n')}\\n`,\n\t\t\t\t\t},\n\t\t\t\t\t...diffArgs,\n\t\t\t\t\t'--root',\n\t\t\t\t\t'--stdin',\n\t\t\t\t\t...(options?.paths?.length ? ['--', ...options.paths] : []),\n\t\t\t\t);\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\tconst batchIds =\n\t\t\t\t\tdiff.stdout.length > 0\n\t\t\t\t\t\t? await this.computePatchIds(repoPath, diff.stdout, options?.verbatim, cancellation)\n\t\t\t\t\t\t: undefined;\n\t\t\t\t// Every patch in the input starts with its commit's sha, so an id under any other commit means\n\t\t\t\t// `patch-id` split a patch, leaving some commit with an id for only part of its change\n\t\t\t\tif (batchIds != null) {\n\t\t\t\t\tconst batchShas = new Set(batch);\n\t\t\t\t\tif (some(batchIds.keys(), commitId => !batchShas.has(commitId))) {\n\t\t\t\t\t\tthrow new Error('patch-id answered for a commit it was not given');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const sha of batch) {\n\t\t\t\t\tconst id = batchIds?.get(sha);\n\t\t\t\t\t// `getOrCreate` rather than `set`, since only it enforces the cache's capacity and expiry\n\t\t\t\t\tvoid this.cache.patchIds.getOrCreate(repoPath, `${sha}${keySuffix}`, () => Promise.resolve(id));\n\t\t\t\t\tif (id != null) {\n\t\t\t\t\t\tids.set(sha, id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ids;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/** The commits a shallow clone was cut at, read from the repository's common git directory so linked worktrees work. */\n\tprivate async getShallowBoundary(repoPath: string, cancellation: AbortSignal | undefined): Promise<Set<string>> {\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'throw' },\n\t\t\t'rev-parse',\n\t\t\t'--git-path',\n\t\t\t'shallow',\n\t\t);\n\t\tconst path = result.stdout.trim();\n\t\tif (!path) return new Set();\n\n\t\tconst contents = await this.context.fs\n\t\t\t.readFile(this.provider.getAbsoluteUri(path, repoPath))\n\t\t\t.catch((ex: unknown) => {\n\t\t\t\tconst code = (ex as { code?: unknown }).code;\n\t\t\t\t// No file is a repository that isn't shallow\n\t\t\t\tif (code === 'ENOENT' || code === 'FileNotFound') return undefined;\n\n\t\t\t\tthrow ex;\n\t\t\t});\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\treturn new Set(\n\t\t\tcontents == null\n\t\t\t\t? []\n\t\t\t\t: new TextDecoder()\n\t\t\t\t\t\t.decode(contents)\n\t\t\t\t\t\t.split(/\\s+/)\n\t\t\t\t\t\t.filter(s => s.length > 0),\n\t\t);\n\t}\n\n\t/**\n\t * Lists the full shas of the commits {@link getCommitPatchIds} reads diffs of, since `diff-tree --stdin` does not\n\t * accept abbreviated ones. A list of revisions that are all full shas is taken as is, and a merge commit among them\n\t * is dropped later by `diff-tree`. Resolves to `undefined` when more than `options.limit` commits match, never a\n\t * truncated list.\n\t */\n\tprivate async resolvePatchIdCommitShas(\n\t\trepoPath: string,\n\t\trevs: readonly string[] | GitRevisionRange,\n\t\toptions: { paths?: readonly string[]; limit?: number } | undefined,\n\t\tcancellation: AbortSignal | undefined,\n\t): Promise<string[] | undefined> {\n\t\tlet result: GitResult;\n\t\tif (typeof revs === 'string') {\n\t\t\t// Only a range, since a single revision would walk its whole history; any revision syntax is fine on\n\t\t\t// either side (`HEAD~3`, `@{u}`, a `#` or `+` in a branch name), so git, not a pattern, decides validity\n\t\t\tif (!revs.includes('..') || revs.startsWith('-')) return undefined;\n\n\t\t\t// `--full-history`: without it, history simplification can skip a side branch's commits that touch `paths`\n\t\t\tresult = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'throw', env: patchIdEnv },\n\t\t\t\t'rev-list',\n\t\t\t\t'--no-merges',\n\t\t\t\t'--full-history',\n\t\t\t\t// One past the limit, so exceeding it is detectable without walking the rest of a large history\n\t\t\t\toptions?.limit != null ? `--max-count=${options.limit + 1}` : undefined,\n\t\t\t\trevs,\n\t\t\t\t'--',\n\t\t\t\t...(options?.paths ?? []),\n\t\t\t);\n\t\t} else {\n\t\t\tif (!revs.length) return [];\n\t\t\t// An option or a newline in a revision would be read by `--stdin` as another revision or a pseudo-option,\n\t\t\t// and an exclusion or a range turns `--no-walk` off, walking history instead of naming commits\n\t\t\tif (revs.some(r => !r || r.startsWith('-') || r.startsWith('^') || r.includes('..') || r.includes('\\n'))) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// Full shas need no resolution, so `diff-tree --stdin` can read them directly: it prints nothing for a\n\t\t\t// merge commit (without `-m`/`-c`), so merges still drop out. Deduplicated since it would print a\n\t\t\t// repeated sha's diff twice, which `patch-id` would answer twice.\n\t\t\tif (revs.every(r => fullShaRegex.test(r))) {\n\t\t\t\tconst shas = [...new Set(revs)];\n\t\t\t\treturn options?.limit != null && shas.length > options.limit ? undefined : shas;\n\t\t\t}\n\n\t\t\t// `--no-walk` yields just these commits, peeling tags and resolving abbreviations; the trailing `--`\n\t\t\t// keeps a revision that is also a file name from being ambiguous. No `--max-count` here: it makes git\n\t\t\t// ignore `--no-walk` and list ancestors too, and the input already bounds the output.\n\t\t\tresult = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\terrors: 'throw',\n\t\t\t\t\tenv: patchIdEnv,\n\t\t\t\t\tstdin: `${revs.join('\\n')}\\n--\\n`,\n\t\t\t\t},\n\t\t\t\t'rev-list',\n\t\t\t\t'--no-merges',\n\t\t\t\t'--no-walk=unsorted',\n\t\t\t\t'--stdin',\n\t\t\t);\n\t\t}\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tconst shas = result.stdout\n\t\t\t.split('\\n')\n\t\t\t.map(l => l.trim())\n\t\t\t.filter(l => l.length > 0);\n\t\treturn options?.limit != null && shas.length > options.limit ? undefined : shas;\n\t}\n\n\t@debug({ exit: true })\n\tasync getDiffPatchId(\n\t\trepoPath: string,\n\t\tfrom: string,\n\t\tto: string,\n\t\toptions?: { paths?: readonly string[]; verbatim?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif (!from || !to || from.startsWith('-') || to.startsWith('-')) return undefined;\n\t\tif (options?.verbatim && !(await this.git.supports('git:patch-id:verbatim'))) return undefined;\n\n\t\ttry {\n\t\t\tconst diff = await this.git.run<Buffer>(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\tconfigs: patchIdDiffConfigs,\n\t\t\t\t\terrors: 'throw',\n\t\t\t\t\tencoding: 'buffer',\n\t\t\t\t\tenv: patchIdEnv,\n\t\t\t\t},\n\t\t\t\t...(await this.getPatchIdDiffArgs()),\n\t\t\t\tfrom,\n\t\t\t\tto,\n\t\t\t\t'--',\n\t\t\t\t...(options?.paths ?? []),\n\t\t\t);\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\t\t// No change prints nothing, and `patch-id` has nothing to answer for it\n\t\t\tif (!diff.stdout.length) return undefined;\n\n\t\t\treturn first((await this.computePatchIds(repoPath, diff.stdout, options?.verbatim, cancellation)).values());\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * A `patch-id` older than 2.39 hashes a binary diff's text rather than its blob ids, so only there is the binary\n\t * data worth reading: it is all that tells two changes to one binary file apart. Elsewhere it is ignored, and\n\t * would only bloat the diff held in memory and piped to `patch-id`.\n\t */\n\tprivate async getPatchIdDiffArgs(): Promise<readonly string[]> {\n\t\treturn (await this.git.supports('git:patch-id:binary-oids'))\n\t\t\t? patchIdDiffArgs\n\t\t\t: [...patchIdDiffArgs, '--binary'];\n\t}\n\n\t/**\n\t * Pipes `diff` through `patch-id`, answering patch id by the commit id on the diff's header line (all zeros when it\n\t * has none). Throws when a commit is answered twice: `patch-id` older than 2.39 splits a patch at a binary diff and\n\t * answers the rest separately, so neither id covers the whole change.\n\t */\n\tprivate async computePatchIds(\n\t\trepoPath: string,\n\t\tdiff: Buffer,\n\t\tverbatim: boolean | undefined,\n\t\tcancellation: AbortSignal | undefined,\n\t): Promise<Map<string, string>> {\n\t\t// An explicit flag always wins over `patchid.stable`/`patchid.verbatim`, so neither config can change the result\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'throw', stdin: diff },\n\t\t\t'patch-id',\n\t\t\tverbatim ? '--verbatim' : '--stable',\n\t\t);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tconst ids = new Map<string, string>();\n\t\tfor (const line of result.stdout.split('\\n')) {\n\t\t\tconst [patchId, commitId] = line.trim().split(' ');\n\t\t\tif (!patchId || !commitId) continue;\n\n\t\t\tif (ids.has(commitId)) throw new Error(`patch-id answered more than once for ${commitId}`);\n\n\t\t\tids.set(commitId, patchId);\n\t\t}\n\t\treturn ids;\n\t}\n\n\t@debug()\n\tasync getCommitFiles(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<GitFileChange[]> {\n\t\tconst parser = getShaAndFilesAndStatsLogParser();\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsLog },\n\t\t\t'log',\n\t\t\t...parser.arguments,\n\t\t\t'-n1',\n\t\t\trev && !isUncommittedStaged(rev) ? rev : undefined,\n\t\t\t'--',\n\t\t);\n\n\t\tconst repoUri = fileUri(normalizePath(repoPath));\n\t\tconst files = first(parser.parse(result.stdout))?.files.map(\n\t\t\tf =>\n\t\t\t\tnew GitFileChange(\n\t\t\t\t\trepoPath,\n\t\t\t\t\tf.path,\n\t\t\t\t\tf.status as GitFileStatus,\n\t\t\t\t\tjoinUriPath(repoUri, normalizePath(f.path)),\n\t\t\t\t\tf.originalPath,\n\t\t\t\t\tf.originalPath != null ? joinUriPath(repoUri, normalizePath(f.originalPath)) : undefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{ additions: f.additions, deletions: f.deletions, changes: 0 },\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\tf.mode,\n\t\t\t\t\tf.oid ? { oid: f.oid, previousOid: f.previousOid } : undefined,\n\t\t\t\t),\n\t\t);\n\n\t\treturn files ?? [];\n\t}\n\n\t@debug()\n\tasync getCommitForFile(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev?: string | undefined,\n\t\toptions?: { firstIfNotFound?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitCommit | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst [relativePath, root] = splitPath(toFsPath(pathOrUri), repoPath);\n\n\t\ttry {\n\t\t\tconst log = await this.getLogForPath(root, relativePath, rev, { limit: 1 }, cancellation);\n\t\t\tif (log == null) return undefined;\n\n\t\t\tlet commit;\n\t\t\tif (rev) {\n\t\t\t\tcommit = log.commits.get(rev);\n\t\t\t\tif (commit == null && !options?.firstIfNotFound) {\n\t\t\t\t\t// If the ref isn't a valid sha we will never find it, so let it fall through so we return the first\n\t\t\t\t\tif (isSha(rev) || isUncommitted(rev)) return undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn commit ?? first(log.commits.values());\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug()\n\tgetCommitReachability(\n\t\trepoPath: string,\n\t\trev: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitCommitReachability | undefined> {\n\t\tif (repoPath == null || isUncommitted(rev)) return Promise.resolve(undefined);\n\n\t\tconst scope = getScopedLogger();\n\n\t\tconst getCore = async (cacheable?: CacheController) => {\n\t\t\ttry {\n\t\t\t\t// Use for-each-ref with %(HEAD) to mark current branch with *\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t'for-each-ref',\n\t\t\t\t\t'--contains',\n\t\t\t\t\trev,\n\t\t\t\t\t'--format=%(HEAD)%(refname)',\n\t\t\t\t\t'--sort=-version:refname',\n\t\t\t\t\t'--sort=-committerdate',\n\t\t\t\t\t'--sort=-HEAD',\n\t\t\t\t\t'refs/heads/',\n\t\t\t\t\t'refs/remotes/',\n\t\t\t\t\t'refs/tags/',\n\t\t\t\t);\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\tconst refs: GitCommitReachability['refs'] = [];\n\n\t\t\t\t// Parse branches from refs/heads/ and refs/remotes/\n\t\t\t\tif (result?.stdout) {\n\t\t\t\t\tconst lines = result.stdout.split('\\n');\n\n\t\t\t\t\tfor (let line of lines) {\n\t\t\t\t\t\tline = line.trim();\n\t\t\t\t\t\tif (!line) continue;\n\n\t\t\t\t\t\t// %(HEAD) outputs '*' for current branch, ' ' for others\n\t\t\t\t\t\tconst isCurrent = line.startsWith('*');\n\t\t\t\t\t\tconst refname = isCurrent ? line.substring(1) : line; // Skip the HEAD marker\n\n\t\t\t\t\t\t// Skip HEADs\n\t\t\t\t\t\tif (refname.endsWith('/HEAD')) continue;\n\n\t\t\t\t\t\tif (refname.startsWith('refs/heads/')) {\n\t\t\t\t\t\t\t// Remove 'refs/heads/'\n\t\t\t\t\t\t\tconst name = refname.substring(11);\n\t\t\t\t\t\t\trefs.push({\n\t\t\t\t\t\t\t\trefType: 'branch',\n\t\t\t\t\t\t\t\tname: name,\n\t\t\t\t\t\t\t\tremote: false,\n\t\t\t\t\t\t\t\tcurrent: isCurrent,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (refname.startsWith('refs/remotes/')) {\n\t\t\t\t\t\t\t// Remove 'refs/remotes/'\n\t\t\t\t\t\t\trefs.push({ refType: 'branch', name: refname.substring(13), remote: true });\n\t\t\t\t\t\t} else if (refname.startsWith('refs/tags/')) {\n\t\t\t\t\t\t\t// Remove 'refs/tags/'\n\t\t\t\t\t\t\trefs.push({ refType: 'tag', name: refname.substring(10) });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// git already returns sorted by -HEAD, -committerdate, -version:refname;\n\t\t\t\t// compareReachableRefs refines by current-first / local-before-remote / tag-version.\n\t\t\t\trefs.sort(compareReachableRefs);\n\n\t\t\t\treturn { refs: refs };\n\t\t\t} catch (ex) {\n\t\t\t\tcacheable?.invalidate();\n\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\tdebugger;\n\t\t\t\tscope?.error(ex);\n\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t};\n\n\t\treturn this.cache.reachability.getOrCreate(repoPath, rev, getCore);\n\t}\n\n\t@debug()\n\tasync getIncomingActivity(\n\t\trepoPath: string,\n\t\toptions?: IncomingActivityOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitReflog | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst cfg = this.context.config;\n\t\tconst parser = getReflogParser();\n\t\tconst args = ['--walk-reflogs', ...parser.arguments, '--date=iso8601'];\n\n\t\tconst ordering = options?.ordering ?? cfg?.commits.ordering;\n\t\tif (ordering) {\n\t\t\targs.push(`--${ordering}-order`);\n\t\t}\n\n\t\tif (options?.all) {\n\t\t\targs.push('--all');\n\t\t}\n\n\t\t// Pass a much larger limit to reflog, because we aggregate the data and we won't know how many lines we'll need\n\t\tconst limit = (options?.limit ?? cfg?.commits.maxItems ?? 0) * 100;\n\t\tif (limit) {\n\t\t\targs.push(`-n${limit}`);\n\t\t}\n\n\t\tif (options?.skip) {\n\t\t\targs.push(`--skip=${options.skip}`);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsLog, priority: 'background' },\n\t\t\t\t'log',\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tconst reflog = parseGitRefLog(parser, result.stdout, repoPath, reflogCommands, limit, limit * 100);\n\t\t\tif (reflog?.hasMore) {\n\t\t\t\treflog.more = this.getReflogMoreFn(reflog, options);\n\t\t\t}\n\n\t\t\treturn reflog;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate getReflogMoreFn(\n\t\treflog: GitReflog,\n\t\toptions?: IncomingActivityOptions,\n\t): (limit: number) => Promise<GitReflog> {\n\t\treturn async (limit: number | undefined) => {\n\t\t\tlimit = limit ?? 0;\n\n\t\t\tconst moreLog = await this.getIncomingActivity(reflog.repoPath, {\n\t\t\t\t...options,\n\t\t\t\tlimit: limit,\n\t\t\t\tskip: reflog.total,\n\t\t\t});\n\t\t\tif (moreLog == null) {\n\t\t\t\t// If we can't find any more, assume we have everything\n\t\t\t\treturn { ...reflog, hasMore: false, more: undefined };\n\t\t\t}\n\n\t\t\tconst mergedLog: GitReflog = {\n\t\t\t\trepoPath: reflog.repoPath,\n\t\t\t\trecords: [...reflog.records, ...moreLog.records],\n\t\t\t\tcount: reflog.count + moreLog.count,\n\t\t\t\ttotal: reflog.total + moreLog.total,\n\t\t\t\tlimit: (reflog.limit ?? 0) + limit,\n\t\t\t\thasMore: moreLog.hasMore,\n\t\t\t};\n\t\t\tif (mergedLog.hasMore) {\n\t\t\t\tmergedLog.more = this.getReflogMoreFn(mergedLog, options);\n\t\t\t}\n\n\t\t\treturn mergedLog;\n\t\t};\n\t}\n\n\t@debug({ exit: true })\n\tgetInitialCommitSha(repoPath: string, cancellation?: AbortSignal): Promise<string | undefined> {\n\t\t// Initial commit SHA is shared across all worktrees\n\t\treturn this.cache.getInitialCommitSha(repoPath, async commonPath => {\n\t\t\ttry {\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: commonPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t'rev-list',\n\t\t\t\t\t`--max-parents=0`,\n\t\t\t\t\t'HEAD',\n\t\t\t\t\t'--',\n\t\t\t\t);\n\t\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t}\n\n\t\t\t\treturn result.stdout.trim().split('\\n')?.[0];\n\t\t\t} catch (ex) {\n\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t});\n\t}\n\n\t@debug()\n\tasync getLeftRightCommitCount(\n\t\trepoPath: string,\n\t\trange: GitRevisionRange,\n\t\toptions?: { authors?: GitUser[]; excludeMerges?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<LeftRightCommitCountResult | undefined> {\n\t\tconst authors = options?.authors?.length\n\t\t\t? options.authors.map(a => `--author=^${escapeRegex(a.name ?? '')} <${escapeRegex(a.email ?? '')}>$`)\n\t\t\t: [];\n\n\t\tconst run = async (): Promise<LeftRightCommitCountResult | undefined> => {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t'rev-list',\n\t\t\t\t'--left-right',\n\t\t\t\t'--count',\n\t\t\t\t...authors,\n\t\t\t\toptions?.excludeMerges ? '--no-merges' : undefined,\n\t\t\t\trange,\n\t\t\t\t'--',\n\t\t\t);\n\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\tthrow new CancellationError();\n\t\t\t}\n\t\t\tif (!result.stdout) return undefined;\n\n\t\t\tconst parts = result.stdout.split('\\t');\n\t\t\tif (parts.length !== 2) return undefined;\n\n\t\t\tconst [left, right] = parts;\n\t\t\tconst counts = {\n\t\t\t\tleft: parseInt(left, 10),\n\t\t\t\tright: parseInt(right, 10),\n\t\t\t};\n\n\t\t\tif (isNaN(counts.left) || isNaN(counts.right)) return undefined;\n\n\t\t\treturn counts;\n\t\t};\n\n\t\t// Author-filtered calls are one-off (e.g. \"who made these commits\") with low re-hit\n\t\t// rate; skip the cache to protect its capacity for the hot no-author merge-target path.\n\t\tif (authors.length > 0) return run();\n\n\t\t// Cache key: range + excludeMerges. RepositoryChange events affecting branches/remotes\n\t\t// invalidate this cache via clearCaches('branches').\n\t\tconst cacheKey = `${range}\\x1f${options?.excludeMerges ? 'no-merges' : ''}`;\n\t\treturn this.cache.leftRightCommitCount.getOrCreate(repoPath, cacheKey, run);\n\t}\n\n\t@debug()\n\tasync getLog(\n\t\trepoPath: string,\n\t\trev?: string | undefined,\n\t\toptions?: GitLogOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitLog | undefined> {\n\t\treturn this.getLogCore(repoPath, rev, options, cancellation);\n\t}\n\n\t@trace({ args: (repoPath, rev) => ({ repoPath: repoPath, rev: rev }), exit: true })\n\tprivate async getLogCore(\n\t\trepoPath: string,\n\t\trev?: string | undefined,\n\t\toptions?: GitLogOptions & {\n\t\t\tpath?: { pathspec: string; filters?: GitDiffFilter[]; range?: DiffRange; renames?: boolean };\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t\tadditionalArgs?: string[],\n\t): Promise<GitLog | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst currentUserPromise = this.provider.config.getCurrentUser(repoPath);\n\n\t\t\tconst cfg = this.context.config;\n\t\t\tconst limit = options?.limit ?? cfg?.commits.maxItems ?? 0;\n\t\t\tconst isSingleCommit = limit === 1;\n\n\t\t\tconst cfgIncludeFiles = options?.includeFiles ?? cfg?.commits.includeFileDetails?.(repoPath) ?? true;\n\t\t\tconst includeFiles = cfgIncludeFiles || isSingleCommit || Boolean(options?.path?.pathspec);\n\n\t\t\tconst parser = getCommitsLogParser(includeFiles, Boolean(options?.path?.pathspec && options?.path?.range));\n\t\t\tconst args = ['log', ...parser.arguments];\n\n\t\t\tconst similarityThreshold = options?.similarityThreshold ?? cfg?.commits.similarityThreshold;\n\t\t\targs.push(`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`, '--use-mailmap');\n\n\t\t\tif (options?.all) {\n\t\t\t\targs.push('--all');\n\t\t\t\tif (options?.path?.pathspec) {\n\t\t\t\t\targs.push('--single-worktree');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst merges = options?.merges ?? true;\n\t\t\tif (merges) {\n\t\t\t\t// If we are are asking for a specific ref, ensure we return the merge commit files\n\t\t\t\tif (isSingleCommit) {\n\t\t\t\t\targs.push('-m');\n\t\t\t\t}\n\t\t\t\targs.push(merges === 'first-parent' ? '--first-parent' : '--no-min-parents');\n\t\t\t} else {\n\t\t\t\targs.push('--no-merges');\n\t\t\t}\n\n\t\t\tconst ordering = options?.ordering ?? cfg?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\tif (options?.authors?.length) {\n\t\t\t\targs.push(\n\t\t\t\t\t...options.authors.map(\n\t\t\t\t\t\ta => `--author=^${escapeRegex(a.name ?? '')} <${escapeRegex(a.email ?? '')}>$`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet overrideHasMore;\n\n\t\t\tif (options?.since) {\n\t\t\t\toverrideHasMore = true;\n\t\t\t\targs.push(`--since=\"${options.since}\"`);\n\t\t\t}\n\n\t\t\tif (options?.until) {\n\t\t\t\toverrideHasMore = true;\n\t\t\t\targs.push(`--until=\"${options.until}\"`);\n\t\t\t}\n\n\t\t\tif (additionalArgs?.length) {\n\t\t\t\targs.push(...additionalArgs);\n\t\t\t}\n\n\t\t\tif (limit > 0) {\n\t\t\t\toverrideHasMore = isSingleCommit ? false : undefined;\n\t\t\t\t// Add 1 to the limit so we can check if there are more commits\n\t\t\t\targs.push(`-n${isSingleCommit ? 1 : limit + 1}`);\n\t\t\t}\n\n\t\t\tlet stashes: ReadonlyMap<string, GitStashCommit> | undefined;\n\n\t\t\tif (!isSingleCommit && options?.stashes) {\n\t\t\t\tstashes =\n\t\t\t\t\ttypeof options.stashes === 'boolean'\n\t\t\t\t\t\t? (await this.provider.stash?.getStash(repoPath, { reachableFrom: rev }, cancellation))?.stashes\n\t\t\t\t\t\t: options.stashes;\n\t\t\t\tif (stashes?.size) {\n\t\t\t\t\trev ??= 'HEAD';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rev && !isUncommittedStaged(rev)) {\n\t\t\t\targs.push(rev);\n\t\t\t}\n\n\t\t\tlet pathspec: string | undefined;\n\t\t\tlet pathspecRange: `${number},${number}` | undefined;\n\n\t\t\tif (options?.path?.pathspec) {\n\t\t\t\tpathspec = options.path.pathspec;\n\t\t\t\tconst { filters, range, renames } = options.path;\n\n\t\t\t\tif (filters?.length) {\n\t\t\t\t\targs.push(`--diff-filter=${filters.join('')}`);\n\t\t\t\t}\n\n\t\t\t\tif (range != null) {\n\t\t\t\t\t// Git doesn't allow rename detection (`--follow`) if a range is used\n\n\t\t\t\t\tconst [start, end] = getGitStartEnd(range);\n\t\t\t\t\tpathspecRange = `${start},${end}`;\n\t\t\t\t\targs.push(`-L ${pathspecRange}:${pathspec}`, '--');\n\t\t\t\t} else {\n\t\t\t\t\tif (renames !== false) {\n\t\t\t\t\t\targs.push('--follow');\n\t\t\t\t\t}\n\t\t\t\t\targs.push('--', pathspec);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\targs.push('--');\n\t\t\t}\n\n\t\t\tconst currentUser = await currentUserPromise.catch(() => undefined);\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t// Only the eager, paged, multi-commit log measures the cost this evidence switches off — a\n\t\t\t// single-commit load and a pathspec-filtered log are cheap per numstat regardless of `includeFiles`.\n\t\t\tconst isEagerPagedFileLog = includeFiles && !isSingleCommit && !options?.path?.pathspec;\n\n\t\t\tconst cmdOpts: GitRunOptions = {\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\tconfigs: gitConfigsLogWithFiles,\n\t\t\t\t// Single-commit log serves user-initiated reads (commit details, hover, etc.).\n\t\t\t\t// Mirrors getCommitDates: full SHAs are immutable so a 5-min TTL is safe; non-SHA refs\n\t\t\t\t// rely on gitResults being cleared on head/heads/remotes events (60s is the failsafe\n\t\t\t\t// for watcher latency / web with no fs watcher).\n\t\t\t\t...(isSingleCommit && rev\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tcaching: {\n\t\t\t\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\t\t\t\toptions: { accessTTL: isSha(rev) ? 5 * 60 * 1000 : 60 * 1000 },\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\t\t...(isEagerPagedFileLog ? { slownessCategory: 'commitFiles' as const } : undefined),\n\t\t\t};\n\t\t\tlet { commits, count } = await parseCommits(\n\t\t\t\tparser,\n\t\t\t\tisSingleCommit ? this.git.run(cmdOpts, ...args) : this.git.stream(cmdOpts, ...args),\n\t\t\t\trepoPath,\n\t\t\t\tpathspec,\n\t\t\t\tlimit,\n\t\t\t\tundefined,\n\t\t\t\tcurrentUser,\n\t\t\t);\n\n\t\t\t// If we didn't find any history from the working tree, check to see if the file was renamed\n\t\t\tif (rev == null && pathspec && !commits.size) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpathspec,\n\t\t\t\t\tundefined,\n\t\t\t\t\tcancellation,\n\t\t\t\t);\n\t\t\t\tif (status?.originalPath != null) {\n\t\t\t\t\tpathspec = status.originalPath;\n\n\t\t\t\t\tif (pathspecRange) {\n\t\t\t\t\t\tconst index = args.findIndex(a => a.startsWith('-L '));\n\t\t\t\t\t\targs.splice(index, 1, `-L ${pathspecRange}:${pathspec}`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\targs.splice(args.length - 1, 1, pathspec);\n\t\t\t\t\t}\n\n\t\t\t\t\t({ commits, count } = await parseCommits(\n\t\t\t\t\t\tparser,\n\t\t\t\t\t\tisSingleCommit ? this.git.run(cmdOpts, ...args) : this.git.stream(cmdOpts, ...args),\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tpathspec,\n\t\t\t\t\t\tlimit,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tcurrentUser,\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Merge stashes in-memory rather than via `git log --stdin <stash>` — git would\n\t\t\t// walk each stash's parent chains and pull in pre-rebase ancestors that aren't\n\t\t\t// reachable from <rev>. Slot each stash directly above its first parent; stashes\n\t\t\t// whose parent isn't in the result (rebased away, or below the current limit) are\n\t\t\t// dropped — the Stashes view still surfaces them, and they reappear here if the\n\t\t\t// parent loads via \"Load more\".\n\t\t\tif (stashes?.size) {\n\t\t\t\t// `stashes` arrives in `git stash list` order (newest @{0} first), so per-parent\n\t\t\t\t// groups naturally land newest-first without an explicit sort\n\t\t\t\tconst stashesByParent = new Map<string, GitStashCommit[]>();\n\t\t\t\tfor (const stash of stashes.values()) {\n\t\t\t\t\tconst parentSha = stash.parents[0];\n\t\t\t\t\tif (parentSha == null || !commits.has(parentSha)) continue;\n\n\t\t\t\t\tconst group = stashesByParent.get(parentSha);\n\t\t\t\t\tif (group != null) {\n\t\t\t\t\t\tgroup.push(stash);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstashesByParent.set(parentSha, [stash]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (stashesByParent.size) {\n\t\t\t\t\tconst cap = limit > 0 ? limit + 1 : Number.POSITIVE_INFINITY;\n\t\t\t\t\tconst merged = new Map<string, GitCommit>();\n\t\t\t\t\touter: for (const c of commits.values()) {\n\t\t\t\t\t\tconst group = stashesByParent.get(c.sha);\n\t\t\t\t\t\tif (group != null) {\n\t\t\t\t\t\t\tfor (const s of group) {\n\t\t\t\t\t\t\t\tif (merged.size >= cap) break outer;\n\n\t\t\t\t\t\t\t\tmerged.set(s.sha, s);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (merged.size >= cap) break;\n\n\t\t\t\t\t\tmerged.set(c.sha, c);\n\t\t\t\t\t}\n\t\t\t\t\tcommits = merged;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst log: GitLog = {\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tcommits: commits,\n\t\t\t\tsha: isRevisionRange(rev) ? undefined : rev,\n\t\t\t\tcount: commits.size,\n\t\t\t\tlimit: limit,\n\t\t\t\thasMore: overrideHasMore ?? (limit > 0 && count > limit),\n\t\t\t};\n\n\t\t\tif (!isSingleCommit) {\n\t\t\t\tlog.query = (limit: number | undefined) =>\n\t\t\t\t\tthis.getLogCore(repoPath, rev, { ...options, limit: limit }, undefined, additionalArgs);\n\t\t\t\tif (log.hasMore) {\n\t\t\t\t\tlog.more = this.getLogCoreMoreFn(log, rev, options);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn log;\n\t\t} catch (ex) {\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t// Check if this is a \"bad object\" error due to a submodule's internal SHA\n\t\t\tconst pathspec = options?.path?.pathspec;\n\t\t\tif (rev && pathspec && ex instanceof Error && GitErrors.badObject.test(ex.message)) {\n\t\t\t\tconst tree = await this.provider.revision.getTreeEntryForRevision(repoPath, pathspec, 'HEAD');\n\t\t\t\tif (tree?.type === 'commit') {\n\t\t\t\t\t// It's a submodule - retry without the rev and without rename tracking\n\t\t\t\t\treturn this.getLogCore(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t{ ...options, path: { ...options.path, pathspec: pathspec, renames: false } },\n\t\t\t\t\t\tcancellation,\n\t\t\t\t\t\tadditionalArgs,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tdebugger;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate getLogCoreMoreFn(\n\t\tlog: GitLog,\n\t\trev: string | undefined,\n\t\toptions?: GitLogOptions & {\n\t\t\tpath?: { pathspec: string; filters?: GitDiffFilter[]; range?: DiffRange; renames?: boolean };\n\t\t},\n\t): (limit: number | { until: string } | undefined) => Promise<GitLog> {\n\t\treturn async (limit: number | { until: string } | undefined) => {\n\t\t\tconst moreUntil = limit != null && typeof limit === 'object' ? limit.until : undefined;\n\t\t\tlet moreLimit = typeof limit === 'number' ? limit : undefined;\n\n\t\t\tif (moreUntil && some(log.commits.values(), c => c.ref === moreUntil)) {\n\t\t\t\treturn log;\n\t\t\t}\n\n\t\t\tmoreLimit = moreLimit ?? 0;\n\n\t\t\t// If the log is for a range, then just get everything prior + more\n\t\t\tif (isRevisionRange(log.sha)) {\n\t\t\t\tconst moreLog = await this.getLogCore(log.repoPath, rev, {\n\t\t\t\t\t...options,\n\t\t\t\t\tlimit: moreLimit === 0 ? 0 : (options?.limit ?? 0) + moreLimit,\n\t\t\t\t});\n\t\t\t\t// If we can't find any more, assume we have everything\n\t\t\t\tif (moreLog == null) return { ...log, hasMore: false, more: undefined };\n\n\t\t\t\treturn moreLog;\n\t\t\t}\n\n\t\t\t// Stashes are not part of the normal commit history, so we need to find the last non-stash commit for the cursor\n\t\t\tconst lastCommit = findLast(log.commits.values(), c => !GitCommit.isStash(c)) ?? last(log.commits.values());\n\t\t\tconst sha = lastCommit?.ref;\n\n\t\t\t// Check to make sure the filename hasn't changed and if it has use the previous\n\t\t\tconst lastCommitFile = lastCommit?.anyFiles?.[0];\n\t\t\tif (options?.path?.pathspec && lastCommitFile != null) {\n\t\t\t\tconst path = lastCommitFile.originalPath ?? lastCommitFile.path;\n\t\t\t\tif (path !== options.path.pathspec) {\n\t\t\t\t\toptions = { ...options, path: { ...options.path, pathspec: path } };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we were asked for all refs, use the last commit timestamp (plus a second) as a cursor\n\t\t\tlet timestamp: number | undefined;\n\t\t\tif (options?.all) {\n\t\t\t\tconst date = lastCommit?.committer.date;\n\t\t\t\t// Git only allows 1-second precision, so round up to the nearest second\n\t\t\t\ttimestamp = date != null ? Math.ceil(date.getTime() / 1000) + 1 : undefined;\n\t\t\t}\n\n\t\t\tlet moreLogCount;\n\t\t\tlet queryLimit = moreUntil == null ? moreLimit : 0;\n\t\t\tdo {\n\t\t\t\tconst moreLog = await this.getLogCore(\n\t\t\t\t\tlog.repoPath,\n\t\t\t\t\ttimestamp ? rev : moreUntil == null ? `${sha}^` : `${moreUntil}^..${sha}^`,\n\t\t\t\t\t{\n\t\t\t\t\t\t...options,\n\t\t\t\t\t\tlimit: queryLimit,\n\t\t\t\t\t\t...(timestamp ? { until: timestamp } : undefined),\n\t\t\t\t\t},\n\t\t\t\t\tundefined,\n\t\t\t\t\ttimestamp ? ['--boundary'] : undefined,\n\t\t\t\t);\n\t\t\t\t// If we can't find any more, assume we have everything\n\t\t\t\tif (moreLog == null) return { ...log, hasMore: false, more: undefined };\n\n\t\t\t\tconst currentCount = log.commits.size;\n\t\t\t\tconst commits = new Map([...log.commits, ...moreLog.commits]);\n\n\t\t\t\tif (currentCount === commits.size && queryLimit !== 0) {\n\t\t\t\t\t// If we didn't find any new commits, we must have them all so return that we have everything\n\t\t\t\t\tif (moreLogCount === moreLog.commits.size) {\n\t\t\t\t\t\treturn { ...log, hasMore: false, more: undefined };\n\t\t\t\t\t}\n\n\t\t\t\t\tmoreLogCount = moreLog.commits.size;\n\t\t\t\t\tqueryLimit = queryLimit * 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (timestamp != null && sha != null && !moreLog.commits.has(sha)) {\n\t\t\t\t\tdebugger;\n\t\t\t\t}\n\n\t\t\t\tconst mergedLog: GitLog = {\n\t\t\t\t\trepoPath: log.repoPath,\n\t\t\t\t\tcommits: commits,\n\t\t\t\t\tsha: log.sha,\n\t\t\t\t\tcount: commits.size,\n\t\t\t\t\tlimit: moreUntil == null ? (log.limit ?? 0) + moreLimit : undefined,\n\t\t\t\t\thasMore: moreUntil == null ? moreLog.hasMore : true,\n\t\t\t\t\t// The oldest commit SHA of the previous page — the graph webview compares this\n\t\t\t\t\t// against its last displayed row to determine the merge point for appending new rows\n\t\t\t\t\tstartingCursor: sha,\n\t\t\t\t\tendingCursor: moreLog.endingCursor,\n\t\t\t\t\tpagedCommits: () => {\n\t\t\t\t\t\t// Remove any duplicates\n\t\t\t\t\t\tfor (const sha of log.commits.keys()) {\n\t\t\t\t\t\t\tmoreLog.commits.delete(sha);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn moreLog.commits;\n\t\t\t\t\t},\n\t\t\t\t\t// oxlint-disable-next-line no-loop-func\n\t\t\t\t\tquery: (limit: number | undefined) =>\n\t\t\t\t\t\tthis.getLogCore(log.repoPath, rev, { ...options, limit: limit }),\n\t\t\t\t};\n\t\t\t\tif (mergedLog.hasMore) {\n\t\t\t\t\tmergedLog.more = this.getLogCoreMoreFn(mergedLog, rev, options);\n\t\t\t\t}\n\n\t\t\t\treturn mergedLog;\n\t\t\t} while (true);\n\t\t};\n\t}\n\n\t@debug()\n\tasync getLogForPath(\n\t\trepoPath: string | undefined,\n\t\tpathOrUri: string | Uri,\n\t\trev?: string | undefined,\n\t\toptions?: GitLogForPathOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitLog | undefined> {\n\t\tif (repoPath == null) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\n\t\tif (repoPath != null && repoPath === relativePath) {\n\t\t\tthrow new Error(`Path cannot match the repository path; path=${relativePath}`);\n\t\t}\n\n\t\tconst cfg = this.context.config;\n\t\toptions = {\n\t\t\t...options,\n\t\t\tall: options?.all ?? cfg?.fileHistory?.showAllBranches,\n\t\t\tlimit: options?.limit ?? cfg?.commits.maxItems ?? 0,\n\t\t\tmerges: options?.merges ?? cfg?.fileHistory?.showMergeCommits,\n\t\t\tordering: options?.ordering ?? cfg?.commits.ordering ?? undefined,\n\t\t\trenames: options?.renames ?? cfg?.fileHistory?.followRenames,\n\t\t\tsimilarityThreshold: options?.similarityThreshold ?? cfg?.commits.similarityThreshold,\n\t\t};\n\n\t\tif (isFolderGlob(relativePath)) {\n\t\t\trelativePath = stripFolderGlob(relativePath);\n\t\t\toptions.isFolder = true;\n\t\t} else if (options.isFolder == null) {\n\t\t\tconst tree = await this.provider.revision.getTreeEntryForRevision(repoPath, relativePath, rev || 'HEAD');\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\tif (tree?.type === 'commit') {\n\t\t\t\t// It's a submodule — line ranges and rename tracking don't apply, and the rev may reference\n\t\t\t\t// the submodule's internal SHA which isn't valid in the parent repo\n\t\t\t\toptions.range = undefined;\n\t\t\t\toptions.renames = false;\n\t\t\t\t// rev = undefined;\n\t\t\t} else {\n\t\t\t\toptions.isFolder = tree?.type === 'tree';\n\t\t\t}\n\t\t}\n\n\t\t// Build cache key — only for non-folder, non-filtered queries\n\t\tlet cacheKey: string | undefined;\n\t\tif (\n\t\t\t!options.isFolder &&\n\t\t\toptions.authors == null &&\n\t\t\toptions.cursor == null &&\n\t\t\toptions.filters == null &&\n\t\t\toptions.range == null &&\n\t\t\toptions.since == null &&\n\t\t\toptions.until == null\n\t\t) {\n\t\t\tlet suffix = 'log';\n\t\t\tif (rev != null) {\n\t\t\t\tsuffix += `:${rev}`;\n\t\t\t}\n\t\t\tif (options.all) {\n\t\t\t\tsuffix += ':all';\n\t\t\t}\n\t\t\tif (options.limit) {\n\t\t\t\tsuffix += `:n${options.limit}`;\n\t\t\t}\n\t\t\tif (options.merges) {\n\t\t\t\tsuffix += `:merges=${options.merges}`;\n\t\t\t}\n\t\t\tif (options.ordering) {\n\t\t\t\tsuffix += `:ordering=${options.ordering}`;\n\t\t\t}\n\t\t\tif (options.renames) {\n\t\t\t\tsuffix += ':follow';\n\t\t\t}\n\t\t\tcacheKey = `${normalizePath(relativePath)}:${suffix}`;\n\t\t}\n\n\t\tif (cacheKey != null) {\n\t\t\t// Check for exact cache hit\n\t\t\tconst cached = this.cache.fileLog.get(repoPath, cacheKey);\n\t\t\tif (cached != null) {\n\t\t\t\tscope?.trace(`Cache hit: '${cacheKey}'`);\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\t// Subset optimization: if requesting partial log, check if whole-file log is cached\n\t\t\tif (rev != null || (options.limit != null && options.limit !== 0)) {\n\t\t\t\tconst baseKey = `${normalizePath(relativePath)}:log${options.renames ? ':follow' : ''}`;\n\t\t\t\tconst baseLog = this.cache.fileLog.get(repoPath, baseKey);\n\t\t\t\tif (baseLog != null) {\n\t\t\t\t\tif (rev == null) {\n\t\t\t\t\t\tscope?.trace(`Cache hit: ~'${cacheKey}'`);\n\t\t\t\t\t\treturn baseLog;\n\t\t\t\t\t}\n\n\t\t\t\t\tscope?.trace(`Cache ?: '${cacheKey}'`);\n\t\t\t\t\tconst log = await baseLog;\n\t\t\t\t\tif (log != null && !log.hasMore && log.commits.has(rev)) {\n\t\t\t\t\t\tscope?.trace(`Cache hit: '${cacheKey}'`);\n\n\t\t\t\t\t\t// Create a copy of the log starting at the requested commit\n\t\t\t\t\t\tlet skip = true;\n\t\t\t\t\t\tlet i = 0;\n\t\t\t\t\t\tconst limit = options.limit;\n\t\t\t\t\t\tconst commits = new Map(\n\t\t\t\t\t\t\tfilterMap<[string, GitCommit], [string, GitCommit]>(log.commits.entries(), ([sha, c]) => {\n\t\t\t\t\t\t\t\tif (skip) {\n\t\t\t\t\t\t\t\t\tif (sha !== rev) return undefined;\n\n\t\t\t\t\t\t\t\t\tskip = false;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\t\t\tif (limit != null && i > limit) {\n\t\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn [sha, c];\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst optsCopy = { ...options };\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...log,\n\t\t\t\t\t\t\tlimit: optsCopy.limit,\n\t\t\t\t\t\t\tcount: commits.size,\n\t\t\t\t\t\t\tcommits: commits,\n\t\t\t\t\t\t\tquery: (limit: number | undefined) =>\n\t\t\t\t\t\t\t\tthis.getLogForPath(repoPath, pathOrUri, rev, {\n\t\t\t\t\t\t\t\t\t...optsCopy,\n\t\t\t\t\t\t\t\t\tlimit: limit,\n\t\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}\n\t\t\t}\n\n\t\t\tscope?.trace(`Cache miss: '${cacheKey}'`);\n\n\t\t\treturn this.cache.fileLog.getOrCreate(\n\t\t\t\trepoPath,\n\t\t\t\tcacheKey,\n\t\t\t\t(_cacheable, signal) => this.getLogForPathCore(repoPath, relativePath, rev, options, signal),\n\t\t\t\t{ cancellation: cancellation },\n\t\t\t);\n\t\t}\n\n\t\treturn this.getLogForPathCore(repoPath, relativePath, rev, options, cancellation);\n\t}\n\n\tprivate async getLogForPathCore(\n\t\trepoPath: string,\n\t\tpath: string,\n\t\trev: string | undefined,\n\t\toptions: GitLogForPathOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitLog | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst tracked = await this.provider.isTrackedWithDetails(path, repoPath, rev);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tif (tracked == null) {\n\t\t\tscope?.debug(`Skipping log; '${path}' is not tracked`);\n\t\t\treturn emptyPromise as Promise<GitLog>;\n\t\t}\n\n\t\tconst relativePath = tracked.path;\n\t\tconst root = repoPath;\n\n\t\tconst log = await this.getLogCore(\n\t\t\troot,\n\t\t\trev,\n\t\t\t{\n\t\t\t\tall: options.all,\n\t\t\t\tauthors: options.authors,\n\t\t\t\tcursor: options.cursor,\n\t\t\t\tlimit: options.limit,\n\t\t\t\tmerges: options.merges,\n\t\t\t\tordering: options.ordering,\n\t\t\t\tsince: options.since,\n\t\t\t\tuntil: options.until,\n\t\t\t\tpath: {\n\t\t\t\t\tpathspec: relativePath,\n\t\t\t\t\tfilters: options.filters,\n\t\t\t\t\trange: options.range,\n\t\t\t\t\trenames: options.renames,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\n\t\treturn log;\n\t}\n\n\t@debug()\n\tasync getLogShas(\n\t\trepoPath: string,\n\t\trev?: string | undefined,\n\t\toptions?: GitLogShasOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<Iterable<string>> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst cfg = this.context.config;\n\t\toptions ??= {};\n\t\toptions.limit ??= cfg?.commits.maxItems ?? 0;\n\t\toptions.ordering ??= cfg?.commits.ordering ?? undefined;\n\t\toptions.similarityThreshold ??= cfg?.commits.similarityThreshold;\n\t\toptions.merges ??= true;\n\n\t\tconst getCore = async (): Promise<string[]> => {\n\t\t\ttry {\n\t\t\t\tconst parser = getShaLogParser();\n\t\t\t\tconst args = [...parser.arguments];\n\n\t\t\t\tif (options.all) {\n\t\t\t\t\targs.push(`--all`);\n\t\t\t\t}\n\n\t\t\t\tif (options.ordering) {\n\t\t\t\t\targs.push(`--${options.ordering}-order`);\n\t\t\t\t}\n\n\t\t\t\tif (options.limit) {\n\t\t\t\t\targs.push(`-n${options.limit}`);\n\t\t\t\t}\n\n\t\t\t\tif (options.since) {\n\t\t\t\t\targs.push(`--since=\"${options.since}\"`);\n\t\t\t\t}\n\n\t\t\t\tif (options.merges) {\n\t\t\t\t\targs.push(options.merges === 'first-parent' ? '--first-parent' : '--no-min-parents');\n\t\t\t\t} else {\n\t\t\t\t\targs.push('--no-merges');\n\t\t\t\t}\n\n\t\t\t\tif (options.reverse) {\n\t\t\t\t\targs.push('--reverse');\n\t\t\t\t}\n\n\t\t\t\tif (options.authors?.length) {\n\t\t\t\t\tif (!args.includes('--use-mailmap')) {\n\t\t\t\t\t\targs.push('--use-mailmap');\n\t\t\t\t\t}\n\t\t\t\t\targs.push(\n\t\t\t\t\t\t...options.authors.map(\n\t\t\t\t\t\t\ta => `--author=^${escapeRegex(a.name ?? '')} <${escapeRegex(a.email ?? '')}>$`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst pathspec =\n\t\t\t\t\toptions.pathOrUri != null ? this.provider.getRelativePath(options.pathOrUri, repoPath) : undefined;\n\t\t\t\tif (pathspec) {\n\t\t\t\t\tconst similarityThreshold = options.similarityThreshold;\n\t\t\t\t\targs.push(`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`);\n\t\t\t\t}\n\n\t\t\t\tconst excludeArgs = getRefExclusionArgs(options.excluding);\n\t\t\t\tif (rev && !isUncommittedStaged(rev)) {\n\t\t\t\t\targs.push(rev);\n\t\t\t\t} else if (excludeArgs.length) {\n\t\t\t\t\t// A bare `--not` lists nothing, so anchor the exclusion to HEAD\n\t\t\t\t\targs.push('HEAD');\n\t\t\t\t}\n\t\t\t\targs.push(...excludeArgs);\n\n\t\t\t\targs.push('--');\n\n\t\t\t\tif (pathspec) {\n\t\t\t\t\targs.push(pathspec);\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsLog },\n\t\t\t\t\t'log',\n\t\t\t\t\t...args,\n\t\t\t\t);\n\t\t\t\treturn [...parser.parse(result.stdout)];\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\tdebugger;\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\n\t\t// Cache simple queries (no pathspec, no authors) as these are on hot paths (e.g. getting unpublished commits)\n\t\tconst cacheable = !options.pathOrUri && !options.authors?.length && !options.reverse && !options.all;\n\n\t\tif (cacheable) {\n\t\t\treturn this.cache.logShas.getOrCreate(\n\t\t\t\trepoPath,\n\t\t\t\t`${rev ?? ''}:${options.ordering ?? ''}:${options.limit}:${options.merges}:${options.since ?? ''}${options.excluding == null ? '' : `:${getRefExclusionsKey(options.excluding)}`}`,\n\t\t\t\t() => getCore(),\n\t\t\t);\n\t\t}\n\n\t\treturn getCore();\n\t}\n\n\t@debug()\n\tasync getOldestUnpushedShaForPath(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\n\t\t\tconst parser = getShaLogParser();\n\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsLog },\n\t\t\t\t'log',\n\t\t\t\t...parser.arguments,\n\t\t\t\t'--follow',\n\t\t\t\t'--reverse',\n\t\t\t\t'@{u}..',\n\t\t\t\t'--',\n\t\t\t\trelativePath,\n\t\t\t);\n\t\t\treturn first(parser.parse(result.stdout));\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tdebugger;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug()\n\tasync hasCommitBeenPushed(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\tif (repoPath == null) return false;\n\n\t\treturn this.isAncestorOf(repoPath, rev, '@{u}', cancellation);\n\t}\n\n\t@debug()\n\tasync isAncestorOf(repoPath: string, rev1: string, rev2: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\tif (repoPath == null) return false;\n\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t'merge-base',\n\t\t\t'--is-ancestor',\n\t\t\trev1,\n\t\t\trev2,\n\t\t);\n\t\t// A cancelled check has no answer. `completion` now keeps that distinct from a real \"is an ancestor\"\n\t\t// result — the missing `exitCode` alone already makes the check below `false` — but callers branch on\n\t\t// `isCancellationError`, so this still has to throw rather than quietly answer \"no\".\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\treturn result.exitCode === 0;\n\t}\n\n\t@debug({\n\t\targs: (repoPath, s) => ({\n\t\t\trepoPath: repoPath,\n\t\t\tsearch: `[${s.matchAll ? 'A' : ''}${s.matchCase ? 'C' : ''}${s.matchRegex ? 'R' : ''}${\n\t\t\t\ts.matchWholeWord ? 'W' : ''\n\t\t\t}]: ${s.query.length > 500 ? `${s.query.substring(0, 500)}...` : s.query}`,\n\t\t}),\n\t})\n\tasync searchCommits(\n\t\trepoPath: string,\n\t\tsearch: SearchQuery,\n\t\toptions?: GitSearchCommitsOptions,\n\t\tcancellation?: AbortSignal,\n\t): Promise<SearchCommitsResult> {\n\t\tconst scope = getScopedLogger();\n\n\t\tsearch = { matchAll: false, matchCase: false, matchRegex: true, matchWholeWord: false, ...search };\n\n\t\t// Pre-process natural language search queries via the host-provided hook\n\t\tif (\n\t\t\tsearch.naturalLanguage &&\n\t\t\t(typeof search.naturalLanguage !== 'object' || !search.naturalLanguage.processedQuery)\n\t\t) {\n\t\t\tsearch = (await this.context.searchQuery?.preprocessQuery?.(search, options?.source)) ?? search;\n\t\t}\n\n\t\t// The conversion failed — `search.query` is still the raw English sentence, not a query; running\n\t\t// it as an ERE would produce a regex error about text the user never wrote.\n\t\tif (typeof search.naturalLanguage === 'object' && search.naturalLanguage.error) {\n\t\t\treturn { search: search, log: undefined };\n\t\t}\n\n\t\ttry {\n\t\t\tconst cfg = this.context.config;\n\t\t\tconst currentUser = await this.provider.config.getCurrentUser(repoPath);\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\tconst parser = getCommitsLogParser(true);\n\n\t\t\tconst similarityThreshold = options?.similarityThreshold ?? cfg?.commits.similarityThreshold;\n\t\t\tconst args = [\n\t\t\t\t'log',\n\t\t\t\t...parser.arguments,\n\t\t\t\t`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`,\n\t\t\t\t'--use-mailmap',\n\t\t\t];\n\n\t\t\tconst { args: searchArgs, files, shas, filters } = parseSearchQueryGitCommand(search, currentUser);\n\t\t\t// Stash commits have 2-3 parents, so `--merges` matches them; excluded in parseCommits.\n\t\t\t// Derived from the args git actually runs rather than `filters.type`, since a multi-value\n\t\t\t// `type:` query (e.g. `type:merge type:tip`) leaves `--merges` in the args while\n\t\t\t// `filters.type` reflects only the last value parsed\n\t\t\tconst mergesOnly = searchArgs.includes('--merges');\n\n\t\t\tlet stashes: Map<string, GitStashCommit> | undefined;\n\t\t\tlet stdin: string | undefined;\n\n\t\t\tlet resolvedShas: Set<string> | undefined;\n\t\t\tif (shas?.size) {\n\t\t\t\tresolvedShas = await this.provider.revision.resolveShas(repoPath, shas, cancellation);\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\t\t\t// Short SHA(s) matched no commit: return empty (empty stdin to `--no-walk --stdin`\n\t\t\t\t// would return HEAD, so we must not fall through to git).\n\t\t\t\tif (!resolvedShas.size) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsearch: search,\n\t\t\t\t\t\tlog: {\n\t\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\t\tcommits: new Map(),\n\t\t\t\t\t\t\tsha: undefined,\n\t\t\t\t\t\t\tsearchFilters: filters,\n\t\t\t\t\t\t\tcount: 0,\n\t\t\t\t\t\t\tlimit: options?.limit ?? cfg?.search?.maxItems ?? 0,\n\t\t\t\t\t\t\thasMore: false,\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\tif (resolvedShas?.size) {\n\t\t\t\tstdin = join(resolvedShas, '\\n');\n\t\t\t\targs.push('--no-walk');\n\t\t\t} else if (!filters.refs) {\n\t\t\t\t// Don't include stashes when using ref: filter, as they would add unrelated commits\n\t\t\t\t// There *HAS* to be a better way to get git log to return stashes, but this is the best we've found\n\t\t\t\tconst converted = convertStashesToStdin(\n\t\t\t\t\tawait this.provider.stash?.getStash(repoPath, undefined, cancellation),\n\t\t\t\t);\n\t\t\t\tstashes = converted.stashes;\n\t\t\t\t// `--all` already surfaces refs/stash's tip on its own, so when merges-only there's no need\n\t\t\t\t// to walk the rest of the stash stack via stdin -- parseCommits still excludes any stash\n\t\t\t\t// sha that slips through via refs/stash\n\t\t\t\tstdin = mergesOnly ? undefined : converted.stdin;\n\t\t\t} else if (mergesOnly) {\n\t\t\t\t// `ref:` skips walking stashes into the results (they're unrelated to the ref), but a\n\t\t\t\t// stash's tip can still leak in via `--merges` if the ref reaches refs/stash -- fetch\n\t\t\t\t// stashes here purely so parseCommits can exclude them, without widening the walk via\n\t\t\t\t// stdin\n\t\t\t\tstashes = convertStashesToStdin(\n\t\t\t\t\tawait this.provider.stash?.getStash(repoPath, undefined, cancellation),\n\t\t\t\t).stashes;\n\t\t\t}\n\n\t\t\tif (stdin) {\n\t\t\t\targs.push('--stdin');\n\t\t\t}\n\n\t\t\tconst limit = options?.limit ?? cfg?.search?.maxItems ?? 0;\n\t\t\tif (limit && !shas?.size) {\n\t\t\t\targs.push(`-n${limit + 1}`);\n\t\t\t}\n\n\t\t\tconst ordering = options?.ordering ?? cfg?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\tif (options?.skip) {\n\t\t\t\targs.push(`--skip=${options.skip}`);\n\t\t\t}\n\n\t\t\t// Add the search args, but skip any shas (as they are already included in the stdin)\n\t\t\tfor (const arg of searchArgs) {\n\t\t\t\tif (shas?.has(arg) || args.includes(arg)) continue;\n\n\t\t\t\targs.push(arg);\n\t\t\t}\n\n\t\t\tconst pathspec = files?.join(' ');\n\t\t\tconst { commits, count, countStashChildCommits } = await parseCommits(\n\t\t\t\tparser,\n\t\t\t\tthis.git.stream(\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\t\tconfigs: ['-C', repoPath, ...gitConfigsLog],\n\t\t\t\t\t\tstdin: stdin,\n\t\t\t\t\t},\n\t\t\t\t\t...args,\n\t\t\t\t\t'--',\n\t\t\t\t\t...files,\n\t\t\t\t),\n\t\t\t\trepoPath,\n\t\t\t\tpathspec,\n\t\t\t\tlimit,\n\t\t\t\tstashes,\n\t\t\t\tcurrentUser,\n\t\t\t\tfilters,\n\t\t\t\tmergesOnly,\n\t\t\t);\n\n\t\t\tconst log: GitLog = {\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tcommits: commits,\n\t\t\t\tsha: undefined,\n\t\t\t\tsearchFilters: filters,\n\t\t\t\tcount: commits.size,\n\t\t\t\tlimit: limit,\n\t\t\t\thasMore: count - countStashChildCommits > commits.size,\n\t\t\t\tquery: (limit: number | undefined) =>\n\t\t\t\t\tthis.searchCommits(repoPath, search, { ...options, limit: limit }).then(r => r.log),\n\t\t\t};\n\n\t\t\tif (log.hasMore) {\n\t\t\t\tconst searchCommitsCore = (log: GitLog): ((limit: number | undefined) => Promise<GitLog>) => {\n\t\t\t\t\treturn async (limit: number | undefined) => {\n\t\t\t\t\t\tlimit = limit ?? 0;\n\n\t\t\t\t\t\tconst moreLog = (\n\t\t\t\t\t\t\tawait this.searchCommits(log.repoPath, search, {\n\t\t\t\t\t\t\t\t...options,\n\t\t\t\t\t\t\t\tlimit: limit,\n\t\t\t\t\t\t\t\tskip: log.count,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t).log;\n\t\t\t\t\t\t// If we can't find any more, assume we have everything\n\t\t\t\t\t\tif (moreLog == null) return { ...log, hasMore: false, more: undefined };\n\n\t\t\t\t\t\tconst commits = new Map([...log.commits, ...moreLog.commits]);\n\n\t\t\t\t\t\tconst mergedLog: GitLog = {\n\t\t\t\t\t\t\trepoPath: log.repoPath,\n\t\t\t\t\t\t\tcommits: commits,\n\t\t\t\t\t\t\tsha: log.sha,\n\t\t\t\t\t\t\tsearchFilters: filters,\n\t\t\t\t\t\t\tcount: commits.size,\n\t\t\t\t\t\t\tlimit: (log.limit ?? 0) + limit,\n\t\t\t\t\t\t\thasMore: moreLog.hasMore,\n\t\t\t\t\t\t\tquery: (limit: number | undefined) =>\n\t\t\t\t\t\t\t\tthis.searchCommits(log.repoPath, search, { ...options, limit: limit }).then(r => r.log),\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (mergedLog.hasMore) {\n\t\t\t\t\t\t\tmergedLog.more = searchCommitsCore(mergedLog);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn mergedLog;\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\tlog.more = searchCommitsCore(log);\n\t\t\t}\n\n\t\t\treturn { search: search, log: log };\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn { search: search, log: undefined };\n\t\t}\n\t}\n\n\t@debug()\n\tasync getCommitSignature(repoPath: string, sha: string): Promise<CommitSignature | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\terrors: 'ignore',\n\t\t\t\t\tcaching: {\n\t\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\t\toptions: { accessTTL: isSha(sha) ? 5 * 60 * 1000 : 60 * 1000 },\n\t\t\t\t\t},\n\t\t\t\t\tconfigs: gitConfigsLog,\n\t\t\t\t},\n\t\t\t\t'log',\n\t\t\t\t`--format=${signatureFormat}`,\n\t\t\t\t'-1',\n\t\t\t\tsha,\n\t\t\t);\n\n\t\t\tif (!result.stdout) return undefined;\n\n\t\t\treturn parseSignatureOutput(result.stdout);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug()\n\tasync isCommitSigned(repoPath: string, sha: string): Promise<boolean> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\terrors: 'ignore',\n\t\t\t\t\tcaching: {\n\t\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\t\toptions: { accessTTL: isSha(sha) ? 5 * 60 * 1000 : 60 * 1000 },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t'cat-file',\n\t\t\t\t'commit',\n\t\t\t\tsha,\n\t\t\t);\n\t\t\treturn /^gpgsig(-sha256)? /m.test(result.stdout);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getCommitsSshSigners(repoPath: string, shas: string[]): Promise<Map<string, SshSignedCommit>> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst result = new Map<string, SshSignedCommit>();\n\t\tif (shas.length === 0) return result;\n\n\t\ttry {\n\t\t\t// Read every commit object in a single `cat-file --batch` process (the SHAs are piped to stdin) rather than\n\t\t\t// spawning one `git` per commit — the embedded SSH signature and committer identity are then parsed from\n\t\t\t// each raw object, avoiding a separate (and far heavier) `git log` pass to enumerate identities.\n\t\t\tconst data = await this.git.run<Buffer>(\n\t\t\t\t{ cwd: repoPath, errors: 'ignore', stdin: `${shas.join('\\n')}\\n`, encoding: 'buffer' },\n\t\t\t\t'cat-file',\n\t\t\t\t'--batch',\n\t\t\t);\n\t\t\tparseCatFileBatchForSshSigners(data.stdout, new Set(shas), result);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Parses `git cat-file --batch` output, extracting the embedded SSH public key (if any) from each requested commit\n * object. Each record is `<sha> <type> <size>` LF `<content>` LF (or `<sha> missing` LF), and the object's bytes are\n * consumed using the header's `<size>` rather than scanned line-by-line — so a commit/tag body line that happens to\n * look like an object header can never be misread as a boundary. Operates on the raw `Buffer` because `<size>` counts\n * bytes, not decoded characters.\n *\n * Exported for unit testing.\n */\nexport function parseCatFileBatchForSshSigners(\n\tstdout: Buffer,\n\trequestedShas: Set<string>,\n\tout: Map<string, SshSignedCommit>,\n): void {\n\tconst headerRegex = /^([0-9a-f]{40,64}) (commit|tag|blob|missing)(?: (\\d+))?$/;\n\n\tlet offset = 0;\n\twhile (offset < stdout.length) {\n\t\tconst newline = stdout.indexOf(0x0a, offset);\n\t\tif (newline === -1) break;\n\n\t\tconst match = headerRegex.exec(stdout.toString('utf8', offset, newline));\n\t\toffset = newline + 1;\n\t\t// A missing object (or an unrecognizable header) has no content body following its header line.\n\t\tif (match == null || match[2] === 'missing') continue;\n\n\t\tconst sha = match[1];\n\t\tconst object = stdout.toString('utf8', offset, offset + Number(match[3]));\n\t\toffset += Number(match[3]) + 1; // consume the object's bytes and the trailing newline that separates records\n\n\t\tif (!requestedShas.has(sha)) continue;\n\n\t\tconst key = extractSshPublicKeyFromCommitObject(object);\n\t\tif (key == null) continue;\n\n\t\tconst committer = extractCommitterFromCommitObject(object);\n\t\tout.set(sha, { key: key, name: committer?.name, email: committer?.email });\n\t}\n}\n\nfunction toCommit(c: ParsedCommit, repoPath: string, pathspec: string | undefined, currentUser: GitUser | undefined) {\n\tconst message = c.message.trim();\n\tconst index = message.indexOf('\\n');\n\n\tconst isCurrentAuthor = isUserMatch(currentUser, c.author, c.authorEmail) || undefined;\n\tconst isCurrentCommitter = isUserMatch(currentUser, c.committer, c.committerEmail) || undefined;\n\n\treturn new GitCommit(\n\t\trepoPath,\n\t\tc.sha,\n\t\tnew GitCommitIdentity(\n\t\t\tc.author,\n\t\t\tc.authorEmail,\n\t\t\tnew Date(Number(c.authorDate) * 1000),\n\t\t\tundefined,\n\t\t\tisCurrentAuthor,\n\t\t),\n\t\tnew GitCommitIdentity(\n\t\t\tc.committer,\n\t\t\tc.committerEmail,\n\t\t\tnew Date(Number(c.committerDate) * 1000),\n\t\t\tundefined,\n\t\t\tisCurrentCommitter,\n\t\t),\n\t\tindex !== -1 ? message.substring(0, index) : message,\n\t\tc.parents?.split(' ') ?? [],\n\t\tmessage,\n\t\tcreateCommitFileset(c, repoPath, pathspec),\n\t\tc.stats,\n\t\tundefined,\n\t\tc.tips?.split(' '),\n\t);\n}\n\nfunction getGitStartEnd(range: DiffRange): [number, number] {\n\t// Library DiffRange is always 1-based, startLine <= endLine\n\treturn [range.startLine, range.endLine];\n}\n\nasync function parseCommits(\n\tparser: CommitsLogParser | CommitsWithFilesLogParser | CommitsInFileRangeLogParser,\n\tresultOrStream: Promise<GitResult> | AsyncGenerator<string>,\n\trepoPath: string,\n\tpathspec: string | undefined,\n\tlimit: number | undefined,\n\tstashes: Map<string, GitStashCommit> | undefined,\n\tcurrentUser: GitUser | undefined,\n\tsearchFilters?: SearchQueryFilters,\n\t// Stash commits have 2-3 parents, so `--merges` matches them; excluded below. Passed in by the\n\t// caller (derived from the args git actually runs) rather than re-derived from `searchFilters.type`\n\t// here, since a multi-value `type:` query (e.g. `type:merge type:tip`) leaves `--merges` in the\n\t// args while `searchFilters.type` reflects only the last value parsed\n\tmergesOnly: boolean = false,\n): Promise<{ commits: Map<string, GitCommit>; count: number; countStashChildCommits: number }> {\n\tlet count = 0;\n\tlet countStashChildCommits = 0;\n\tconst commits = new Map<string, GitCommit>();\n\n\tconst tipsOnly = searchFilters?.type === 'tip';\n\n\tif (resultOrStream instanceof Promise) {\n\t\tconst scope = getScopedLogger();\n\t\tconst result = await resultOrStream;\n\n\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\tif (stashes?.size) {\n\t\t\tconst allowFilteredFiles = searchFilters?.files ?? false;\n\t\t\tconst stashesOnly = searchFilters?.type === 'stash';\n\n\t\t\tfor (const c of parser.parse(result.stdout)) {\n\t\t\t\tif (stashesOnly && !stashes?.has(c.sha)) continue;\n\t\t\t\tif (mergesOnly && stashes?.has(c.sha)) continue;\n\t\t\t\tif (tipsOnly && !c.tips) continue;\n\n\t\t\t\tcount++;\n\t\t\t\tif (limit && count > limit) break;\n\n\t\t\t\tconst stash = stashes?.get(c.sha);\n\t\t\t\tif (stash != null) {\n\t\t\t\t\tif (commits.has(stash.sha)) {\n\t\t\t\t\t\tcountStashChildCommits++;\n\t\t\t\t\t} else if (allowFilteredFiles) {\n\t\t\t\t\t\tcommits.set(\n\t\t\t\t\t\t\tstash.sha,\n\t\t\t\t\t\t\tstash.with({\n\t\t\t\t\t\t\t\tfileset: {\n\t\t\t\t\t\t\t\t\t...createCommitFileset(c, repoPath, pathspec),\n\t\t\t\t\t\t\t\t\t// Add the full stash files back into the fileset\n\t\t\t\t\t\t\t\t\tfiles: stash.fileset?.files,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcommits.set(stash.sha, stash);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tcommits.set(c.sha, toCommit(c, repoPath, pathspec, currentUser));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const c of parser.parse(result.stdout)) {\n\t\t\t\tif (tipsOnly && !c.tips) continue;\n\n\t\t\t\tcount++;\n\t\t\t\tif (limit && count > limit) break;\n\n\t\t\t\tcommits.set(c.sha, toCommit(c, repoPath, pathspec, currentUser));\n\t\t\t}\n\t\t}\n\n\t\tsw?.stop({ suffix: ` created ${count} commits` });\n\n\t\treturn { commits: commits, count: count, countStashChildCommits: countStashChildCommits };\n\t}\n\n\tusing _streamDisposer = createDisposable(() => void resultOrStream.return?.(undefined));\n\n\tif (stashes?.size) {\n\t\tconst allowFilteredFiles = searchFilters?.files ?? false;\n\t\tconst stashesOnly = searchFilters?.type === 'stash';\n\n\t\tfor await (const c of parser.parseAsync(resultOrStream)) {\n\t\t\tif (stashesOnly && !stashes?.has(c.sha)) continue;\n\t\t\tif (mergesOnly && stashes?.has(c.sha)) continue;\n\t\t\tif (tipsOnly && !c.tips) continue;\n\n\t\t\tcount++;\n\t\t\tif (limit && count > limit) break;\n\n\t\t\tconst stash = stashes?.get(c.sha);\n\t\t\tif (stash != null) {\n\t\t\t\tif (commits.has(stash.sha)) {\n\t\t\t\t\tcountStashChildCommits++;\n\t\t\t\t} else if (allowFilteredFiles) {\n\t\t\t\t\tcommits.set(\n\t\t\t\t\t\tstash.sha,\n\t\t\t\t\t\tstash.with({\n\t\t\t\t\t\t\tfileset: {\n\t\t\t\t\t\t\t\t...createCommitFileset(c, repoPath, pathspec),\n\t\t\t\t\t\t\t\t// Add the full stash files back into the fileset\n\t\t\t\t\t\t\t\tfiles: stash.fileset?.files,\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} else {\n\t\t\t\t\tcommits.set(stash.sha, stash);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcommits.set(c.sha, toCommit(c, repoPath, pathspec, currentUser));\n\t\t}\n\t} else {\n\t\tfor await (const c of parser.parseAsync(resultOrStream)) {\n\t\t\tif (tipsOnly && !c.tips) continue;\n\n\t\t\tcount++;\n\t\t\tif (limit && count > limit) break;\n\n\t\t\tcommits.set(c.sha, toCommit(c, repoPath, pathspec, currentUser));\n\t\t}\n\t}\n\n\treturn { commits: commits, count: count, countStashChildCommits: countStashChildCommits };\n}\n"],"mappings":"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"}
|
|
@@ -856,7 +856,7 @@ function toProviderPullRequest(pr) {
|
|
|
856
856
|
owner: { login: "" },
|
|
857
857
|
remoteInfo: null
|
|
858
858
|
},
|
|
859
|
-
headRepository: pr.refs?.head
|
|
859
|
+
headRepository: pr.refs?.head?.owner && pr.refs.head.repo ? {
|
|
860
860
|
id: pr.refs.head.repo,
|
|
861
861
|
name: pr.refs.head.repo,
|
|
862
862
|
owner: { login: pr.refs.head.owner },
|