@gitkraken/core-gitlens 0.10.6 → 0.11.0

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.
Files changed (106) hide show
  1. package/CHANGELOG.md +33 -1
  2. package/dist/git/cache.d.ts +34 -2
  3. package/dist/git/cache.js +53 -7
  4. package/dist/git/cache.js.map +1 -1
  5. package/dist/git/context.d.ts +1 -1
  6. package/dist/git/models/repository.d.ts +3 -2
  7. package/dist/git/models/repository.js +5 -4
  8. package/dist/git/models/repository.js.map +1 -1
  9. package/dist/git/providers/branches.d.ts +22 -0
  10. package/dist/git/providers/config.d.ts +3 -1
  11. package/dist/git/providers/diff.d.ts +1 -0
  12. package/dist/git/providers/provider.d.ts +13 -1
  13. package/dist/git/providers/staging.d.ts +1 -1
  14. package/dist/git/service.d.ts +17 -1
  15. package/dist/git/service.js +59 -8
  16. package/dist/git/service.js.map +1 -1
  17. package/dist/git/watching/changeEvent.d.ts +48 -5
  18. package/dist/git/watching/changeEvent.js +82 -7
  19. package/dist/git/watching/changeEvent.js.map +1 -1
  20. package/dist/git/watching/classifyChange.d.ts +13 -2
  21. package/dist/git/watching/classifyChange.js +40 -5
  22. package/dist/git/watching/classifyChange.js.map +1 -1
  23. package/dist/git/watching/gitIgnoreFilter.d.ts +57 -10
  24. package/dist/git/watching/gitIgnoreFilter.js +186 -29
  25. package/dist/git/watching/gitIgnoreFilter.js.map +1 -1
  26. package/dist/git/watching/initWatcher.d.ts +5 -1
  27. package/dist/git/watching/initWatcher.js +1 -1
  28. package/dist/git/watching/initWatcher.js.map +1 -1
  29. package/dist/git/watching/provider.d.ts +33 -8
  30. package/dist/git/watching/watchGroup.d.ts +13 -2
  31. package/dist/git/watching/watchGroup.js +60 -14
  32. package/dist/git/watching/watchGroup.js.map +1 -1
  33. package/dist/git/watching/watchService.d.ts +42 -1
  34. package/dist/git/watching/watchService.js +172 -20
  35. package/dist/git/watching/watchService.js.map +1 -1
  36. package/dist/git/watching/watchSession.d.ts +50 -17
  37. package/dist/git/watching/watchSession.js +274 -83
  38. package/dist/git/watching/watchSession.js.map +1 -1
  39. package/dist/git/watching/watcherPatterns.d.ts +13 -2
  40. package/dist/git/watching/watcherPatterns.js +22 -2
  41. package/dist/git/watching/watcherPatterns.js.map +1 -1
  42. package/dist/git/watching/worktreeSummary.d.ts +121 -0
  43. package/dist/git/watching/worktreeSummary.js +427 -0
  44. package/dist/git/watching/worktreeSummary.js.map +1 -0
  45. package/dist/git-cli/cliGitProvider.d.ts +6 -1
  46. package/dist/git-cli/cliGitProvider.js +87 -2
  47. package/dist/git-cli/cliGitProvider.js.map +1 -1
  48. package/dist/git-cli/exec/git.js +1 -1
  49. package/dist/git-cli/providers/blame.js +1 -1
  50. package/dist/git-cli/providers/branches.d.ts +32 -1
  51. package/dist/git-cli/providers/branches.js +195 -0
  52. package/dist/git-cli/providers/branches.js.map +1 -1
  53. package/dist/git-cli/providers/commits.js +1 -1
  54. package/dist/git-cli/providers/config.d.ts +3 -0
  55. package/dist/git-cli/providers/config.js +14 -8
  56. package/dist/git-cli/providers/config.js.map +1 -1
  57. package/dist/git-cli/providers/contributors.js +1 -1
  58. package/dist/git-cli/providers/diff.d.ts +3 -0
  59. package/dist/git-cli/providers/diff.js +3 -2
  60. package/dist/git-cli/providers/diff.js.map +1 -1
  61. package/dist/git-cli/providers/graph.js +1 -1
  62. package/dist/git-cli/providers/maintenance.js +1 -1
  63. package/dist/git-cli/providers/pausedOperations.js +2 -2
  64. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  65. package/dist/git-cli/providers/refs.js +1 -1
  66. package/dist/git-cli/providers/staging.js +2 -2
  67. package/dist/git-cli/providers/status.js +1 -1
  68. package/dist/git-cli/service.js +1 -0
  69. package/dist/git-cli/service.js.map +1 -1
  70. package/dist/ipc/discovery.js +1 -1
  71. package/dist/ipc/ipcServer.js +1 -1
  72. package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
  73. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
  74. package/dist/plus/agents/providers/gkAgentProvider.js +2 -2
  75. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -1
  76. package/dist/plus/git-github/api/github.d.ts +1 -1
  77. package/dist/plus/git-github/api/github.js +2 -1
  78. package/dist/plus/git-github/api/github.js.map +1 -1
  79. package/dist/plus/git-github/providers/github/blame.js +1 -1
  80. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +1 -1
  81. package/dist/plus/integrations/context.d.ts +1 -1
  82. package/dist/plus/integrations/integrationService.js +1 -1
  83. package/dist/plus/integrations/models/integration.d.ts +1 -1
  84. package/dist/plus/integrations/models/integration.js +2 -2
  85. package/dist/plus/integrations/models/integration.js.map +1 -1
  86. package/dist/plus/integrations/providers/azure/azure.js +1 -1
  87. package/dist/plus/integrations/providers/bitbucket-server.d.ts +1 -1
  88. package/dist/plus/integrations/providers/jira.d.ts +2 -0
  89. package/dist/plus/integrations/providers/jira.js +5 -0
  90. package/dist/plus/integrations/providers/jira.js.map +1 -1
  91. package/dist/plus/integrations/providers/linear.d.ts +7 -0
  92. package/dist/plus/integrations/providers/linear.js +19 -0
  93. package/dist/plus/integrations/providers/linear.js.map +1 -1
  94. package/dist/plus/integrations/providers/trello.d.ts +8 -0
  95. package/dist/plus/integrations/providers/trello.js +22 -0
  96. package/dist/plus/integrations/providers/trello.js.map +1 -1
  97. package/dist/plus/integrations/reads/currentAccount.d.ts +1 -1
  98. package/dist/plus/integrations/reads/currentAccount.js +1 -1
  99. package/dist/plus/integrations/reads/currentAccount.js.map +1 -1
  100. package/dist/plus/integrations/reads/issueTracker.js +1 -0
  101. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  102. package/dist/utils/env/node/exec.js +2 -2
  103. package/dist/utils/event.d.ts +1 -1
  104. package/docs/integrations.md +6 -6
  105. package/docs/kepler-read-api-parity.md +2 -2
  106. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"diff.js","names":[],"sources":["../../../../git-cli/src/providers/diff.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport type {\n\tGitDiff,\n\tGitDiffFiles,\n\tGitDiffFilter,\n\tGitDiffShortStat,\n\tParsedGitDiff,\n\tParsedGitDiffHunks,\n} from '@gitlens/git/models/diff.js';\nimport type { GitFile } from '@gitlens/git/models/file.js';\nimport type { GitRevisionRange, GitRevisionRangeNotation } from '@gitlens/git/models/revision.js';\nimport { deletedOrMissing, uncommitted, uncommittedStaged } from '@gitlens/git/models/revision.js';\nimport {\n\tparseGitApplyFiles,\n\tparseGitDiff,\n\tparseGitDiffNumStatFiles,\n\tparseGitDiffShortStat,\n\tparseGitFileDiff,\n} from '@gitlens/git/parsers/diffParser.js';\nimport type {\n\tGitDiffSubProvider,\n\tNextComparisonUrisResult,\n\tPreviousComparisonUrisResult,\n\tPreviousRangeComparisonUrisResult,\n} from '@gitlens/git/providers/diff.js';\nimport type { DisposableTemporaryGitIndex } from '@gitlens/git/providers/staging.js';\nimport type { DiffRange, RevisionUri } from '@gitlens/git/providers/types.js';\nimport type { GitErrorHandling } from '@gitlens/git/run.types.js';\nimport {\n\tgetRevisionRangeParts,\n\tisRevisionRange,\n\tisUncommitted,\n\tisUncommittedStaged,\n} from '@gitlens/git/utils/revision.utils.js';\nimport { encodeGitLensRevisionUriAuthority } from '@gitlens/git/utils/uriAuthority.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { fnv1aHash } from '@gitlens/utils/hash.js';\nimport { first } from '@gitlens/utils/iterable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { normalizePath, splitPath } from '@gitlens/utils/path.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fromUri, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult } from '../exec/exec.types.js';\nimport type { Git } from '../exec/git.js';\nimport { gitConfigsDiff, gitConfigsLog, GitError, GitErrors } from '../exec/git.js';\nimport type { LogParsedFile } from '../parsers/logParser.js';\nimport { getShaAndFileRangeLogParser, getShaAndFileSummaryLogParser } from '../parsers/logParser.js';\n\nexport class DiffGitSubProvider implements GitDiffSubProvider {\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@debug()\n\tasync getChangedFilesCount(\n\t\trepoPath: string,\n\t\tto?: string,\n\t\tfrom?: string,\n\t\toptions?: { uris?: (string | Uri)[]; includeUntracked?: boolean; errors?: GitErrorHandling },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiffShortStat | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst args: string[] = [];\n\t\tif (to != null) {\n\t\t\t// Handle revision ranges specially if there is no `from`, otherwise `prepareToFromDiffArgs` will duplicate the range\n\t\t\tif (isRevisionRange(to) && from == null) {\n\t\t\t\targs.push(to);\n\t\t\t} else {\n\t\t\t\tprepareToFromDiffArgs(to, from, args);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// A default run swallows a failure matching a git warning (not a repository, say) into empty output\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, errors: options?.errors === 'throw' ? 'throw' : undefined },\n\t\t\t\t'diff',\n\t\t\t\t'--shortstat',\n\t\t\t\t'--no-ext-diff',\n\t\t\t\t...args,\n\t\t\t\t'--',\n\t\t\t\t...(options?.uris?.map(p => this.provider.getRelativePath(p, repoPath)) ?? []),\n\t\t\t);\n\n\t\t\tconst stat = result.stdout ? parseGitDiffShortStat(result.stdout) : undefined;\n\n\t\t\t// Merge in untracked files when the comparison involves the working tree.\n\t\t\t// Skip when a pathspec filter is active — mixing a path-filtered diff count with an\n\t\t\t// unfiltered untracked count would silently produce wrong totals.\n\t\t\tif (options?.includeUntracked && !options.uris?.length && isWorkingTreeComparison(to, from)) {\n\t\t\t\tconst untracked = await this.getUntrackedFilesForDiff(repoPath, options.errors);\n\t\t\t\tif (untracked.length) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tfiles: (stat?.files ?? 0) + untracked.length,\n\t\t\t\t\t\tadditions: stat?.additions ?? 0,\n\t\t\t\t\t\tdeletions: stat?.deletions ?? 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stat;\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif (options?.errors !== 'throw' && (GitErrors.noMergeBase.test(msg) || GitErrors.badRevision.test(msg))) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDiff(\n\t\trepoPath: string,\n\t\tto: string,\n\t\tfrom?: string,\n\t\toptions?: {\n\t\t\tcontext?: number;\n\t\t\tindex?: DisposableTemporaryGitIndex;\n\t\t\tnotation?: GitRevisionRangeNotation;\n\t\t\turis?: (string | Uri)[];\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiff | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst args = [`-U${options?.context ?? 3}`];\n\n\t\tif (to != null && isRevisionRange(to)) {\n\t\t\tconst parts = getRevisionRangeParts(to);\n\t\t\tif (parts != null) {\n\t\t\t\tto = parts.right ?? '';\n\t\t\t\tfrom = parts.left;\n\t\t\t\toptions = { ...options, notation: parts.notation };\n\t\t\t}\n\t\t}\n\n\t\tconst hasFrom = from != null;\n\t\tfrom = prepareToFromDiffArgs(to, from, args, options?.notation);\n\n\t\tlet paths: Set<string> | undefined;\n\t\tif (options?.uris) {\n\t\t\tpaths = new Set<string>(options.uris.map(p => this.provider.getRelativePath(p, repoPath)));\n\t\t\targs.push('--', ...paths);\n\t\t}\n\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, errors: 'throw', env: options?.index?.env },\n\t\t\t\t'diff',\n\t\t\t\t...args,\n\t\t\t\targs.includes('--') ? undefined : '--',\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\t// Before its first commit HEAD names nothing, so a diff from it fails; the empty tree is what it is against\n\t\t\tif (isHead(from) && (await isUnbornHeadFailure(this.provider, repoPath, ex))) {\n\t\t\t\tconst emptyTree = await this.provider.revision.getEmptyTreeSha(repoPath);\n\t\t\t\t// With no `from`, a `to` of HEAD means the working tree against HEAD, so it is the empty tree alone\n\t\t\t\tconst retried = await this.getDiff(\n\t\t\t\t\trepoPath,\n\t\t\t\t\t!hasFrom && isHead(to) ? '' : to,\n\t\t\t\t\temptyTree,\n\t\t\t\t\toptions,\n\t\t\t\t\t_cancellation,\n\t\t\t\t);\n\t\t\t\treturn retried != null ? { ...retried, to: to } : undefined;\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tif (options?.errors === 'throw') throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst diff: GitDiff = { contents: result.stdout, from: from, to: to, notation: options?.notation };\n\t\treturn diff;\n\t}\n\n\t@debug()\n\tasync getParsedDiff(\n\t\trepoPath: string,\n\t\tto: string,\n\t\tfrom?: string,\n\t\toptions?: {\n\t\t\tcontext?: number;\n\t\t\tnotation?: GitRevisionRangeNotation;\n\t\t\turis?: (string | Uri)[];\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ParsedGitDiff | undefined> {\n\t\tconst diff = await this.getDiff(repoPath, to, from, options, cancellation);\n\t\tif (!diff?.contents) return undefined;\n\n\t\treturn parseGitDiff(diff.contents);\n\t}\n\n\t@debug({ args: repoPath => ({ repoPath: repoPath }) })\n\tasync getDiffFiles(\n\t\trepoPath: string,\n\t\tcontents: string,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiffFiles | undefined> {\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, configs: gitConfigsLog, stdin: contents },\n\t\t\t'apply',\n\t\t\t'--numstat',\n\t\t\t'--summary',\n\t\t\t'-z',\n\t\t\t'-',\n\t\t);\n\t\tif (!result.stdout) return undefined;\n\n\t\tconst files = parseGitApplyFiles(result.stdout, repoPath);\n\t\treturn {\n\t\t\tfiles: files,\n\t\t};\n\t}\n\n\t@debug()\n\tasync getDiffStatus(\n\t\trepoPath: string,\n\t\tref1OrRange: string | GitRevisionRange,\n\t\tref2?: string,\n\t\toptions?: {\n\t\t\tfilters?: GitDiffFilter[];\n\t\t\tincludeUntracked?: boolean;\n\t\t\tpath?: string;\n\t\t\trenameLimit?: number;\n\t\t\tsimilarityThreshold?: number;\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t): Promise<GitFile[] | undefined> {\n\t\ttry {\n\t\t\tconst similarityThreshold =\n\t\t\t\toptions?.similarityThreshold ?? this.context.config?.commits.similarityThreshold;\n\t\t\tconst configs =\n\t\t\t\toptions?.renameLimit != null\n\t\t\t\t\t? [...gitConfigsDiff, '-c', `diff.renameLimit=${options.renameLimit}`]\n\t\t\t\t\t: gitConfigsDiff;\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: configs, errors: options?.errors === 'throw' ? 'throw' : undefined },\n\t\t\t\t'diff',\n\t\t\t\t'--numstat',\n\t\t\t\t'--summary',\n\t\t\t\t`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`,\n\t\t\t\t'--no-ext-diff',\n\t\t\t\t'-z',\n\t\t\t\toptions?.filters?.length ? `--diff-filter=${options.filters.join('')}` : undefined,\n\t\t\t\tref1OrRange ? ref1OrRange : undefined,\n\t\t\t\tref2 ? ref2 : undefined,\n\t\t\t\t'--',\n\t\t\t\toptions?.path ? options.path : undefined,\n\t\t\t);\n\n\t\t\tconst files = result.stdout ? (parseGitDiffNumStatFiles(result.stdout, repoPath) ?? []) : [];\n\n\t\t\t// Merge in untracked files when the comparison involves the working tree.\n\t\t\t// Skip when `filters` excludes additions (untracked entries are semantically 'A'/added),\n\t\t\t// or when `path` is a non-exact pathspec we can't reliably match against the untracked list.\n\t\t\tif (\n\t\t\t\toptions?.includeUntracked &&\n\t\t\t\tref2 == null &&\n\t\t\t\ttypeof ref1OrRange === 'string' &&\n\t\t\t\t!isRevisionRange(ref1OrRange) &&\n\t\t\t\t!isUncommittedStaged(ref1OrRange) &&\n\t\t\t\tfiltersAllowUntracked(options.filters) &&\n\t\t\t\t!isNonExactPathspec(options.path)\n\t\t\t) {\n\t\t\t\tconst untracked = await this.getUntrackedFilesForDiff(repoPath, options.errors);\n\t\t\t\tif (untracked.length) {\n\t\t\t\t\tconst seen = new Set(files.map(f => f.path));\n\t\t\t\t\tfor (const file of untracked) {\n\t\t\t\t\t\tif (seen.has(file.path)) continue;\n\t\t\t\t\t\tif (options.path && options.path !== file.path) continue;\n\n\t\t\t\t\t\tfiles.push(file);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn files.length ? files : undefined;\n\t\t} catch (ex) {\n\t\t\tif (options?.errors === 'throw') throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * The untracked files a working-tree diff folds in; outside `errors: 'throw'`, a failed listing adds nothing. The diff\n\t * reads take no cancellation, so a `CancellationError` here is a timeout and degrades like any other failure.\n\t */\n\tprivate async getUntrackedFilesForDiff(repoPath: string, errors: GitErrorHandling | undefined): Promise<GitFile[]> {\n\t\ttry {\n\t\t\treturn (await this.provider.status?.getUntrackedFiles?.(repoPath)) ?? [];\n\t\t} catch (ex) {\n\t\t\tif (errors === 'throw') throw ex;\n\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDiffTool(repoPath?: string): Promise<string | undefined> {\n\t\treturn (\n\t\t\t(await this.provider.config.getConfig?.(repoPath, 'diff.guitool', { runGitLocally: true })) ??\n\t\t\tthis.provider.config.getConfig?.(repoPath, 'diff.tool', { runGitLocally: true })\n\t\t);\n\t}\n\n\t@debug()\n\tasync getNextComparisonUris(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\tskip: number = 0,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<NextComparisonUrisResult | undefined> {\n\t\t// If we have no revision there is no next commit\n\t\tif (!rev) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\n\t\tif (isUncommittedStaged(rev)) {\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, relativePath, rev),\n\t\t\t\tnext: createRevisionUri(this.provider, repoPath, relativePath, undefined),\n\t\t\t};\n\t\t} else if (isUncommitted(rev)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\t\tconst args = ['log', ...parser.arguments];\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\targs.push(\n\t\t\t\t// Use reverse to get the next commits (oldest to newest instead of newest to oldest)\n\t\t\t\t'--reverse',\n\t\t\t);\n\n\t\t\tif (rev !== deletedOrMissing) {\n\t\t\t\targs.push(\n\t\t\t\t\t// Ancestry path to ensure we only follow the path from the given revision to HEAD\n\t\t\t\t\t'--ancestry-path',\n\t\t\t\t\t// Range from the given revision to HEAD\n\t\t\t\t\t`${rev}..HEAD`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Follow file history and specify the file path\n\t\t\targs.push('--follow', '--', relativePath);\n\n\t\t\t// Unbounded --follow walk over file history can be slow on long histories — queue as background\n\t\t\t// so it doesn't compete with interactive work.\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsLog, priority: 'background' },\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tlet currentSha;\n\t\t\tlet currentPath;\n\n\t\t\tif (skip === 0) {\n\t\t\t\tcurrentSha = rev;\n\t\t\t\tcurrentPath = relativePath;\n\t\t\t} else {\n\t\t\t\tskip--;\n\t\t\t}\n\n\t\t\tlet nextSha;\n\t\t\tlet nextPath;\n\n\t\t\tlet file;\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.path && file.path !== relativePath) {\n\t\t\t\t\trelativePath = file.path;\n\t\t\t\t}\n\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t} else if (nextSha == null) {\n\t\t\t\t\t// if (commit.sha === rev) continue;\n\n\t\t\t\t\tnextSha = commit.sha;\n\t\t\t\t\tnextPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, relativePath);\n\t\t\t\tif (status != null) {\n\t\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\t\tcurrentSha = uncommittedStaged;\n\t\t\t\t\t\tcurrentPath = status.originalPath ?? status.path;\n\t\t\t\t\t\tnextSha = '';\n\t\t\t\t\t\tnextPath = status.path;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (nextSha == null || nextPath == null) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, relativePath);\n\t\t\t\tif (status != null) {\n\t\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\t\tnextSha = uncommittedStaged;\n\t\t\t\t\t\tnextPath = status.originalPath ?? status.path;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnextSha = '';\n\t\t\t\t\t\tnextPath = status.path;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnextSha = '';\n\t\t\t\t\tnextPath = relativePath;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tnext: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tnextPath ?? currentPath,\n\t\t\t\t\t(nextSha ?? deletedOrMissing) || undefined,\n\t\t\t\t),\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getPreviousComparisonUris(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\tskip: number = 0,\n\t\tunsaved?: boolean,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PreviousComparisonUrisResult | undefined> {\n\t\tif (rev === deletedOrMissing) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tif (rev === uncommitted) {\n\t\t\trev = undefined;\n\t\t}\n\n\t\t/* Rules:\n\t\t * Starting from working tree (rev is empty or undefined):\n\t\t * 1. Check file status:\n\t\t * 1.1. If file has both staged and working (or unsaved) changes:\n\t\t * - If skip=0: diff working with staged\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.2. If file has only staged changes:\n\t\t * - If skip=0: diff working with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.3. If file has only working changes:\n\t\t * - If skip=0: diff working with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.4. If file has no changes (or no status found):\n\t\t * - If skip=0: diff working with HEAD~1\n\t\t * - If skip>0: skip through revs starting at HEAD~1\n\t\t *\n\t\t * Starting from staged (rev is uncommittedStaged):\n\t\t * 1. Check file status:\n\t\t * 1.1. If status exists:\n\t\t * - If skip=0: diff staged with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.2. If status doesn't exist:\n\t\t * - If skip=0: diff HEAD with HEAD~1\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * Starting from a commit (rev is a SHA):\n\t\t * - If skip=0: diff SHA with SHA^\n\t\t * - If skip>0: skip through revs starting at SHA\n\t\t */\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\t\tlet skipPrev = 0;\n\n\t\tlet revs: [string, string][] = [];\n\t\tif (!rev) {\n\t\t\trevs = [['', relativePath]];\n\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\trevs.push([uncommittedStaged, status.originalPath ?? status.path]);\n\t\t\t\t}\n\n\t\t\t\trevs.push(['HEAD', status.originalPath ?? status.path]);\n\t\t\t\tif (status.workingTreeStatus == null && !unsaved) {\n\t\t\t\t\tif (skip === 0 || status.indexStatus == null) {\n\t\t\t\t\t\t// Skip over the HEAD commit to get a diff, because working and HEAD are the same\n\t\t\t\t\t\tskipPrev++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trevs.push(['HEAD', relativePath]);\n\t\t\t\tif (!unsaved) {\n\t\t\t\t\t// Skip over the HEAD commit to get a diff, because working and HEAD are the same\n\t\t\t\t\tskipPrev++;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isUncommittedStaged(rev)) {\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\trevs = [\n\t\t\t\t\t[uncommittedStaged, status.originalPath ?? status.path],\n\t\t\t\t\t['HEAD', status.originalPath ?? status.path],\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\t// Even though we supposedly started at staged, there is no staged version\n\t\t\t\trevs = [['HEAD', relativePath]];\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet currentSha;\n\t\tlet currentPath;\n\n\t\tif (revs.length) {\n\t\t\tskip++;\n\t\t\twhile (revs.length && skip > 0) {\n\t\t\t\tskip--;\n\t\t\t\t[rev, relativePath] = revs.shift()!;\n\t\t\t}\n\n\t\t\tif (rev !== 'HEAD') {\n\t\t\t\tcurrentSha = rev;\n\t\t\t\tcurrentPath = relativePath;\n\n\t\t\t\tskipPrev++;\n\t\t\t\twhile (revs.length && skipPrev > 0) {\n\t\t\t\t\tskipPrev--;\n\t\t\t\t\t[rev, relativePath] = revs.shift()!;\n\t\t\t\t}\n\n\t\t\t\tif (skipPrev > 0) {\n\t\t\t\t\tskip += skipPrev;\n\t\t\t\t}\n\n\t\t\t\tif (rev !== 'HEAD' && skip === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha),\n\t\t\t\t\t\tprevious: createRevisionUri(this.provider, repoPath, relativePath, rev),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\t\tconst args = ['log', ...parser.arguments, `-n${skip + 2}`]; // Don't use --skip as it doesn't work with --follow\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\targs.push('--follow', rev!, '--', relativePath);\n\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\tconfigs: gitConfigsLog,\n\t\t\t\t\tcaching: { cache: this.cache.gitResults, options: { accessTTL: 5 * 60 * 1000 } },\n\t\t\t\t},\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tlet previousSha;\n\t\t\tlet previousPath;\n\t\t\tlet file;\n\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.originalPath && file.originalPath !== relativePath) {\n\t\t\t\t\trelativePath = file.originalPath;\n\t\t\t\t}\n\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t} else if (previousSha == null) {\n\t\t\t\t\tif (commit.sha === rev) continue;\n\n\t\t\t\t\tpreviousSha = commit.sha;\n\t\t\t\t\tpreviousPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) return undefined;\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tprevious: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpreviousPath ?? currentPath,\n\t\t\t\t\tpreviousSha ?? deletedOrMissing,\n\t\t\t\t),\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getPreviousComparisonUrisForRange(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\trange: DiffRange,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null; skipFirstRev?: boolean },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PreviousRangeComparisonUrisResult | undefined> {\n\t\tif (rev === deletedOrMissing) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tif (rev === uncommitted) {\n\t\t\trev = undefined;\n\t\t}\n\n\t\tlet currentSha;\n\t\tlet currentPath;\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\t\tconst skipFirstRev = options?.skipFirstRev ?? true;\n\n\t\t// If we are at the working tree (i.e. no ref), we need to dig deeper to figure out where to go\n\t\tif (!rev) {\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\tif (status.workingTreeStatus != null && !skipFirstRev) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, relativePath, undefined),\n\t\t\t\t\t\t\tprevious: createRevisionUri(this.provider, repoPath, relativePath, uncommittedStaged),\n\t\t\t\t\t\t\trange: range,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrentSha = uncommittedStaged;\n\t\t\t\t\tcurrentPath = status.originalPath ?? status.path;\n\t\t\t\t\tif (status.originalPath != null) {\n\t\t\t\t\t\trelativePath = status.originalPath;\n\t\t\t\t\t}\n\t\t\t\t\trev = uncommittedStaged;\n\t\t\t\t} else if (status.workingTreeStatus != null && !skipFirstRev) {\n\t\t\t\t\tcurrentSha = '';\n\t\t\t\t\tcurrentPath = relativePath;\n\t\t\t\t\trev = '';\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (!skipFirstRev) {\n\t\t\tcurrentSha = rev;\n\t\t\tcurrentPath = relativePath;\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileRangeLogParser();\n\t\t\tconst args = ['log', ...parser.arguments, '-n2']; // Don't use --skip as it doesn't work with --follow\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\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\targs.push(`-L${range.startLine},${range.endLine}:${relativePath}`);\n\n\t\t\tlet result: GitResult;\n\t\t\ttry {\n\t\t\t\tresult = await this.git.run({ cwd: repoPath, configs: gitConfigsLog }, ...args);\n\t\t\t} catch (ex) {\n\t\t\t\tif (rev && !isUncommittedStaged(rev)) throw ex;\n\n\t\t\t\t// If the line count is invalid reset to a valid range\n\t\t\t\tconst match = GitErrors.invalidLineCount.exec(ex?.toString() ?? '');\n\t\t\t\tif (match == null) throw ex;\n\n\t\t\t\tconst line = parseInt(match[1], 10);\n\t\t\t\tif (isNaN(line)) throw ex;\n\n\t\t\t\tconst index = args.findIndex(a => a.startsWith('-L'));\n\t\t\t\tif (index === -1) throw ex;\n\n\t\t\t\trange = {\n\t\t\t\t\tstartLine: Math.min(range.startLine, line),\n\t\t\t\t\tstartCharacter: range.startCharacter,\n\t\t\t\t\tendLine: Math.min(range.endLine, line),\n\t\t\t\t\tendCharacter: range.endCharacter,\n\t\t\t\t\tactive: range.active,\n\t\t\t\t};\n\n\t\t\t\targs.splice(index, 1, `-L${range.startLine},${range.endLine}:${relativePath}`);\n\t\t\t\tresult = await this.git.run({ cwd: repoPath, configs: gitConfigsLog }, ...args);\n\t\t\t}\n\n\t\t\tlet currentRange;\n\t\t\tlet previousSha;\n\t\t\tlet previousPath;\n\t\t\tlet file;\n\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// If we couldn't find the file, but there is only one file in the commit, use that one and assume the filename changed\n\t\t\t\tif (file == null && commit.files.length === 1) {\n\t\t\t\t\tfile = commit.files[0];\n\t\t\t\t\trelativePath = file.path;\n\t\t\t\t}\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.originalPath && file.originalPath !== relativePath) {\n\t\t\t\t\trelativePath = file.originalPath;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t\tcurrentRange =\n\t\t\t\t\t\tfile?.range != null ? { ...file.range, startCharacter: 1, endCharacter: 1 } : undefined;\n\t\t\t\t} else if (previousSha == null) {\n\t\t\t\t\tif (commit.sha === rev) continue;\n\n\t\t\t\t\tpreviousSha = commit.sha;\n\t\t\t\t\tpreviousPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) return undefined;\n\n\t\t\t// If we have no previous SHA but have a real current SHA, resolve the parent commit.\n\t\t\t// This handles the case where a line is newly added — the line has no prior history,\n\t\t\t// but the file likely existed at the parent commit\n\t\t\tif (previousSha == null && currentSha) {\n\t\t\t\tpreviousSha =\n\t\t\t\t\t(await this.provider.refs.validateReference(repoPath, `${currentSha}^`)) ?? deletedOrMissing;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tprevious: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpreviousPath ?? currentPath,\n\t\t\t\t\tpreviousSha ?? deletedOrMissing,\n\t\t\t\t),\n\t\t\t\trange: currentRange ?? range,\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Returns raw diff output for a file between two revisions. */\n\tasync diff(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1?: string,\n\t\tref2?: string,\n\t\toptions?: {\n\t\t\tencoding?: string;\n\t\t\tfilters?: GitDiffFilter[];\n\t\t\tlinesOfContext?: number;\n\t\t\trenames?: boolean;\n\t\t\tsimilarityThreshold?: number | null;\n\t\t},\n\t): Promise<GitResult> {\n\t\tconst params = ['diff', '--no-ext-diff', '--minimal'];\n\n\t\tif (options?.linesOfContext != null) {\n\t\t\tparams.push(`-U${options.linesOfContext}`);\n\t\t}\n\n\t\tif (options?.renames) {\n\t\t\tparams.push(`-M${options.similarityThreshold == null ? '' : `${options.similarityThreshold}%`}`);\n\t\t}\n\n\t\tif (options?.filters != null && options.filters.length !== 0) {\n\t\t\tparams.push(`--diff-filter=${options.filters.join('')}`);\n\t\t}\n\n\t\tif (ref1) {\n\t\t\t// <sha>^3 signals an untracked file in a stash and if we are trying to find its parent, use the empty tree\n\t\t\tif (ref1.endsWith('^3^')) {\n\t\t\t\tref1 = await this.provider.revision.getEmptyTreeSha(repoPath);\n\t\t\t}\n\t\t\tparams.push(isUncommittedStaged(ref1) ? '--staged' : ref1);\n\t\t}\n\t\tif (ref2) {\n\t\t\tparams.push(isUncommittedStaged(ref2) ? '--staged' : ref2);\n\t\t}\n\n\t\ttry {\n\t\t\treturn await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, encoding: options?.encoding },\n\t\t\t\t...params,\n\t\t\t\t'--',\n\t\t\t\tfileName,\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tconst match = GitErrors.badRevision.exec(ex.message);\n\t\t\tif (match !== null) {\n\t\t\t\tconst [, ref] = match;\n\n\t\t\t\t// If the bad ref is trying to find a parent ref, assume we hit to the last commit, so try again using the empty tree\n\t\t\t\tif (ref === ref1 && ref?.endsWith('^')) {\n\t\t\t\t\treturn this.diff(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tfileName,\n\t\t\t\t\t\tawait this.provider.revision.getEmptyTreeSha(repoPath),\n\t\t\t\t\t\tref2,\n\t\t\t\t\t\toptions,\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/** Returns raw diff output comparing a file's revision with given contents via stdin. */\n\tasync diffContents(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions?: { encoding?: string; filters?: GitDiffFilter[]; similarityThreshold?: number | null },\n\t): Promise<string> {\n\t\tconst params = [\n\t\t\t'diff',\n\t\t\t`-M${options?.similarityThreshold == null ? '' : `${options.similarityThreshold}%`}`,\n\t\t\t'--no-ext-diff',\n\t\t\t'-U0',\n\t\t\t'--minimal',\n\t\t];\n\n\t\tif (options?.filters != null && options.filters.length !== 0) {\n\t\t\tparams.push(`--diff-filter=${options.filters.join('')}`);\n\t\t}\n\n\t\tparams.push('--no-index');\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\tconfigs: gitConfigsDiff,\n\t\t\t\t\tencoding: options?.encoding,\n\t\t\t\t\tstdin: contents,\n\t\t\t\t},\n\t\t\t\t...params,\n\t\t\t\t'--',\n\t\t\t\tfileName,\n\t\t\t\t// Pipe the contents to stdin\n\t\t\t\t'-',\n\t\t\t);\n\t\t\treturn result.stdout;\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof GitError && ex.stdout) {\n\t\t\t\treturn ex.stdout;\n\t\t\t}\n\n\t\t\tconst match = GitErrors.badRevision.exec(ex.message);\n\t\t\tif (match !== null) {\n\t\t\t\tconst [, matchedRef] = match;\n\n\t\t\t\t// If the bad ref is trying to find a parent ref, assume we hit to the last commit, so try again using the empty tree\n\t\t\t\tif (matchedRef === ref && matchedRef?.endsWith('^')) {\n\t\t\t\t\treturn this.diffContents(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tfileName,\n\t\t\t\t\t\tawait this.provider.revision.getEmptyTreeSha(repoPath),\n\t\t\t\t\t\tcontents,\n\t\t\t\t\t\toptions,\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/** Returns parsed diff hunks for a file between two revisions. */\n\t@debug()\n\tgetDiffForFile(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1: string | undefined,\n\t\tref2?: string,\n\t\toptions?: { encoding?: string },\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst cacheKey = `${normalizePath(fileName)}:${ref1 ?? ''}:${ref2 ?? ''}`;\n\t\treturn this.cache.diff.getOrCreate(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\t() => this.getDiffForFileCore(repoPath, fileName, ref1, ref2, options),\n\t\t\t{ errorTTL: 1000 * 60 },\n\t\t);\n\t}\n\n\tprivate async getDiffForFileCore(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1: string | undefined,\n\t\tref2: string | undefined,\n\t\toptions: { encoding?: string } | undefined,\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\t// Include renames (R) and copies (C) so content diffs on renamed files still surface;\n\t\t// --diff-filter runs after `-M` rename detection, so 'M' alone would drop valid rename diffs.\n\t\tconst result = await this.diff(repoPath, fileName, ref1, ref2, {\n\t\t\tencoding: options?.encoding,\n\t\t\tfilters: ['M', 'R', 'C'],\n\t\t\tlinesOfContext: 0,\n\t\t\trenames: true,\n\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t});\n\t\treturn parseGitFileDiff(result.stdout);\n\t}\n\n\t/** Returns parsed diff hunks comparing a file's revision with given contents via stdin. */\n\t@debug()\n\tgetDiffForFileContents(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions?: { encoding?: string },\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst cacheKey = `${normalizePath(fileName)}:${ref}:~${fnv1aHash(contents)}`;\n\t\treturn this.cache.diff.getOrCreate(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\t() => this.getDiffForFileContentsCore(repoPath, fileName, ref, contents, options),\n\t\t\t{ errorTTL: 1000 * 60 },\n\t\t);\n\t}\n\n\tprivate async getDiffForFileContentsCore(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions: { encoding?: string } | undefined,\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst data = await this.diffContents(repoPath, fileName, ref, contents, {\n\t\t\tencoding: options?.encoding,\n\t\t\tfilters: ['M', 'R', 'C'],\n\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t});\n\t\treturn parseGitFileDiff(data);\n\t}\n\n\t/** Finds the most recent commit where the given path was copied, renamed, or deleted. */\n\t@debug()\n\tasync findPathStatusChanged(\n\t\trepoPath: string,\n\t\tpathspec: string,\n\t\trev: string | undefined,\n\t\toptions?: { filters?: GitDiffFilter[]; ordering?: 'date' | 'author-date' | 'topo' | null },\n\t): Promise<{ sha: string; file: LogParsedFile | undefined } | undefined> {\n\t\treturn findPathStatusChanged(this.git, repoPath, pathspec, rev, options);\n\t}\n\n\t@debug()\n\tasync openDiffTool(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\toptions?: { ref1?: string; ref2?: string; staged?: boolean; tool?: string },\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\t\tconst [relativePath, root] = splitPath(toFsPath(pathOrUri), repoPath);\n\n\t\ttry {\n\t\t\tlet tool = options?.tool;\n\t\t\tif (!tool) {\n\t\t\t\tconst scope = getScopedLogger();\n\n\t\t\t\ttool = await this.getDiffTool(root);\n\t\t\t\tif (tool == null) throw new Error('No diff tool found');\n\n\t\t\t\tscope?.debug(`Using tool=${tool}`);\n\t\t\t}\n\n\t\t\tawait this.git.run(\n\t\t\t\t{ cwd: root },\n\t\t\t\t'difftool',\n\t\t\t\t'--no-prompt',\n\t\t\t\t`--tool=${tool}`,\n\t\t\t\toptions?.staged ? '--staged' : undefined,\n\t\t\t\toptions?.ref1 ? options.ref1 : undefined,\n\t\t\t\toptions?.ref2 ? options.ref2 : undefined,\n\t\t\t\t'--',\n\t\t\t\trelativePath,\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif ((ex instanceof Error && ex.message === 'No diff tool found') || /Unknown .+? tool/.test(msg)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Unable to open changes because the specified diff tool cannot be found or no Git diff tool is configured',\n\t\t\t\t\t),\n\t\t\t\t\t{ cause: ex },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync openDirectoryCompare(repoPath: string, ref1: string, ref2?: string, tool?: string): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tif (!tool) {\n\t\t\t\tconst scope = getScopedLogger();\n\n\t\t\t\ttool = await this.getDiffTool(repoPath);\n\t\t\t\tif (tool == null) throw new Error('No diff tool found');\n\n\t\t\t\tscope?.debug(`Using tool=${tool}`);\n\t\t\t}\n\n\t\t\tawait this.git.run({ cwd: repoPath }, 'difftool', '--dir-diff', `--tool=${tool}`, ref1, ref2);\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif ((ex instanceof Error && ex.message === 'No diff tool found') || /Unknown .+? tool/.test(msg)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Unable to open directory compare because the specified diff tool cannot be found or no Git diff tool is configured',\n\t\t\t\t\t),\n\t\t\t\t\t{ cause: ex },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n}\n// Returns true when no --diff-filter is active or when it includes additions ('A' or '*').\n// Untracked files are semantically \"added\" — if a caller restricts filters to e.g. ['M'],\n// honor that and omit untracked.\nfunction filtersAllowUntracked(filters: GitDiffFilter[] | undefined): boolean {\n\tif (!filters?.length) return true;\n\treturn filters.includes('A') || filters.includes('*');\n}\n\n// Returns true when the path is a git pathspec we can't match with simple equality\n// (directory prefix, glob, or magic pathspec). In that case, skip the untracked merge\n// rather than risk excluding legitimate matches or including wrong ones.\nfunction isNonExactPathspec(path: string | undefined): boolean {\n\tif (!path) return false;\n\treturn path.endsWith('/') || /[*?[\\]]|^:/.test(path);\n}\n\n// Returns true when the `git diff` invocation shape includes the working tree\n// (i.e. `git diff`, `git diff HEAD`, or `git diff <ref>` with no `from`), and\n// therefore untracked files are a meaningful addition to the result.\nfunction isWorkingTreeComparison(to: string | undefined, from: string | undefined): boolean {\n\tif (to == null) return true;\n\tif (isRevisionRange(to) || isUncommittedStaged(to)) return false;\n\n\t// `to === uncommitted` always targets the working tree (`prepareToFromDiffArgs` sets\n\t// `from = 'HEAD'` when omitted, or diffs against the caller-supplied `from`).\n\tif (isUncommitted(to)) return true;\n\n\t// `git diff <from>` — `to === ''` means the caller explicitly asked for working tree vs `from`\n\tif (to === '') return from == null || !isUncommittedStaged(from);\n\n\t// `getChangedFilesCount` uses `prepareToFromDiffArgs`, which translates `to` (with no `from`)\n\t// to `${to}^ ${to}` UNLESS `to` is HEAD or empty.\n\tif (isHead(to) && from == null) return true;\n\treturn false;\n}\n\nfunction isHead(ref: string | undefined): boolean {\n\treturn ref?.toUpperCase() === 'HEAD';\n}\n\n/** Whether `ex` is git failing to resolve `HEAD` because the repository has no commit yet */\nasync function isUnbornHeadFailure(provider: CliGitProviderInternal, repoPath: string, ex: unknown): Promise<boolean> {\n\tconst ref = GitErrors.badRevision.exec(String(ex))?.[1];\n\tif (!isHead(ref)) return false;\n\n\treturn (await provider.refs.validateReference(repoPath, 'HEAD', { force: true })) == null;\n}\n\nfunction prepareToFromDiffArgs(\n\tto: string,\n\tfrom: string | undefined,\n\targs: string[],\n\tnotation?: GitRevisionRangeNotation,\n): string {\n\tif (to === uncommitted) {\n\t\tif (from != null) {\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\t// Get only unstaged changes\n\t\t\tfrom = 'HEAD';\n\t\t}\n\t} else if (to === uncommittedStaged) {\n\t\targs.push('--staged');\n\t\tif (from != null) {\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\t// Get only staged changes\n\t\t\tfrom = 'HEAD';\n\t\t}\n\t} else if (from == null) {\n\t\tif (to === '' || isHead(to)) {\n\t\t\tfrom = 'HEAD';\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\tfrom = `${to}^`;\n\t\t\targs.push(from, to);\n\t\t}\n\t} else if (to === '') {\n\t\targs.push(from);\n\t} else if (notation != null) {\n\t\targs.push(`${from}${notation}${to}`);\n\t} else {\n\t\targs.push(from, to);\n\t}\n\treturn from;\n}\n\nfunction createRevisionUri(\n\tprovider: CliGitProviderInternal,\n\trepoPath: string,\n\trelativePath: string,\n\tsha: string | undefined,\n): RevisionUri {\n\treturn {\n\t\turi: sha\n\t\t\t? fromUri({\n\t\t\t\t\tscheme: 'gitlens',\n\t\t\t\t\tauthority: encodeGitLensRevisionUriAuthority({ ref: sha, repoPath: repoPath }),\n\t\t\t\t\tpath: provider.getAbsoluteUri(relativePath, repoPath).path,\n\t\t\t\t})\n\t\t\t: provider.getAbsoluteUri(relativePath, repoPath),\n\t\tpath: relativePath,\n\t\tsha: sha,\n\t\trepoPath: repoPath,\n\t};\n}\n\nexport async function findPathStatusChanged(\n\tgit: Git,\n\trepoPath: string,\n\tpathspec: string,\n\trev: string | undefined,\n\toptions?: { filters?: GitDiffFilter[]; ordering?: 'date' | 'author-date' | 'topo' | null },\n): Promise<{ sha: string; file: LogParsedFile | undefined } | undefined> {\n\tconst parser = getShaAndFileSummaryLogParser();\n\n\tconst ordering = options?.ordering;\n\n\tconst result = await git.run(\n\t\t{ cwd: repoPath, configs: gitConfigsLog },\n\t\t'log',\n\t\t...parser.arguments,\n\t\tordering ? `--${ordering}-order` : undefined,\n\t\t'--no-walk',\n\t\t`--diff-filter=${options?.filters?.length ? options.filters.join('') : 'RCD'}`,\n\t\trev,\n\t\t// Note: --no-walk constrains to the exact commit (no ancestor search). Pathspec is omitted\n\t\t// because git suppresses rename detection with pathspecs (shows D instead of R, losing the destination path).\n\t\t'--',\n\t);\n\n\tconst commit = first(parser.parse(result.stdout));\n\tif (commit == null) return undefined;\n\n\tconst file = commit.files.find(f => f.path === pathspec || f.originalPath === pathspec);\n\treturn { sha: commit.sha, file: file };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"diff.js","names":[],"sources":["../../../../git-cli/src/providers/diff.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport type {\n\tGitDiff,\n\tGitDiffFiles,\n\tGitDiffFilter,\n\tGitDiffShortStat,\n\tParsedGitDiff,\n\tParsedGitDiffHunks,\n} from '@gitlens/git/models/diff.js';\nimport type { GitFile } from '@gitlens/git/models/file.js';\nimport type { GitRevisionRange, GitRevisionRangeNotation } from '@gitlens/git/models/revision.js';\nimport { deletedOrMissing, uncommitted, uncommittedStaged } from '@gitlens/git/models/revision.js';\nimport {\n\tparseGitApplyFiles,\n\tparseGitDiff,\n\tparseGitDiffNumStatFiles,\n\tparseGitDiffShortStat,\n\tparseGitFileDiff,\n} from '@gitlens/git/parsers/diffParser.js';\nimport type {\n\tGitDiffSubProvider,\n\tNextComparisonUrisResult,\n\tPreviousComparisonUrisResult,\n\tPreviousRangeComparisonUrisResult,\n} from '@gitlens/git/providers/diff.js';\nimport type { DisposableTemporaryGitIndex } from '@gitlens/git/providers/staging.js';\nimport type { DiffRange, RevisionUri } from '@gitlens/git/providers/types.js';\nimport type { GitErrorHandling } from '@gitlens/git/run.types.js';\nimport {\n\tgetRevisionRangeParts,\n\tisRevisionRange,\n\tisUncommitted,\n\tisUncommittedStaged,\n} from '@gitlens/git/utils/revision.utils.js';\nimport { encodeGitLensRevisionUriAuthority } from '@gitlens/git/utils/uriAuthority.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { fnv1aHash } from '@gitlens/utils/hash.js';\nimport { first } from '@gitlens/utils/iterable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { normalizePath, splitPath } from '@gitlens/utils/path.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fromUri, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult } from '../exec/exec.types.js';\nimport type { Git } from '../exec/git.js';\nimport { gitConfigsDiff, gitConfigsLog, GitError, GitErrors } from '../exec/git.js';\nimport type { LogParsedFile } from '../parsers/logParser.js';\nimport { getShaAndFileRangeLogParser, getShaAndFileSummaryLogParser } from '../parsers/logParser.js';\n\nexport class DiffGitSubProvider implements GitDiffSubProvider {\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@debug()\n\tasync getChangedFilesCount(\n\t\trepoPath: string,\n\t\tto?: string,\n\t\tfrom?: string,\n\t\toptions?: { uris?: (string | Uri)[]; includeUntracked?: boolean; errors?: GitErrorHandling },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiffShortStat | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst args: string[] = [];\n\t\tif (to != null) {\n\t\t\t// Handle revision ranges specially if there is no `from`, otherwise `prepareToFromDiffArgs` will duplicate the range\n\t\t\tif (isRevisionRange(to) && from == null) {\n\t\t\t\targs.push(to);\n\t\t\t} else {\n\t\t\t\tprepareToFromDiffArgs(to, from, args);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// A default run swallows a failure matching a git warning (not a repository, say) into empty output\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, errors: options?.errors === 'throw' ? 'throw' : undefined },\n\t\t\t\t'diff',\n\t\t\t\t'--shortstat',\n\t\t\t\t'--no-ext-diff',\n\t\t\t\t...args,\n\t\t\t\t'--',\n\t\t\t\t...(options?.uris?.map(p => this.provider.getRelativePath(p, repoPath)) ?? []),\n\t\t\t);\n\n\t\t\tconst stat = result.stdout ? parseGitDiffShortStat(result.stdout) : undefined;\n\n\t\t\t// Merge in untracked files when the comparison involves the working tree.\n\t\t\t// Skip when a pathspec filter is active — mixing a path-filtered diff count with an\n\t\t\t// unfiltered untracked count would silently produce wrong totals.\n\t\t\tif (options?.includeUntracked && !options.uris?.length && isWorkingTreeComparison(to, from)) {\n\t\t\t\tconst untracked = await this.getUntrackedFilesForDiff(repoPath, options.errors);\n\t\t\t\tif (untracked.length) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tfiles: (stat?.files ?? 0) + untracked.length,\n\t\t\t\t\t\tadditions: stat?.additions ?? 0,\n\t\t\t\t\t\tdeletions: stat?.deletions ?? 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stat;\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif (options?.errors !== 'throw' && (GitErrors.noMergeBase.test(msg) || GitErrors.badRevision.test(msg))) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDiff(\n\t\trepoPath: string,\n\t\tto: string,\n\t\tfrom?: string,\n\t\toptions?: {\n\t\t\tcontext?: number;\n\t\t\tindex?: DisposableTemporaryGitIndex;\n\t\t\tnotation?: GitRevisionRangeNotation;\n\t\t\turis?: (string | Uri)[];\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiff | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst args = [`-U${options?.context ?? 3}`];\n\n\t\tif (to != null && isRevisionRange(to)) {\n\t\t\tconst parts = getRevisionRangeParts(to);\n\t\t\tif (parts != null) {\n\t\t\t\tto = parts.right ?? '';\n\t\t\t\tfrom = parts.left;\n\t\t\t\toptions = { ...options, notation: parts.notation };\n\t\t\t}\n\t\t}\n\n\t\tconst hasFrom = from != null;\n\t\tfrom = prepareToFromDiffArgs(to, from, args, options?.notation);\n\n\t\tlet paths: Set<string> | undefined;\n\t\tif (options?.uris) {\n\t\t\tpaths = new Set<string>(options.uris.map(p => this.provider.getRelativePath(p, repoPath)));\n\t\t\targs.push('--', ...paths);\n\t\t}\n\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, errors: 'throw', env: options?.index?.env },\n\t\t\t\t'diff',\n\t\t\t\t...args,\n\t\t\t\targs.includes('--') ? undefined : '--',\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\t// Before its first commit HEAD names nothing, so a diff from it fails; the empty tree is what it is against\n\t\t\tif (isHead(from) && (await isUnbornHeadFailure(this.provider, repoPath, ex))) {\n\t\t\t\tconst emptyTree = await this.provider.revision.getEmptyTreeSha(repoPath);\n\t\t\t\t// With no `from`, a `to` of HEAD means the working tree against HEAD, so it is the empty tree alone\n\t\t\t\tconst retried = await this.getDiff(\n\t\t\t\t\trepoPath,\n\t\t\t\t\t!hasFrom && isHead(to) ? '' : to,\n\t\t\t\t\temptyTree,\n\t\t\t\t\toptions,\n\t\t\t\t\t_cancellation,\n\t\t\t\t);\n\t\t\t\treturn retried != null ? { ...retried, to: to } : undefined;\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tif (options?.errors === 'throw') throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst diff: GitDiff = { contents: result.stdout, from: from, to: to, notation: options?.notation };\n\t\treturn diff;\n\t}\n\n\t@debug()\n\tasync getParsedDiff(\n\t\trepoPath: string,\n\t\tto: string,\n\t\tfrom?: string,\n\t\toptions?: {\n\t\t\tcontext?: number;\n\t\t\tnotation?: GitRevisionRangeNotation;\n\t\t\turis?: (string | Uri)[];\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ParsedGitDiff | undefined> {\n\t\tconst diff = await this.getDiff(repoPath, to, from, options, cancellation);\n\t\tif (!diff?.contents) return undefined;\n\n\t\treturn parseGitDiff(diff.contents);\n\t}\n\n\t@debug({ args: repoPath => ({ repoPath: repoPath }) })\n\tasync getDiffFiles(\n\t\trepoPath: string,\n\t\tcontents: string,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiffFiles | undefined> {\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, configs: gitConfigsLog, stdin: contents },\n\t\t\t'apply',\n\t\t\t'--numstat',\n\t\t\t'--summary',\n\t\t\t'-z',\n\t\t\t'-',\n\t\t);\n\t\tif (!result.stdout) return undefined;\n\n\t\tconst files = parseGitApplyFiles(result.stdout, repoPath);\n\t\treturn {\n\t\t\tfiles: files,\n\t\t};\n\t}\n\n\t@debug()\n\tasync getDiffStatus(\n\t\trepoPath: string,\n\t\tref1OrRange: string | GitRevisionRange,\n\t\tref2?: string,\n\t\toptions?: {\n\t\t\tfilters?: GitDiffFilter[];\n\t\t\tincludeUntracked?: boolean;\n\t\t\tpath?: string;\n\t\t\trenameLimit?: number;\n\t\t\tsimilarityThreshold?: number;\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t): Promise<GitFile[] | undefined> {\n\t\ttry {\n\t\t\tconst similarityThreshold =\n\t\t\t\toptions?.similarityThreshold ?? this.context.config?.commits.similarityThreshold;\n\t\t\tconst configs =\n\t\t\t\toptions?.renameLimit != null\n\t\t\t\t\t? [...gitConfigsDiff, '-c', `diff.renameLimit=${options.renameLimit}`]\n\t\t\t\t\t: gitConfigsDiff;\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: configs, errors: options?.errors === 'throw' ? 'throw' : undefined },\n\t\t\t\t'diff',\n\t\t\t\t'--numstat',\n\t\t\t\t'--summary',\n\t\t\t\t`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`,\n\t\t\t\t'--no-ext-diff',\n\t\t\t\t'-z',\n\t\t\t\toptions?.filters?.length ? `--diff-filter=${options.filters.join('')}` : undefined,\n\t\t\t\tref1OrRange ? ref1OrRange : undefined,\n\t\t\t\tref2 ? ref2 : undefined,\n\t\t\t\t'--',\n\t\t\t\toptions?.path ? options.path : undefined,\n\t\t\t);\n\n\t\t\tconst files = result.stdout ? (parseGitDiffNumStatFiles(result.stdout, repoPath) ?? []) : [];\n\n\t\t\t// Merge in untracked files when the comparison involves the working tree.\n\t\t\t// Skip when `filters` excludes additions (untracked entries are semantically 'A'/added),\n\t\t\t// or when `path` is a non-exact pathspec we can't reliably match against the untracked list.\n\t\t\tif (\n\t\t\t\toptions?.includeUntracked &&\n\t\t\t\tref2 == null &&\n\t\t\t\ttypeof ref1OrRange === 'string' &&\n\t\t\t\t!isRevisionRange(ref1OrRange) &&\n\t\t\t\t!isUncommittedStaged(ref1OrRange) &&\n\t\t\t\tfiltersAllowUntracked(options.filters) &&\n\t\t\t\t!isNonExactPathspec(options.path)\n\t\t\t) {\n\t\t\t\tconst untracked = await this.getUntrackedFilesForDiff(repoPath, options.errors);\n\t\t\t\tif (untracked.length) {\n\t\t\t\t\tconst seen = new Set(files.map(f => f.path));\n\t\t\t\t\tfor (const file of untracked) {\n\t\t\t\t\t\tif (seen.has(file.path)) continue;\n\t\t\t\t\t\tif (options.path && options.path !== file.path) continue;\n\n\t\t\t\t\t\tfiles.push(file);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn files.length ? files : undefined;\n\t\t} catch (ex) {\n\t\t\tif (options?.errors === 'throw') throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * The untracked files a working-tree diff folds in; outside `errors: 'throw'`, a failed listing adds nothing. The diff\n\t * reads take no cancellation, so a `CancellationError` here is a timeout and degrades like any other failure.\n\t */\n\tprivate async getUntrackedFilesForDiff(repoPath: string, errors: GitErrorHandling | undefined): Promise<GitFile[]> {\n\t\ttry {\n\t\t\treturn (await this.provider.status?.getUntrackedFiles?.(repoPath)) ?? [];\n\t\t} catch (ex) {\n\t\t\tif (errors === 'throw') throw ex;\n\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDiffTool(repoPath?: string): Promise<string | undefined> {\n\t\treturn (\n\t\t\t(await this.provider.config.getConfig?.(repoPath, 'diff.guitool', { runGitLocally: true })) ??\n\t\t\tthis.provider.config.getConfig?.(repoPath, 'diff.tool', { runGitLocally: true })\n\t\t);\n\t}\n\n\t@debug()\n\tasync getNextComparisonUris(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\tskip: number = 0,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<NextComparisonUrisResult | undefined> {\n\t\t// If we have no revision there is no next commit\n\t\tif (!rev) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\n\t\tif (isUncommittedStaged(rev)) {\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, relativePath, rev),\n\t\t\t\tnext: createRevisionUri(this.provider, repoPath, relativePath, undefined),\n\t\t\t};\n\t\t} else if (isUncommitted(rev)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\t\tconst args = ['log', ...parser.arguments];\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\targs.push(\n\t\t\t\t// Use reverse to get the next commits (oldest to newest instead of newest to oldest)\n\t\t\t\t'--reverse',\n\t\t\t);\n\n\t\t\tif (rev !== deletedOrMissing) {\n\t\t\t\targs.push(\n\t\t\t\t\t// Ancestry path to ensure we only follow the path from the given revision to HEAD\n\t\t\t\t\t'--ancestry-path',\n\t\t\t\t\t// Range from the given revision to HEAD\n\t\t\t\t\t`${rev}..HEAD`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Follow file history and specify the file path\n\t\t\targs.push('--follow', '--', relativePath);\n\n\t\t\t// Unbounded --follow walk over file history can be slow on long histories — queue as background\n\t\t\t// so it doesn't compete with interactive work.\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsLog, priority: 'background' },\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tlet currentSha;\n\t\t\tlet currentPath;\n\n\t\t\tif (skip === 0) {\n\t\t\t\tcurrentSha = rev;\n\t\t\t\tcurrentPath = relativePath;\n\t\t\t} else {\n\t\t\t\tskip--;\n\t\t\t}\n\n\t\t\tlet nextSha;\n\t\t\tlet nextPath;\n\n\t\t\tlet file;\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.path && file.path !== relativePath) {\n\t\t\t\t\trelativePath = file.path;\n\t\t\t\t}\n\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t} else if (nextSha == null) {\n\t\t\t\t\t// if (commit.sha === rev) continue;\n\n\t\t\t\t\tnextSha = commit.sha;\n\t\t\t\t\tnextPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, relativePath);\n\t\t\t\tif (status != null) {\n\t\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\t\tcurrentSha = uncommittedStaged;\n\t\t\t\t\t\tcurrentPath = status.originalPath ?? status.path;\n\t\t\t\t\t\tnextSha = '';\n\t\t\t\t\t\tnextPath = status.path;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (nextSha == null || nextPath == null) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, relativePath);\n\t\t\t\tif (status != null) {\n\t\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\t\tnextSha = uncommittedStaged;\n\t\t\t\t\t\tnextPath = status.originalPath ?? status.path;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnextSha = '';\n\t\t\t\t\t\tnextPath = status.path;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnextSha = '';\n\t\t\t\t\tnextPath = relativePath;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tnext: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tnextPath ?? currentPath,\n\t\t\t\t\t(nextSha ?? deletedOrMissing) || undefined,\n\t\t\t\t),\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getPreviousComparisonUris(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\tskip: number = 0,\n\t\tunsaved?: boolean,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PreviousComparisonUrisResult | undefined> {\n\t\tif (rev === deletedOrMissing) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tif (rev === uncommitted) {\n\t\t\trev = undefined;\n\t\t}\n\n\t\t/* Rules:\n\t\t * Starting from working tree (rev is empty or undefined):\n\t\t * 1. Check file status:\n\t\t * 1.1. If file has both staged and working (or unsaved) changes:\n\t\t * - If skip=0: diff working with staged\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.2. If file has only staged changes:\n\t\t * - If skip=0: diff working with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.3. If file has only working changes:\n\t\t * - If skip=0: diff working with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.4. If file has no changes (or no status found):\n\t\t * - If skip=0: diff working with HEAD~1\n\t\t * - If skip>0: skip through revs starting at HEAD~1\n\t\t *\n\t\t * Starting from staged (rev is uncommittedStaged):\n\t\t * 1. Check file status:\n\t\t * 1.1. If status exists:\n\t\t * - If skip=0: diff staged with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.2. If status doesn't exist:\n\t\t * - If skip=0: diff HEAD with HEAD~1\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * Starting from a commit (rev is a SHA):\n\t\t * - If skip=0: diff SHA with SHA^\n\t\t * - If skip>0: skip through revs starting at SHA\n\t\t */\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\t\tlet skipPrev = 0;\n\n\t\tlet revs: [string, string][] = [];\n\t\tif (!rev) {\n\t\t\trevs = [['', relativePath]];\n\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\trevs.push([uncommittedStaged, status.originalPath ?? status.path]);\n\t\t\t\t}\n\n\t\t\t\trevs.push(['HEAD', status.originalPath ?? status.path]);\n\t\t\t\tif (status.workingTreeStatus == null && !unsaved) {\n\t\t\t\t\tif (skip === 0 || status.indexStatus == null) {\n\t\t\t\t\t\t// Skip over the HEAD commit to get a diff, because working and HEAD are the same\n\t\t\t\t\t\tskipPrev++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trevs.push(['HEAD', relativePath]);\n\t\t\t\tif (!unsaved) {\n\t\t\t\t\t// Skip over the HEAD commit to get a diff, because working and HEAD are the same\n\t\t\t\t\tskipPrev++;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isUncommittedStaged(rev)) {\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\trevs = [\n\t\t\t\t\t[uncommittedStaged, status.originalPath ?? status.path],\n\t\t\t\t\t['HEAD', status.originalPath ?? status.path],\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\t// Even though we supposedly started at staged, there is no staged version\n\t\t\t\trevs = [['HEAD', relativePath]];\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet currentSha;\n\t\tlet currentPath;\n\n\t\tif (revs.length) {\n\t\t\tskip++;\n\t\t\twhile (revs.length && skip > 0) {\n\t\t\t\tskip--;\n\t\t\t\t[rev, relativePath] = revs.shift()!;\n\t\t\t}\n\n\t\t\tif (rev !== 'HEAD') {\n\t\t\t\tcurrentSha = rev;\n\t\t\t\tcurrentPath = relativePath;\n\n\t\t\t\tskipPrev++;\n\t\t\t\twhile (revs.length && skipPrev > 0) {\n\t\t\t\t\tskipPrev--;\n\t\t\t\t\t[rev, relativePath] = revs.shift()!;\n\t\t\t\t}\n\n\t\t\t\tif (skipPrev > 0) {\n\t\t\t\t\tskip += skipPrev;\n\t\t\t\t}\n\n\t\t\t\tif (rev !== 'HEAD' && skip === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha),\n\t\t\t\t\t\tprevious: createRevisionUri(this.provider, repoPath, relativePath, rev),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\t\tconst args = ['log', ...parser.arguments, `-n${skip + 2}`]; // Don't use --skip as it doesn't work with --follow\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\targs.push('--follow', rev!, '--', relativePath);\n\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\tconfigs: gitConfigsLog,\n\t\t\t\t\tcaching: { cache: this.cache.gitResults, options: { accessTTL: 5 * 60 * 1000 } },\n\t\t\t\t},\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tlet previousSha;\n\t\t\tlet previousPath;\n\t\t\tlet file;\n\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.originalPath && file.originalPath !== relativePath) {\n\t\t\t\t\trelativePath = file.originalPath;\n\t\t\t\t}\n\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t} else if (previousSha == null) {\n\t\t\t\t\tif (commit.sha === rev) continue;\n\n\t\t\t\t\tpreviousSha = commit.sha;\n\t\t\t\t\tpreviousPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) return undefined;\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tprevious: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpreviousPath ?? currentPath,\n\t\t\t\t\tpreviousSha ?? deletedOrMissing,\n\t\t\t\t),\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getPreviousComparisonUrisForRange(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\trange: DiffRange,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null; skipFirstRev?: boolean },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PreviousRangeComparisonUrisResult | undefined> {\n\t\tif (rev === deletedOrMissing) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tif (rev === uncommitted) {\n\t\t\trev = undefined;\n\t\t}\n\n\t\tlet currentSha;\n\t\tlet currentPath;\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\t\tconst skipFirstRev = options?.skipFirstRev ?? true;\n\n\t\t// If we are at the working tree (i.e. no ref), we need to dig deeper to figure out where to go\n\t\tif (!rev) {\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\tif (status.workingTreeStatus != null && !skipFirstRev) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, relativePath, undefined),\n\t\t\t\t\t\t\tprevious: createRevisionUri(this.provider, repoPath, relativePath, uncommittedStaged),\n\t\t\t\t\t\t\trange: range,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrentSha = uncommittedStaged;\n\t\t\t\t\tcurrentPath = status.originalPath ?? status.path;\n\t\t\t\t\tif (status.originalPath != null) {\n\t\t\t\t\t\trelativePath = status.originalPath;\n\t\t\t\t\t}\n\t\t\t\t\trev = uncommittedStaged;\n\t\t\t\t} else if (status.workingTreeStatus != null && !skipFirstRev) {\n\t\t\t\t\tcurrentSha = '';\n\t\t\t\t\tcurrentPath = relativePath;\n\t\t\t\t\trev = '';\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (!skipFirstRev) {\n\t\t\tcurrentSha = rev;\n\t\t\tcurrentPath = relativePath;\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileRangeLogParser();\n\t\t\tconst args = ['log', ...parser.arguments, '-n2']; // Don't use --skip as it doesn't work with --follow\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\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\targs.push(`-L${range.startLine},${range.endLine}:${relativePath}`);\n\n\t\t\tlet result: GitResult;\n\t\t\ttry {\n\t\t\t\tresult = await this.git.run({ cwd: repoPath, configs: gitConfigsLog }, ...args);\n\t\t\t} catch (ex) {\n\t\t\t\tif (rev && !isUncommittedStaged(rev)) throw ex;\n\n\t\t\t\t// If the line count is invalid reset to a valid range\n\t\t\t\tconst match = GitErrors.invalidLineCount.exec(ex?.toString() ?? '');\n\t\t\t\tif (match == null) throw ex;\n\n\t\t\t\tconst line = parseInt(match[1], 10);\n\t\t\t\tif (isNaN(line)) throw ex;\n\n\t\t\t\tconst index = args.findIndex(a => a.startsWith('-L'));\n\t\t\t\tif (index === -1) throw ex;\n\n\t\t\t\trange = {\n\t\t\t\t\tstartLine: Math.min(range.startLine, line),\n\t\t\t\t\tstartCharacter: range.startCharacter,\n\t\t\t\t\tendLine: Math.min(range.endLine, line),\n\t\t\t\t\tendCharacter: range.endCharacter,\n\t\t\t\t\tactive: range.active,\n\t\t\t\t};\n\n\t\t\t\targs.splice(index, 1, `-L${range.startLine},${range.endLine}:${relativePath}`);\n\t\t\t\tresult = await this.git.run({ cwd: repoPath, configs: gitConfigsLog }, ...args);\n\t\t\t}\n\n\t\t\tlet currentRange;\n\t\t\tlet previousSha;\n\t\t\tlet previousPath;\n\t\t\tlet file;\n\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// If we couldn't find the file, but there is only one file in the commit, use that one and assume the filename changed\n\t\t\t\tif (file == null && commit.files.length === 1) {\n\t\t\t\t\tfile = commit.files[0];\n\t\t\t\t\trelativePath = file.path;\n\t\t\t\t}\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.originalPath && file.originalPath !== relativePath) {\n\t\t\t\t\trelativePath = file.originalPath;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t\tcurrentRange =\n\t\t\t\t\t\tfile?.range != null ? { ...file.range, startCharacter: 1, endCharacter: 1 } : undefined;\n\t\t\t\t} else if (previousSha == null) {\n\t\t\t\t\tif (commit.sha === rev) continue;\n\n\t\t\t\t\tpreviousSha = commit.sha;\n\t\t\t\t\tpreviousPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) return undefined;\n\n\t\t\t// If we have no previous SHA but have a real current SHA, resolve the parent commit.\n\t\t\t// This handles the case where a line is newly added — the line has no prior history,\n\t\t\t// but the file likely existed at the parent commit\n\t\t\tif (previousSha == null && currentSha) {\n\t\t\t\tpreviousSha =\n\t\t\t\t\t(await this.provider.refs.validateReference(repoPath, `${currentSha}^`)) ?? deletedOrMissing;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tprevious: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpreviousPath ?? currentPath,\n\t\t\t\t\tpreviousSha ?? deletedOrMissing,\n\t\t\t\t),\n\t\t\t\trange: currentRange ?? range,\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Returns raw diff output for a file between two revisions. */\n\tasync diff(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1?: string,\n\t\tref2?: string,\n\t\toptions?: {\n\t\t\tencoding?: string;\n\t\t\tfilters?: GitDiffFilter[];\n\t\t\tlinesOfContext?: number;\n\t\t\t/** Path of the file on the ref1 side (when renamed/copied); added to the pathspec so git can pair the rename */\n\t\t\toriginalPath?: string;\n\t\t\trenames?: boolean;\n\t\t\tsimilarityThreshold?: number | null;\n\t\t},\n\t): Promise<GitResult> {\n\t\tconst params = ['diff', '--no-ext-diff', '--minimal'];\n\n\t\tif (options?.linesOfContext != null) {\n\t\t\tparams.push(`-U${options.linesOfContext}`);\n\t\t}\n\n\t\tif (options?.renames) {\n\t\t\tparams.push(`-M${options.similarityThreshold == null ? '' : `${options.similarityThreshold}%`}`);\n\t\t}\n\n\t\tif (options?.filters != null && options.filters.length !== 0) {\n\t\t\tparams.push(`--diff-filter=${options.filters.join('')}`);\n\t\t}\n\n\t\tif (ref1) {\n\t\t\t// <sha>^3 signals an untracked file in a stash and if we are trying to find its parent, use the empty tree\n\t\t\tif (ref1.endsWith('^3^')) {\n\t\t\t\tref1 = await this.provider.revision.getEmptyTreeSha(repoPath);\n\t\t\t}\n\t\t\tparams.push(isUncommittedStaged(ref1) ? '--staged' : ref1);\n\t\t}\n\t\tif (ref2) {\n\t\t\tparams.push(isUncommittedStaged(ref2) ? '--staged' : ref2);\n\t\t}\n\n\t\ttry {\n\t\t\treturn await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, encoding: options?.encoding },\n\t\t\t\t...params,\n\t\t\t\t'--',\n\t\t\t\tfileName,\n\t\t\t\t...(options?.originalPath && options.originalPath !== fileName ? [options.originalPath] : []),\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tconst match = GitErrors.badRevision.exec(ex.message);\n\t\t\tif (match !== null) {\n\t\t\t\tconst [, ref] = match;\n\n\t\t\t\t// If the bad ref is trying to find a parent ref, assume we hit to the last commit, so try again using the empty tree\n\t\t\t\tif (ref === ref1 && ref?.endsWith('^')) {\n\t\t\t\t\treturn this.diff(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tfileName,\n\t\t\t\t\t\tawait this.provider.revision.getEmptyTreeSha(repoPath),\n\t\t\t\t\t\tref2,\n\t\t\t\t\t\toptions,\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/** Returns raw diff output comparing a file's revision with given contents via stdin. */\n\tasync diffContents(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions?: { encoding?: string; filters?: GitDiffFilter[]; similarityThreshold?: number | null },\n\t): Promise<string> {\n\t\tconst params = [\n\t\t\t'diff',\n\t\t\t`-M${options?.similarityThreshold == null ? '' : `${options.similarityThreshold}%`}`,\n\t\t\t'--no-ext-diff',\n\t\t\t'-U0',\n\t\t\t'--minimal',\n\t\t];\n\n\t\tif (options?.filters != null && options.filters.length !== 0) {\n\t\t\tparams.push(`--diff-filter=${options.filters.join('')}`);\n\t\t}\n\n\t\tparams.push('--no-index');\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\tconfigs: gitConfigsDiff,\n\t\t\t\t\tencoding: options?.encoding,\n\t\t\t\t\tstdin: contents,\n\t\t\t\t},\n\t\t\t\t...params,\n\t\t\t\t'--',\n\t\t\t\tfileName,\n\t\t\t\t// Pipe the contents to stdin\n\t\t\t\t'-',\n\t\t\t);\n\t\t\treturn result.stdout;\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof GitError && ex.stdout) {\n\t\t\t\treturn ex.stdout;\n\t\t\t}\n\n\t\t\tconst match = GitErrors.badRevision.exec(ex.message);\n\t\t\tif (match !== null) {\n\t\t\t\tconst [, matchedRef] = match;\n\n\t\t\t\t// If the bad ref is trying to find a parent ref, assume we hit to the last commit, so try again using the empty tree\n\t\t\t\tif (matchedRef === ref && matchedRef?.endsWith('^')) {\n\t\t\t\t\treturn this.diffContents(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tfileName,\n\t\t\t\t\t\tawait this.provider.revision.getEmptyTreeSha(repoPath),\n\t\t\t\t\t\tcontents,\n\t\t\t\t\t\toptions,\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/** Returns parsed diff hunks for a file between two revisions. */\n\t@debug()\n\tgetDiffForFile(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1: string | undefined,\n\t\tref2?: string,\n\t\toptions?: { encoding?: string; originalPath?: string },\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst cacheKey = `${normalizePath(fileName)}${\n\t\t\toptions?.originalPath ? `<${normalizePath(options.originalPath)}` : ''\n\t\t}:${ref1 ?? ''}:${ref2 ?? ''}`;\n\t\treturn this.cache.diff.getOrCreate(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\t() => this.getDiffForFileCore(repoPath, fileName, ref1, ref2, options),\n\t\t\t{ errorTTL: 1000 * 60 },\n\t\t);\n\t}\n\n\tprivate async getDiffForFileCore(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1: string | undefined,\n\t\tref2: string | undefined,\n\t\toptions: { encoding?: string; originalPath?: string } | undefined,\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\t// Include renames (R) and copies (C) so content diffs on renamed files still surface;\n\t\t// --diff-filter runs after `-M` rename detection, so 'M' alone would drop valid rename diffs.\n\t\tconst result = await this.diff(repoPath, fileName, ref1, ref2, {\n\t\t\tencoding: options?.encoding,\n\t\t\tfilters: ['M', 'R', 'C'],\n\t\t\tlinesOfContext: 0,\n\t\t\toriginalPath: options?.originalPath,\n\t\t\trenames: true,\n\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t});\n\t\treturn parseGitFileDiff(result.stdout);\n\t}\n\n\t/** Returns parsed diff hunks comparing a file's revision with given contents via stdin. */\n\t@debug()\n\tgetDiffForFileContents(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions?: { encoding?: string },\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst cacheKey = `${normalizePath(fileName)}:${ref}:~${fnv1aHash(contents)}`;\n\t\treturn this.cache.diff.getOrCreate(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\t() => this.getDiffForFileContentsCore(repoPath, fileName, ref, contents, options),\n\t\t\t{ errorTTL: 1000 * 60 },\n\t\t);\n\t}\n\n\tprivate async getDiffForFileContentsCore(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions: { encoding?: string } | undefined,\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst data = await this.diffContents(repoPath, fileName, ref, contents, {\n\t\t\tencoding: options?.encoding,\n\t\t\tfilters: ['M', 'R', 'C'],\n\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t});\n\t\treturn parseGitFileDiff(data);\n\t}\n\n\t/** Finds the most recent commit where the given path was copied, renamed, or deleted. */\n\t@debug()\n\tasync findPathStatusChanged(\n\t\trepoPath: string,\n\t\tpathspec: string,\n\t\trev: string | undefined,\n\t\toptions?: { filters?: GitDiffFilter[]; ordering?: 'date' | 'author-date' | 'topo' | null },\n\t): Promise<{ sha: string; file: LogParsedFile | undefined } | undefined> {\n\t\treturn findPathStatusChanged(this.git, repoPath, pathspec, rev, options);\n\t}\n\n\t@debug()\n\tasync openDiffTool(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\toptions?: { ref1?: string; ref2?: string; staged?: boolean; tool?: string },\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\t\tconst [relativePath, root] = splitPath(toFsPath(pathOrUri), repoPath);\n\n\t\ttry {\n\t\t\tlet tool = options?.tool;\n\t\t\tif (!tool) {\n\t\t\t\tconst scope = getScopedLogger();\n\n\t\t\t\ttool = await this.getDiffTool(root);\n\t\t\t\tif (tool == null) throw new Error('No diff tool found');\n\n\t\t\t\tscope?.debug(`Using tool=${tool}`);\n\t\t\t}\n\n\t\t\tawait this.git.run(\n\t\t\t\t{ cwd: root },\n\t\t\t\t'difftool',\n\t\t\t\t'--no-prompt',\n\t\t\t\t`--tool=${tool}`,\n\t\t\t\toptions?.staged ? '--staged' : undefined,\n\t\t\t\toptions?.ref1 ? options.ref1 : undefined,\n\t\t\t\toptions?.ref2 ? options.ref2 : undefined,\n\t\t\t\t'--',\n\t\t\t\trelativePath,\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif ((ex instanceof Error && ex.message === 'No diff tool found') || /Unknown .+? tool/.test(msg)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Unable to open changes because the specified diff tool cannot be found or no Git diff tool is configured',\n\t\t\t\t\t),\n\t\t\t\t\t{ cause: ex },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync openDirectoryCompare(repoPath: string, ref1: string, ref2?: string, tool?: string): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tif (!tool) {\n\t\t\t\tconst scope = getScopedLogger();\n\n\t\t\t\ttool = await this.getDiffTool(repoPath);\n\t\t\t\tif (tool == null) throw new Error('No diff tool found');\n\n\t\t\t\tscope?.debug(`Using tool=${tool}`);\n\t\t\t}\n\n\t\t\tawait this.git.run({ cwd: repoPath }, 'difftool', '--dir-diff', `--tool=${tool}`, ref1, ref2);\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif ((ex instanceof Error && ex.message === 'No diff tool found') || /Unknown .+? tool/.test(msg)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Unable to open directory compare because the specified diff tool cannot be found or no Git diff tool is configured',\n\t\t\t\t\t),\n\t\t\t\t\t{ cause: ex },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n}\n// Returns true when no --diff-filter is active or when it includes additions ('A' or '*').\n// Untracked files are semantically \"added\" — if a caller restricts filters to e.g. ['M'],\n// honor that and omit untracked.\nfunction filtersAllowUntracked(filters: GitDiffFilter[] | undefined): boolean {\n\tif (!filters?.length) return true;\n\treturn filters.includes('A') || filters.includes('*');\n}\n\n// Returns true when the path is a git pathspec we can't match with simple equality\n// (directory prefix, glob, or magic pathspec). In that case, skip the untracked merge\n// rather than risk excluding legitimate matches or including wrong ones.\nfunction isNonExactPathspec(path: string | undefined): boolean {\n\tif (!path) return false;\n\treturn path.endsWith('/') || /[*?[\\]]|^:/.test(path);\n}\n\n// Returns true when the `git diff` invocation shape includes the working tree\n// (i.e. `git diff`, `git diff HEAD`, or `git diff <ref>` with no `from`), and\n// therefore untracked files are a meaningful addition to the result.\nfunction isWorkingTreeComparison(to: string | undefined, from: string | undefined): boolean {\n\tif (to == null) return true;\n\tif (isRevisionRange(to) || isUncommittedStaged(to)) return false;\n\n\t// `to === uncommitted` always targets the working tree (`prepareToFromDiffArgs` sets\n\t// `from = 'HEAD'` when omitted, or diffs against the caller-supplied `from`).\n\tif (isUncommitted(to)) return true;\n\n\t// `git diff <from>` — `to === ''` means the caller explicitly asked for working tree vs `from`\n\tif (to === '') return from == null || !isUncommittedStaged(from);\n\n\t// `getChangedFilesCount` uses `prepareToFromDiffArgs`, which translates `to` (with no `from`)\n\t// to `${to}^ ${to}` UNLESS `to` is HEAD or empty.\n\tif (isHead(to) && from == null) return true;\n\treturn false;\n}\n\nfunction isHead(ref: string | undefined): boolean {\n\treturn ref?.toUpperCase() === 'HEAD';\n}\n\n/** Whether `ex` is git failing to resolve `HEAD` because the repository has no commit yet */\nasync function isUnbornHeadFailure(provider: CliGitProviderInternal, repoPath: string, ex: unknown): Promise<boolean> {\n\tconst ref = GitErrors.badRevision.exec(String(ex))?.[1];\n\tif (!isHead(ref)) return false;\n\n\treturn (await provider.refs.validateReference(repoPath, 'HEAD', { force: true })) == null;\n}\n\nfunction prepareToFromDiffArgs(\n\tto: string,\n\tfrom: string | undefined,\n\targs: string[],\n\tnotation?: GitRevisionRangeNotation,\n): string {\n\tif (to === uncommitted) {\n\t\tif (from != null) {\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\t// Get only unstaged changes\n\t\t\tfrom = 'HEAD';\n\t\t}\n\t} else if (to === uncommittedStaged) {\n\t\targs.push('--staged');\n\t\tif (from != null) {\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\t// Get only staged changes\n\t\t\tfrom = 'HEAD';\n\t\t}\n\t} else if (from == null) {\n\t\tif (to === '' || isHead(to)) {\n\t\t\tfrom = 'HEAD';\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\tfrom = `${to}^`;\n\t\t\targs.push(from, to);\n\t\t}\n\t} else if (to === '') {\n\t\targs.push(from);\n\t} else if (notation != null) {\n\t\targs.push(`${from}${notation}${to}`);\n\t} else {\n\t\targs.push(from, to);\n\t}\n\treturn from;\n}\n\nfunction createRevisionUri(\n\tprovider: CliGitProviderInternal,\n\trepoPath: string,\n\trelativePath: string,\n\tsha: string | undefined,\n): RevisionUri {\n\treturn {\n\t\turi: sha\n\t\t\t? fromUri({\n\t\t\t\t\tscheme: 'gitlens',\n\t\t\t\t\tauthority: encodeGitLensRevisionUriAuthority({ ref: sha, repoPath: repoPath }),\n\t\t\t\t\tpath: provider.getAbsoluteUri(relativePath, repoPath).path,\n\t\t\t\t})\n\t\t\t: provider.getAbsoluteUri(relativePath, repoPath),\n\t\tpath: relativePath,\n\t\tsha: sha,\n\t\trepoPath: repoPath,\n\t};\n}\n\nexport async function findPathStatusChanged(\n\tgit: Git,\n\trepoPath: string,\n\tpathspec: string,\n\trev: string | undefined,\n\toptions?: { filters?: GitDiffFilter[]; ordering?: 'date' | 'author-date' | 'topo' | null },\n): Promise<{ sha: string; file: LogParsedFile | undefined } | undefined> {\n\tconst parser = getShaAndFileSummaryLogParser();\n\n\tconst ordering = options?.ordering;\n\n\tconst result = await git.run(\n\t\t{ cwd: repoPath, configs: gitConfigsLog },\n\t\t'log',\n\t\t...parser.arguments,\n\t\tordering ? `--${ordering}-order` : undefined,\n\t\t'--no-walk',\n\t\t`--diff-filter=${options?.filters?.length ? options.filters.join('') : 'RCD'}`,\n\t\trev,\n\t\t// Note: --no-walk constrains to the exact commit (no ancestor search). Pathspec is omitted\n\t\t// because git suppresses rename detection with pathspecs (shows D instead of R, losing the destination path).\n\t\t'--',\n\t);\n\n\tconst commit = first(parser.parse(result.stdout));\n\tif (commit == null) return undefined;\n\n\tconst file = commit.files.find(f => f.path === pathspec || f.originalPath === pathspec);\n\treturn { sha: commit.sha, file: file };\n}\n"],"mappings":"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"}
@@ -3,11 +3,11 @@ import { CancellationError, isCancellationError } from "../../utils/cancellation
3
3
  import { getScopedLogger } from "../../utils/logger.scoped.js";
4
4
  import { getSettledValue } from "../../utils/promise.js";
5
5
  import { debug } from "../../utils/decorators/log.js";
6
+ import { createDisposable } from "../../utils/disposable.js";
6
7
  import { getBranchId, getBranchNameWithoutRemote, getRemoteNameFromBranchName } from "../../utils/gitRefs.js";
7
8
  import { isUncommitted } from "../../git/utils/revision.utils.js";
8
9
  import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
9
10
  import { GitSearchError } from "../../git/errors.js";
10
- import { createDisposable } from "../../utils/disposable.js";
11
11
  import { classifySearchError, gitConfigsLog } from "../exec/git.js";
12
12
  import { fnv1aHash64 } from "../../utils/hash.js";
13
13
  import { isUserMatch } from "../../git/utils/user.utils.js";
@@ -10,10 +10,10 @@ import "../../git/gitHealth.js";
10
10
  import { fsExists } from "../../utils/env/node/exec.js";
11
11
  import { canonicalizeGitConfigKey, isGitBooleanFalse, parseConfigRegexOutput, parseGitBoolean } from "./config.js";
12
12
  import * as l10n from "@vscode/l10n";
13
+ import { hostname } from "node:os";
13
14
  import * as process from "node:process";
14
15
  import { randomUUID } from "node:crypto";
15
16
  import { mkdir, open, readFile, readdir, realpath, rename, rm, stat } from "node:fs/promises";
16
- import { hostname } from "node:os";
17
17
  //#region ../git-cli/src/providers/maintenance.ts
18
18
  /** Deterministic sample of the 256 object fanout dirs (`00`,`10`,…,`f0`) used to extrapolate loose-object count. */
19
19
  const looseObjectSampleDirs = Array.from({ length: 16 }, (_, i) => (i * 16).toString(16).padStart(2, "0"));
@@ -9,8 +9,8 @@ import { PausedOperationAbortError, PausedOperationContinueError } from "../../g
9
9
  import { getGitCommandError } from "../exec/git.js";
10
10
  import { gate } from "../../utils/decorators/gate.js";
11
11
  import * as l10n from "@vscode/l10n";
12
+ import { readdir } from "fs";
12
13
  import { readFile, stat } from "fs/promises";
13
- import { readdir as readdir$1 } from "fs";
14
14
  //#region ../git-cli/src/providers/pausedOperations.ts
15
15
  const todoCommitRegex = /^(?:p(?:ick)?|revert)\s+([a-f0-9]+)(?:\s+(.+))?$/i;
16
16
  const orderedOperations = [
@@ -38,7 +38,7 @@ var PausedOperationsGitSubProvider = class {
38
38
  return this.cache.pausedOperationStatus.getOrCreate(repoPath, async (_cancellable) => {
39
39
  const gitDir = await this.provider.config.getGitDir(repoPath);
40
40
  const operations = await new Promise((resolve, _) => {
41
- readdir$1(gitDir.uri.fsPath, { withFileTypes: true }, (err, entries) => {
41
+ readdir(gitDir.uri.fsPath, { withFileTypes: true }, (err, entries) => {
42
42
  const operations = /* @__PURE__ */ new Set();
43
43
  if (err != null) {
44
44
  resolve(operations);
@@ -1 +1 @@
1
- {"version":3,"file":"pausedOperations.js","names":[],"sources":["../../../../git-cli/src/providers/pausedOperations.ts"],"sourcesContent":["import { readdir } from 'fs';\nimport { readFile, stat } from 'fs/promises';\nimport * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { PausedOperationAbortError, PausedOperationContinueError } from '@gitlens/git/errors.js';\nimport type {\n\tGitCherryPickStatus,\n\tGitMergeStatus,\n\tGitPausedOperationStatus,\n\tGitRebaseStatus,\n\tGitRevertStatus,\n} from '@gitlens/git/models/pausedOperationStatus.js';\nimport type { GitBranchReference, GitTagReference } from '@gitlens/git/models/reference.js';\nimport type { GitDir } from '@gitlens/git/models/repository.js';\nimport type { GitPausedOperationsSubProvider } from '@gitlens/git/providers/pausedOperations.js';\nimport { createReference } from '@gitlens/git/utils/reference.utils.js';\nimport { CancellationError } from '@gitlens/utils/cancellation.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { joinPaths } from '@gitlens/utils/path.js';\nimport { getSettledValue } from '@gitlens/utils/promise.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { Git } from '../exec/git.js';\nimport { getGitCommandError } from '../exec/git.js';\n\nconst todoCommitRegex = /^(?:p(?:ick)?|revert)\\s+([a-f0-9]+)(?:\\s+(.+))?$/i;\n\ntype Operation = 'cherry-pick' | 'merge' | 'rebase-apply' | 'rebase-merge' | 'revert' | 'sequencer';\n\n// Note: 'sequencer' is checked after specific HEAD files since those take precedence\n// The sequencer directory is used for multi-commit cherry-picks/reverts\nconst orderedOperations: Operation[] = ['rebase-apply', 'rebase-merge', 'merge', 'cherry-pick', 'revert', 'sequencer'];\n\nexport class PausedOperationsGitSubProvider implements GitPausedOperationsSubProvider {\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@debug()\n\tgetPausedOperationStatus(\n\t\trepoPath: string,\n\t\toptions?: { force?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitPausedOperationStatus | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\t// Self-heal callers (WIP refresh) bypass the cache so a missed `'pausedOp'` FS-watcher\n\t\t// event (CLI-driven completion, torn-down secondary-worktree watcher) can't leave the\n\t\t// status stuck — the readdir-based detection is cheap enough to repeat on every tick.\n\t\tif (options?.force) {\n\t\t\tthis.cache.pausedOperationStatus.delete(repoPath);\n\t\t}\n\n\t\tconst status = this.cache.pausedOperationStatus.getOrCreate(repoPath, async _cancellable => {\n\t\t\tconst gitDir = await this.provider.config.getGitDir(repoPath);\n\n\t\t\tconst operations = await new Promise<Set<Operation>>((resolve, _) => {\n\t\t\t\treaddir(gitDir.uri.fsPath, { withFileTypes: true }, (err, entries) => {\n\t\t\t\t\tconst operations = new Set<Operation>();\n\t\t\t\t\tif (err != null) {\n\t\t\t\t\t\tresolve(operations);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (entries.length === 0) {\n\t\t\t\t\t\tresolve(operations);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet entry;\n\t\t\t\t\tfor (entry of entries) {\n\t\t\t\t\t\tif (entry.isFile()) {\n\t\t\t\t\t\t\tswitch (entry.name) {\n\t\t\t\t\t\t\t\tcase 'CHERRY_PICK_HEAD':\n\t\t\t\t\t\t\t\t\toperations.add('cherry-pick');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'MERGE_HEAD':\n\t\t\t\t\t\t\t\t\toperations.add('merge');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'REVERT_HEAD':\n\t\t\t\t\t\t\t\t\toperations.add('revert');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (entry.isDirectory()) {\n\t\t\t\t\t\t\tswitch (entry.name) {\n\t\t\t\t\t\t\t\tcase 'rebase-apply':\n\t\t\t\t\t\t\t\t\toperations.add('rebase-apply');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'rebase-merge':\n\t\t\t\t\t\t\t\t\toperations.add('rebase-merge');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'sequencer':\n\t\t\t\t\t\t\t\t\t// The sequencer directory is used for multi-commit cherry-picks/reverts\n\t\t\t\t\t\t\t\t\t// We'll determine the type by reading the todo file later\n\t\t\t\t\t\t\t\t\toperations.add('sequencer');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve(operations);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tif (!operations.size) return undefined;\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\tconst sortedOperations = [...operations].sort(\n\t\t\t\t(a, b) => orderedOperations.indexOf(a) - orderedOperations.indexOf(b),\n\t\t\t);\n\t\t\tscope?.info(`Detected paused operations: ${sortedOperations.join(', ')}`);\n\n\t\t\tconst operation = sortedOperations[0];\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'cherry-pick': {\n\t\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t'--verify',\n\t\t\t\t\t\t'CHERRY_PICK_HEAD',\n\t\t\t\t\t);\n\t\t\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cherryPickHead = result.stdout.trim();\n\t\t\t\t\tif (!cherryPickHead) {\n\t\t\t\t\t\tscope?.addExitInfo('No CHERRY_PICK_HEAD found');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [branchResult, mergeBaseResult, messageResult] = await Promise.allSettled([\n\t\t\t\t\t\tthis.provider.branches.getCurrentBranchReference(repoPath, cancellation),\n\t\t\t\t\t\tthis.provider.refs.getMergeBase(repoPath, 'CHERRY_PICK_HEAD', 'HEAD', undefined, cancellation),\n\t\t\t\t\t\tthis.getCommitMessage(repoPath, cherryPickHead, cancellation),\n\t\t\t\t\t]);\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst current = getSettledValue(branchResult)!;\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\t\t\t\t\t// Names the commit being applied, so consumers can say which one a skip would drop\n\t\t\t\t\tconst message = getSettledValue(messageResult);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'cherry-pick',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(cherryPickHead, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\tincoming: createReference(cherryPickHead, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t} satisfies GitCherryPickStatus;\n\t\t\t\t}\n\t\t\t\tcase 'merge': {\n\t\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t'--verify',\n\t\t\t\t\t\t'MERGE_HEAD',\n\t\t\t\t\t);\n\t\t\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst mergeHead = result.stdout.trim();\n\t\t\t\t\tif (!mergeHead) {\n\t\t\t\t\t\tscope?.addExitInfo('No MERGE_HEAD found');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [branchResult, mergeBaseResult, possibleSourceBranchesResult] = await Promise.allSettled([\n\t\t\t\t\t\tthis.provider.branches.getCurrentBranchReference(repoPath, cancellation),\n\t\t\t\t\t\tthis.provider.refs.getMergeBase(repoPath, 'MERGE_HEAD', 'HEAD', undefined, cancellation),\n\t\t\t\t\t\tthis.provider.branches.getBranchesWithCommits(\n\t\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\t\t['MERGE_HEAD'],\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t{ all: true, mode: 'pointsAt' },\n\t\t\t\t\t\t\tcancellation,\n\t\t\t\t\t\t),\n\t\t\t\t\t]);\n\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst current = getSettledValue(branchResult)!;\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\t\t\t\t\tconst possibleSourceBranches = getSettledValue(possibleSourceBranchesResult);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'merge',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(mergeHead, repoPath, { refType: 'revision' }),\n\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\tincoming:\n\t\t\t\t\t\t\tpossibleSourceBranches?.length === 1\n\t\t\t\t\t\t\t\t? createReference(possibleSourceBranches[0], repoPath, {\n\t\t\t\t\t\t\t\t\t\trefType: 'branch',\n\t\t\t\t\t\t\t\t\t\tname: possibleSourceBranches[0],\n\t\t\t\t\t\t\t\t\t\tremote: false,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: createReference(mergeHead, repoPath, { refType: 'revision' }),\n\t\t\t\t\t} satisfies GitMergeStatus;\n\t\t\t\t}\n\t\t\t\tcase 'revert': {\n\t\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t'--verify',\n\t\t\t\t\t\t'REVERT_HEAD',\n\t\t\t\t\t);\n\t\t\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst revertHead = result.stdout.trim();\n\t\t\t\t\tif (!revertHead) {\n\t\t\t\t\t\tscope?.addExitInfo('No REVERT_HEAD found');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [branchResult, mergeBaseResult, messageResult] = await Promise.allSettled([\n\t\t\t\t\t\tthis.provider.branches.getCurrentBranchReference(repoPath, cancellation),\n\t\t\t\t\t\tthis.provider.refs.getMergeBase(repoPath, 'REVERT_HEAD', 'HEAD', undefined, cancellation),\n\t\t\t\t\t\tthis.getCommitMessage(repoPath, revertHead, cancellation),\n\t\t\t\t\t]);\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst current = getSettledValue(branchResult)!;\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\t\t\t\t\t// Names the commit being reverted, so consumers can say which one a skip would drop\n\t\t\t\t\tconst message = getSettledValue(messageResult);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'revert',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(revertHead, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\tincoming: createReference(revertHead, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t} satisfies GitRevertStatus;\n\t\t\t\t}\n\t\t\t\tcase 'rebase-apply':\n\t\t\t\tcase 'rebase-merge': {\n\t\t\t\t\tlet branch = await this.readDotGitFile(gitDir, [operation, 'head-name']);\n\t\t\t\t\tif (!branch) {\n\t\t\t\t\t\tscope?.addExitInfo(`No '${operation}/head-name' found`);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [\n\t\t\t\t\t\trebaseHeadResult,\n\t\t\t\t\t\torigHeadResult,\n\t\t\t\t\t\tontoResult,\n\t\t\t\t\t\tstepsNumberResult,\n\t\t\t\t\t\tstepsTotalResult,\n\t\t\t\t\t\tstepsMessageResult,\n\t\t\t\t\t\tisInteractiveResult,\n\t\t\t\t\t] = await Promise.allSettled([\n\t\t\t\t\t\tthis.git.run(\n\t\t\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t\t'--verify',\n\t\t\t\t\t\t\t'REBASE_HEAD',\n\t\t\t\t\t\t),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'orig-head']),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'onto']),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'msgnum'], { numeric: true }),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'end'], { numeric: true }),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'message'], { throw: true }).catch(() =>\n\t\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'message-squashed']),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tstat(joinPaths(gitDir.uri.fsPath, operation, 'interactive')).then(\n\t\t\t\t\t\t\t() => true,\n\t\t\t\t\t\t\t() => false,\n\t\t\t\t\t\t),\n\t\t\t\t\t]);\n\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst origHead = getSettledValue(origHeadResult);\n\t\t\t\t\tconst onto = getSettledValue(ontoResult);\n\t\t\t\t\tif (origHead == null || onto == null) {\n\t\t\t\t\t\tscope?.addExitInfo(`Neither '${operation}/orig-head' nor '${operation}/onto' found`);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst rebaseHead = getSettledValue(rebaseHeadResult)?.stdout.trim();\n\n\t\t\t\t\tif (branch.startsWith('refs/heads/')) {\n\t\t\t\t\t\tbranch = branch.substring(11).trim();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [mergeBaseResult, branchTipsResult, tagTipsResult] = await Promise.allSettled([\n\t\t\t\t\t\trebaseHead\n\t\t\t\t\t\t\t? this.provider.refs.getMergeBase(repoPath, rebaseHead, 'HEAD', undefined, cancellation)\n\t\t\t\t\t\t\t: this.provider.refs.getMergeBase(repoPath, onto, origHead, undefined, cancellation),\n\t\t\t\t\t\tthis.provider.branches.getBranchesWithCommits(\n\t\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\t\t[onto],\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tall: true,\n\t\t\t\t\t\t\t\tmode: 'pointsAt',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcancellation,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tthis.provider.tags.getTagsWithCommit(repoPath, onto, { mode: 'pointsAt' }, cancellation),\n\t\t\t\t\t]);\n\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\t\t\t\t\tconst branchTips = getSettledValue(branchTipsResult);\n\t\t\t\t\tconst tagTips = getSettledValue(tagTipsResult);\n\n\t\t\t\t\tlet ontoRef: GitBranchReference | GitTagReference | undefined;\n\t\t\t\t\tif (branchTips != null) {\n\t\t\t\t\t\tfor (const ref of branchTips) {\n\t\t\t\t\t\t\tif (ref.startsWith('(no branch, rebasing')) continue;\n\n\t\t\t\t\t\t\tontoRef = createReference(ref, repoPath, {\n\t\t\t\t\t\t\t\trefType: 'branch',\n\t\t\t\t\t\t\t\tname: ref,\n\t\t\t\t\t\t\t\tremote: false,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (ontoRef == null && tagTips != null) {\n\t\t\t\t\t\tfor (const ref of tagTips) {\n\t\t\t\t\t\t\tif (ref.startsWith('(no branch, rebasing')) continue;\n\n\t\t\t\t\t\t\tontoRef = createReference(ref, repoPath, {\n\t\t\t\t\t\t\t\trefType: 'tag',\n\t\t\t\t\t\t\t\tname: ref,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst stepsNumber = getSettledValue(stepsNumberResult) ?? 0;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'rebase',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(rebaseHead ?? origHead, repoPath, { refType: 'revision' }),\n\t\t\t\t\t\tonto: createReference(onto, repoPath, { refType: 'revision' }),\n\t\t\t\t\t\tsource: createReference(origHead, repoPath, { refType: 'revision' }),\n\t\t\t\t\t\tcurrent: ontoRef,\n\t\t\t\t\t\tincoming: createReference(branch, repoPath, {\n\t\t\t\t\t\t\trefType: 'branch',\n\t\t\t\t\t\t\tname: branch,\n\t\t\t\t\t\t\tremote: false,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tsteps: {\n\t\t\t\t\t\t\tcurrent: {\n\t\t\t\t\t\t\t\tnumber: stepsNumber,\n\t\t\t\t\t\t\t\tcommit: rebaseHead\n\t\t\t\t\t\t\t\t\t? createReference(rebaseHead, repoPath, {\n\t\t\t\t\t\t\t\t\t\t\trefType: 'revision',\n\t\t\t\t\t\t\t\t\t\t\tmessage: getSettledValue(stepsMessageResult),\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttotal: getSettledValue(stepsTotalResult) ?? 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\thasStarted: stepsNumber > 0,\n\t\t\t\t\t\t// REBASE_HEAD only exists when git is paused and waiting for user action\n\t\t\t\t\t\tisPaused: stepsNumber > 0 && rebaseHead != null,\n\t\t\t\t\t\t// 'interactive' file exists for `git rebase -i`, absent for `git pull --rebase`\n\t\t\t\t\t\tisInteractive: getSettledValue(isInteractiveResult) ?? false,\n\t\t\t\t\t} satisfies GitRebaseStatus;\n\t\t\t\t}\n\t\t\t\tcase 'sequencer': {\n\t\t\t\t\t// Used for multi-commit cherry-picks/reverts when CHERRY_PICK_HEAD/REVERT_HEAD don't exist\n\t\t\t\t\tconst todoContent = await this.readDotGitFile(gitDir, ['sequencer', 'todo']);\n\t\t\t\t\tif (!todoContent) {\n\t\t\t\t\t\tscope?.addExitInfo('No sequencer/todo file found');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Get the first line and determine if it's a cherry-pick or revert\n\t\t\t\t\tconst firstLine = todoContent.split('\\n')[0]?.trim();\n\t\t\t\t\tif (!firstLine) {\n\t\t\t\t\t\tscope?.addExitInfo('Empty sequencer/todo file');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if it's a pick (cherry-pick) or revert command\n\t\t\t\t\t// Format: \"pick <sha> <message>\" or \"p <sha> <message>\" or \"revert <sha> <message>\"\n\t\t\t\t\tconst isCherryPick = /^p(?:ick)?\\s/.test(firstLine);\n\t\t\t\t\tconst isRevert = /^revert\\s/.test(firstLine);\n\n\t\t\t\t\tif (!isCherryPick && !isRevert) {\n\t\t\t\t\t\tscope?.addExitInfo(`Unknown sequencer command: ${firstLine}`);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Parse the commit sha being applied from the todo file\n\t\t\t\t\tconst match = firstLine.match(todoCommitRegex);\n\t\t\t\t\tconst currentCommitSha = match?.[1];\n\t\t\t\t\tif (!currentCommitSha) {\n\t\t\t\t\t\tscope?.addExitInfo('Could not parse commit sha from sequencer/todo');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\t// The todo line carries only the commit's SUBJECT (the other producers carry the full\n\t\t\t\t\t// message) — good enough to name the commit a skip would drop, without another git call\n\t\t\t\t\tconst message = match?.[2]?.trim() || undefined;\n\n\t\t\t\t\tconst [branchResult, mergeBaseResult] = await Promise.allSettled([\n\t\t\t\t\t\tthis.provider.branches.getCurrentBranchReference(repoPath, cancellation),\n\t\t\t\t\t\tthis.provider.refs.getMergeBase(repoPath, currentCommitSha, 'HEAD', undefined, cancellation),\n\t\t\t\t\t]);\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst current = getSettledValue(branchResult)!;\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\n\t\t\t\t\tif (isCherryPick) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: 'cherry-pick',\n\t\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\t\tHEAD: createReference(currentCommitSha, repoPath, {\n\t\t\t\t\t\t\t\trefType: 'revision',\n\t\t\t\t\t\t\t\tmessage: message,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\t\tincoming: createReference(currentCommitSha, repoPath, {\n\t\t\t\t\t\t\t\trefType: 'revision',\n\t\t\t\t\t\t\t\tmessage: message,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t} satisfies GitCherryPickStatus;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'revert',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(currentCommitSha, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\tincoming: createReference(currentCommitSha, repoPath, {\n\t\t\t\t\t\t\trefType: 'revision',\n\t\t\t\t\t\t\tmessage: message,\n\t\t\t\t\t\t}),\n\t\t\t\t\t} satisfies GitRevertStatus;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn status;\n\t}\n\n\t/** Memoized per repo by sha — forced status re-reads on FS noise (every file save while resolving\n\t * conflicts) would otherwise re-spawn `git log` for an unchanging commit. */\n\tprivate readonly _commitMessageCache = new Map<string, { sha: string; message: string | undefined }>();\n\n\tprivate async getCommitMessage(\n\t\trepoPath: string,\n\t\tsha: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tconst cached = this._commitMessageCache.get(repoPath);\n\t\tif (cached?.sha === sha) return cached.message;\n\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t'log',\n\t\t\t'-1',\n\t\t\t'--format=%B',\n\t\t\tsha,\n\t\t);\n\t\tconst message = result.stdout.trim() || undefined;\n\t\t// Don't cache a miss — a transient failure would otherwise stick for the operation's lifetime\n\t\tif (message != null) {\n\t\t\tthis._commitMessageCache.set(repoPath, { sha: sha, message: message });\n\t\t}\n\t\treturn message;\n\t}\n\n\tprivate async readDotGitFile(\n\t\tgitDir: GitDir,\n\t\tpathParts: string[],\n\t\toptions?: { numeric?: false; throw?: boolean; trim?: boolean },\n\t): Promise<string | undefined>;\n\tprivate async readDotGitFile(\n\t\tgitDir: GitDir,\n\t\tpathParts: string[],\n\t\toptions?: { numeric: true; throw?: boolean; trim?: boolean },\n\t): Promise<number | undefined>;\n\tprivate async readDotGitFile(\n\t\tgitDir: GitDir,\n\t\tpathParts: string[],\n\t\toptions?: { numeric?: boolean; throw?: boolean; trim?: boolean },\n\t): Promise<string | number | undefined> {\n\t\ttry {\n\t\t\tconst filePath = joinPaths(gitDir.uri.fsPath, ...pathParts);\n\t\t\tconst bytes = await readFile(filePath);\n\t\t\tlet contents = new TextDecoder('utf8').decode(bytes);\n\t\t\tcontents = (options?.trim ?? true) ? contents.trim() : contents;\n\n\t\t\tif (options?.numeric) {\n\t\t\t\tconst number = Number.parseInt(contents, 10);\n\t\t\t\treturn isNaN(number) ? undefined : number;\n\t\t\t}\n\n\t\t\treturn contents;\n\t\t} catch (ex) {\n\t\t\tif (options?.throw) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@gate((rp, o) => `${rp ?? ''}:${o?.quit ?? false}`)\n\t@debug()\n\tasync abortPausedOperation(repoPath: string, options?: { quit?: boolean }): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst status = await this.getPausedOperationStatus(repoPath);\n\t\tif (status == null) return;\n\n\t\tconst args = [status.type, options?.quit ? '--quit' : '--abort'];\n\n\t\ttry {\n\t\t\t// Unbounded like the operations it undoes — an abort of a large rebase can outrun the default\n\t\t\t// command timeout, and being SIGTERM'd partway through would leave the repo mid-abort.\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw', timeout: 0 }, ...args);\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'status');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['head', 'heads', 'index']);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'paused-operation-abort',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew PausedOperationAbortError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\toperation: status,\n\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tex,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\t@debug()\n\tasync continuePausedOperation(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tallowEmpty?: boolean;\n\t\t\tskip?: boolean;\n\t\t\tmessageEditor?: string;\n\t\t\teditorEnv?: Record<string, string>;\n\t\t},\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst status = await this.getPausedOperationStatus(repoPath);\n\t\tif (status == null) return;\n\n\t\tif (status.type === 'merge' && options?.skip) {\n\t\t\tthrow new Error(l10n.t('Skipping a merge is not supported'));\n\t\t}\n\n\t\tconst args = [status.type, options?.skip ? '--skip' : '--continue'];\n\n\t\t// Continuing after a conflicted step can open the commit-message editor (merge-backend rebases,\n\t\t// cherry-picks, and reverts). `GIT_EDITOR` is what git honors for that step, so set it on the\n\t\t// environment; also set `core.editor` config as a fallback.\n\t\tconst configs: string[] = [];\n\t\tlet env: Record<string, string | undefined> | undefined;\n\t\tif (options?.messageEditor) {\n\t\t\tconfigs.push('-c', `core.editor=${options.messageEditor}`);\n\t\t\tenv = { ...options.editorEnv, GIT_EDITOR: options.messageEditor };\n\t\t}\n\n\t\ttry {\n\t\t\tif (options?.allowEmpty) {\n\t\t\t\tconst commitArgs = ['commit', '--allow-empty', '--no-edit'];\n\t\t\t\ttry {\n\t\t\t\t\t// Git won't record the empty commit on its own; making it explicitly (`--no-edit` reuses the\n\t\t\t\t\t// message git already prepared) is what lets the operation move past it.\n\t\t\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw' }, ...commitArgs);\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tscope?.error(ex);\n\t\t\t\t\t// Same reason taxonomy, but attributed to the commit that actually failed\n\t\t\t\t\tthrow getGitCommandError(\n\t\t\t\t\t\t'paused-operation-continue',\n\t\t\t\t\t\tex,\n\t\t\t\t\t\treason =>\n\t\t\t\t\t\t\tnew PausedOperationContinueError(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\t\t\toperation: status,\n\t\t\t\t\t\t\t\t\tskip: false,\n\t\t\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath, args: commitArgs },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tex,\n\t\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\tawait this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\terrors: 'throw',\n\t\t\t\t\tconfigs: configs,\n\t\t\t\t\tenv: env,\n\t\t\t\t\t// A `--continue` that opens the commit-message editor blocks for as long as the user leaves\n\t\t\t\t\t// that tab open, which is unbounded — the default `advanced.git.timeout` would SIGTERM it\n\t\t\t\t\t// mid-operation. The start paths (merge/rebase/revert) opt out for the same reason.\n\t\t\t\t\ttimeout: 0,\n\t\t\t\t\t// The runner dedups in-flight commands by args only — it ignores per-call `configs`/`env`.\n\t\t\t\t\t// A headless continue (with `GIT_EDITOR`) and a plain `--continue` would therefore collapse\n\t\t\t\t\t// into one execution, so the plain one could silently run headless (auto-accepting a commit\n\t\t\t\t\t// message) or the headless one could ride a plain continue and open an editor that hangs the\n\t\t\t\t\t// loop. Tag the headless variant so it can't share a pending command with the plain one.\n\t\t\t\t\tcorrelationKey: options?.messageEditor ? 'paused-op-continue-headless' : undefined,\n\t\t\t\t},\n\t\t\t\t...args,\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tif (PausedOperationContinueError.is(ex)) throw ex;\n\n\t\t\tconst error = getGitCommandError(\n\t\t\t\t'paused-operation-continue',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew PausedOperationContinueError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\toperation: status,\n\t\t\t\t\t\t\tskip: options?.skip ?? false,\n\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tex,\n\t\t\t\t\t),\n\t\t\t);\n\n\t\t\t// An empty commit concludes a single-commit cherry-pick/revert outright, leaving its\n\t\t\t// `--continue` nothing to continue — the operation finished either way.\n\t\t\tif (!options?.allowEmpty || !PausedOperationContinueError.is(error, 'nothingToContinue')) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t} finally {\n\t\t\t// Notify unconditionally rather than only on success: a throwing `--continue` can still have\n\t\t\t// mutated the repo (committing the resolved step, then stopping on the NEXT step's conflict or\n\t\t\t// empty commit), and the error alone can't distinguish that from a no-op failure. Invalidating\n\t\t\t// after a genuine no-op only costs a re-read; not invalidating after a real advance leaves\n\t\t\t// consumers rendering a stale step.\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'status');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['head', 'heads', 'index']);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pausedOperations.js","names":[],"sources":["../../../../git-cli/src/providers/pausedOperations.ts"],"sourcesContent":["import { readdir } from 'fs';\nimport { readFile, stat } from 'fs/promises';\nimport * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { PausedOperationAbortError, PausedOperationContinueError } from '@gitlens/git/errors.js';\nimport type {\n\tGitCherryPickStatus,\n\tGitMergeStatus,\n\tGitPausedOperationStatus,\n\tGitRebaseStatus,\n\tGitRevertStatus,\n} from '@gitlens/git/models/pausedOperationStatus.js';\nimport type { GitBranchReference, GitTagReference } from '@gitlens/git/models/reference.js';\nimport type { GitDir } from '@gitlens/git/models/repository.js';\nimport type { GitPausedOperationsSubProvider } from '@gitlens/git/providers/pausedOperations.js';\nimport { createReference } from '@gitlens/git/utils/reference.utils.js';\nimport { CancellationError } from '@gitlens/utils/cancellation.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { joinPaths } from '@gitlens/utils/path.js';\nimport { getSettledValue } from '@gitlens/utils/promise.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { Git } from '../exec/git.js';\nimport { getGitCommandError } from '../exec/git.js';\n\nconst todoCommitRegex = /^(?:p(?:ick)?|revert)\\s+([a-f0-9]+)(?:\\s+(.+))?$/i;\n\ntype Operation = 'cherry-pick' | 'merge' | 'rebase-apply' | 'rebase-merge' | 'revert' | 'sequencer';\n\n// Note: 'sequencer' is checked after specific HEAD files since those take precedence\n// The sequencer directory is used for multi-commit cherry-picks/reverts\nconst orderedOperations: Operation[] = ['rebase-apply', 'rebase-merge', 'merge', 'cherry-pick', 'revert', 'sequencer'];\n\nexport class PausedOperationsGitSubProvider implements GitPausedOperationsSubProvider {\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@debug()\n\tgetPausedOperationStatus(\n\t\trepoPath: string,\n\t\toptions?: { force?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitPausedOperationStatus | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\t// Self-heal callers (WIP refresh) bypass the cache so a missed `'pausedOp'` FS-watcher\n\t\t// event (CLI-driven completion, torn-down secondary-worktree watcher) can't leave the\n\t\t// status stuck — the readdir-based detection is cheap enough to repeat on every tick.\n\t\tif (options?.force) {\n\t\t\tthis.cache.pausedOperationStatus.delete(repoPath);\n\t\t}\n\n\t\tconst status = this.cache.pausedOperationStatus.getOrCreate(repoPath, async _cancellable => {\n\t\t\tconst gitDir = await this.provider.config.getGitDir(repoPath);\n\n\t\t\tconst operations = await new Promise<Set<Operation>>((resolve, _) => {\n\t\t\t\treaddir(gitDir.uri.fsPath, { withFileTypes: true }, (err, entries) => {\n\t\t\t\t\tconst operations = new Set<Operation>();\n\t\t\t\t\tif (err != null) {\n\t\t\t\t\t\tresolve(operations);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (entries.length === 0) {\n\t\t\t\t\t\tresolve(operations);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet entry;\n\t\t\t\t\tfor (entry of entries) {\n\t\t\t\t\t\tif (entry.isFile()) {\n\t\t\t\t\t\t\tswitch (entry.name) {\n\t\t\t\t\t\t\t\tcase 'CHERRY_PICK_HEAD':\n\t\t\t\t\t\t\t\t\toperations.add('cherry-pick');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'MERGE_HEAD':\n\t\t\t\t\t\t\t\t\toperations.add('merge');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'REVERT_HEAD':\n\t\t\t\t\t\t\t\t\toperations.add('revert');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (entry.isDirectory()) {\n\t\t\t\t\t\t\tswitch (entry.name) {\n\t\t\t\t\t\t\t\tcase 'rebase-apply':\n\t\t\t\t\t\t\t\t\toperations.add('rebase-apply');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'rebase-merge':\n\t\t\t\t\t\t\t\t\toperations.add('rebase-merge');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'sequencer':\n\t\t\t\t\t\t\t\t\t// The sequencer directory is used for multi-commit cherry-picks/reverts\n\t\t\t\t\t\t\t\t\t// We'll determine the type by reading the todo file later\n\t\t\t\t\t\t\t\t\toperations.add('sequencer');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve(operations);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tif (!operations.size) return undefined;\n\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\tconst sortedOperations = [...operations].sort(\n\t\t\t\t(a, b) => orderedOperations.indexOf(a) - orderedOperations.indexOf(b),\n\t\t\t);\n\t\t\tscope?.info(`Detected paused operations: ${sortedOperations.join(', ')}`);\n\n\t\t\tconst operation = sortedOperations[0];\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'cherry-pick': {\n\t\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t'--verify',\n\t\t\t\t\t\t'CHERRY_PICK_HEAD',\n\t\t\t\t\t);\n\t\t\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cherryPickHead = result.stdout.trim();\n\t\t\t\t\tif (!cherryPickHead) {\n\t\t\t\t\t\tscope?.addExitInfo('No CHERRY_PICK_HEAD found');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [branchResult, mergeBaseResult, messageResult] = await Promise.allSettled([\n\t\t\t\t\t\tthis.provider.branches.getCurrentBranchReference(repoPath, cancellation),\n\t\t\t\t\t\tthis.provider.refs.getMergeBase(repoPath, 'CHERRY_PICK_HEAD', 'HEAD', undefined, cancellation),\n\t\t\t\t\t\tthis.getCommitMessage(repoPath, cherryPickHead, cancellation),\n\t\t\t\t\t]);\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst current = getSettledValue(branchResult)!;\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\t\t\t\t\t// Names the commit being applied, so consumers can say which one a skip would drop\n\t\t\t\t\tconst message = getSettledValue(messageResult);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'cherry-pick',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(cherryPickHead, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\tincoming: createReference(cherryPickHead, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t} satisfies GitCherryPickStatus;\n\t\t\t\t}\n\t\t\t\tcase 'merge': {\n\t\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t'--verify',\n\t\t\t\t\t\t'MERGE_HEAD',\n\t\t\t\t\t);\n\t\t\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst mergeHead = result.stdout.trim();\n\t\t\t\t\tif (!mergeHead) {\n\t\t\t\t\t\tscope?.addExitInfo('No MERGE_HEAD found');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [branchResult, mergeBaseResult, possibleSourceBranchesResult] = await Promise.allSettled([\n\t\t\t\t\t\tthis.provider.branches.getCurrentBranchReference(repoPath, cancellation),\n\t\t\t\t\t\tthis.provider.refs.getMergeBase(repoPath, 'MERGE_HEAD', 'HEAD', undefined, cancellation),\n\t\t\t\t\t\tthis.provider.branches.getBranchesWithCommits(\n\t\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\t\t['MERGE_HEAD'],\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t{ all: true, mode: 'pointsAt' },\n\t\t\t\t\t\t\tcancellation,\n\t\t\t\t\t\t),\n\t\t\t\t\t]);\n\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst current = getSettledValue(branchResult)!;\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\t\t\t\t\tconst possibleSourceBranches = getSettledValue(possibleSourceBranchesResult);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'merge',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(mergeHead, repoPath, { refType: 'revision' }),\n\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\tincoming:\n\t\t\t\t\t\t\tpossibleSourceBranches?.length === 1\n\t\t\t\t\t\t\t\t? createReference(possibleSourceBranches[0], repoPath, {\n\t\t\t\t\t\t\t\t\t\trefType: 'branch',\n\t\t\t\t\t\t\t\t\t\tname: possibleSourceBranches[0],\n\t\t\t\t\t\t\t\t\t\tremote: false,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: createReference(mergeHead, repoPath, { refType: 'revision' }),\n\t\t\t\t\t} satisfies GitMergeStatus;\n\t\t\t\t}\n\t\t\t\tcase 'revert': {\n\t\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t'--verify',\n\t\t\t\t\t\t'REVERT_HEAD',\n\t\t\t\t\t);\n\t\t\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) {\n\t\t\t\t\t\tthrow new CancellationError();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst revertHead = result.stdout.trim();\n\t\t\t\t\tif (!revertHead) {\n\t\t\t\t\t\tscope?.addExitInfo('No REVERT_HEAD found');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [branchResult, mergeBaseResult, messageResult] = await Promise.allSettled([\n\t\t\t\t\t\tthis.provider.branches.getCurrentBranchReference(repoPath, cancellation),\n\t\t\t\t\t\tthis.provider.refs.getMergeBase(repoPath, 'REVERT_HEAD', 'HEAD', undefined, cancellation),\n\t\t\t\t\t\tthis.getCommitMessage(repoPath, revertHead, cancellation),\n\t\t\t\t\t]);\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst current = getSettledValue(branchResult)!;\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\t\t\t\t\t// Names the commit being reverted, so consumers can say which one a skip would drop\n\t\t\t\t\tconst message = getSettledValue(messageResult);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'revert',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(revertHead, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\tincoming: createReference(revertHead, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t} satisfies GitRevertStatus;\n\t\t\t\t}\n\t\t\t\tcase 'rebase-apply':\n\t\t\t\tcase 'rebase-merge': {\n\t\t\t\t\tlet branch = await this.readDotGitFile(gitDir, [operation, 'head-name']);\n\t\t\t\t\tif (!branch) {\n\t\t\t\t\t\tscope?.addExitInfo(`No '${operation}/head-name' found`);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [\n\t\t\t\t\t\trebaseHeadResult,\n\t\t\t\t\t\torigHeadResult,\n\t\t\t\t\t\tontoResult,\n\t\t\t\t\t\tstepsNumberResult,\n\t\t\t\t\t\tstepsTotalResult,\n\t\t\t\t\t\tstepsMessageResult,\n\t\t\t\t\t\tisInteractiveResult,\n\t\t\t\t\t] = await Promise.allSettled([\n\t\t\t\t\t\tthis.git.run(\n\t\t\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t\t\t\t'rev-parse',\n\t\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t\t'--verify',\n\t\t\t\t\t\t\t'REBASE_HEAD',\n\t\t\t\t\t\t),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'orig-head']),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'onto']),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'msgnum'], { numeric: true }),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'end'], { numeric: true }),\n\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'message'], { throw: true }).catch(() =>\n\t\t\t\t\t\t\tthis.readDotGitFile(gitDir, [operation, 'message-squashed']),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tstat(joinPaths(gitDir.uri.fsPath, operation, 'interactive')).then(\n\t\t\t\t\t\t\t() => true,\n\t\t\t\t\t\t\t() => false,\n\t\t\t\t\t\t),\n\t\t\t\t\t]);\n\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst origHead = getSettledValue(origHeadResult);\n\t\t\t\t\tconst onto = getSettledValue(ontoResult);\n\t\t\t\t\tif (origHead == null || onto == null) {\n\t\t\t\t\t\tscope?.addExitInfo(`Neither '${operation}/orig-head' nor '${operation}/onto' found`);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst rebaseHead = getSettledValue(rebaseHeadResult)?.stdout.trim();\n\n\t\t\t\t\tif (branch.startsWith('refs/heads/')) {\n\t\t\t\t\t\tbranch = branch.substring(11).trim();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst [mergeBaseResult, branchTipsResult, tagTipsResult] = await Promise.allSettled([\n\t\t\t\t\t\trebaseHead\n\t\t\t\t\t\t\t? this.provider.refs.getMergeBase(repoPath, rebaseHead, 'HEAD', undefined, cancellation)\n\t\t\t\t\t\t\t: this.provider.refs.getMergeBase(repoPath, onto, origHead, undefined, cancellation),\n\t\t\t\t\t\tthis.provider.branches.getBranchesWithCommits(\n\t\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\t\t[onto],\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tall: true,\n\t\t\t\t\t\t\t\tmode: 'pointsAt',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcancellation,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tthis.provider.tags.getTagsWithCommit(repoPath, onto, { mode: 'pointsAt' }, cancellation),\n\t\t\t\t\t]);\n\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\t\t\t\t\tconst branchTips = getSettledValue(branchTipsResult);\n\t\t\t\t\tconst tagTips = getSettledValue(tagTipsResult);\n\n\t\t\t\t\tlet ontoRef: GitBranchReference | GitTagReference | undefined;\n\t\t\t\t\tif (branchTips != null) {\n\t\t\t\t\t\tfor (const ref of branchTips) {\n\t\t\t\t\t\t\tif (ref.startsWith('(no branch, rebasing')) continue;\n\n\t\t\t\t\t\t\tontoRef = createReference(ref, repoPath, {\n\t\t\t\t\t\t\t\trefType: 'branch',\n\t\t\t\t\t\t\t\tname: ref,\n\t\t\t\t\t\t\t\tremote: false,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (ontoRef == null && tagTips != null) {\n\t\t\t\t\t\tfor (const ref of tagTips) {\n\t\t\t\t\t\t\tif (ref.startsWith('(no branch, rebasing')) continue;\n\n\t\t\t\t\t\t\tontoRef = createReference(ref, repoPath, {\n\t\t\t\t\t\t\t\trefType: 'tag',\n\t\t\t\t\t\t\t\tname: ref,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst stepsNumber = getSettledValue(stepsNumberResult) ?? 0;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'rebase',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(rebaseHead ?? origHead, repoPath, { refType: 'revision' }),\n\t\t\t\t\t\tonto: createReference(onto, repoPath, { refType: 'revision' }),\n\t\t\t\t\t\tsource: createReference(origHead, repoPath, { refType: 'revision' }),\n\t\t\t\t\t\tcurrent: ontoRef,\n\t\t\t\t\t\tincoming: createReference(branch, repoPath, {\n\t\t\t\t\t\t\trefType: 'branch',\n\t\t\t\t\t\t\tname: branch,\n\t\t\t\t\t\t\tremote: false,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tsteps: {\n\t\t\t\t\t\t\tcurrent: {\n\t\t\t\t\t\t\t\tnumber: stepsNumber,\n\t\t\t\t\t\t\t\tcommit: rebaseHead\n\t\t\t\t\t\t\t\t\t? createReference(rebaseHead, repoPath, {\n\t\t\t\t\t\t\t\t\t\t\trefType: 'revision',\n\t\t\t\t\t\t\t\t\t\t\tmessage: getSettledValue(stepsMessageResult),\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttotal: getSettledValue(stepsTotalResult) ?? 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\thasStarted: stepsNumber > 0,\n\t\t\t\t\t\t// REBASE_HEAD only exists when git is paused and waiting for user action\n\t\t\t\t\t\tisPaused: stepsNumber > 0 && rebaseHead != null,\n\t\t\t\t\t\t// 'interactive' file exists for `git rebase -i`, absent for `git pull --rebase`\n\t\t\t\t\t\tisInteractive: getSettledValue(isInteractiveResult) ?? false,\n\t\t\t\t\t} satisfies GitRebaseStatus;\n\t\t\t\t}\n\t\t\t\tcase 'sequencer': {\n\t\t\t\t\t// Used for multi-commit cherry-picks/reverts when CHERRY_PICK_HEAD/REVERT_HEAD don't exist\n\t\t\t\t\tconst todoContent = await this.readDotGitFile(gitDir, ['sequencer', 'todo']);\n\t\t\t\t\tif (!todoContent) {\n\t\t\t\t\t\tscope?.addExitInfo('No sequencer/todo file found');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Get the first line and determine if it's a cherry-pick or revert\n\t\t\t\t\tconst firstLine = todoContent.split('\\n')[0]?.trim();\n\t\t\t\t\tif (!firstLine) {\n\t\t\t\t\t\tscope?.addExitInfo('Empty sequencer/todo file');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if it's a pick (cherry-pick) or revert command\n\t\t\t\t\t// Format: \"pick <sha> <message>\" or \"p <sha> <message>\" or \"revert <sha> <message>\"\n\t\t\t\t\tconst isCherryPick = /^p(?:ick)?\\s/.test(firstLine);\n\t\t\t\t\tconst isRevert = /^revert\\s/.test(firstLine);\n\n\t\t\t\t\tif (!isCherryPick && !isRevert) {\n\t\t\t\t\t\tscope?.addExitInfo(`Unknown sequencer command: ${firstLine}`);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Parse the commit sha being applied from the todo file\n\t\t\t\t\tconst match = firstLine.match(todoCommitRegex);\n\t\t\t\t\tconst currentCommitSha = match?.[1];\n\t\t\t\t\tif (!currentCommitSha) {\n\t\t\t\t\t\tscope?.addExitInfo('Could not parse commit sha from sequencer/todo');\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\t// The todo line carries only the commit's SUBJECT (the other producers carry the full\n\t\t\t\t\t// message) — good enough to name the commit a skip would drop, without another git call\n\t\t\t\t\tconst message = match?.[2]?.trim() || undefined;\n\n\t\t\t\t\tconst [branchResult, mergeBaseResult] = await Promise.allSettled([\n\t\t\t\t\t\tthis.provider.branches.getCurrentBranchReference(repoPath, cancellation),\n\t\t\t\t\t\tthis.provider.refs.getMergeBase(repoPath, currentCommitSha, 'HEAD', undefined, cancellation),\n\t\t\t\t\t]);\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\tconst current = getSettledValue(branchResult)!;\n\t\t\t\t\tconst mergeBase = getSettledValue(mergeBaseResult);\n\n\t\t\t\t\tif (isCherryPick) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: 'cherry-pick',\n\t\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\t\tHEAD: createReference(currentCommitSha, repoPath, {\n\t\t\t\t\t\t\t\trefType: 'revision',\n\t\t\t\t\t\t\t\tmessage: message,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\t\tincoming: createReference(currentCommitSha, repoPath, {\n\t\t\t\t\t\t\t\trefType: 'revision',\n\t\t\t\t\t\t\t\tmessage: message,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t} satisfies GitCherryPickStatus;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'revert',\n\t\t\t\t\t\trepoPath: repoPath,\n\t\t\t\t\t\tmergeBase: mergeBase,\n\t\t\t\t\t\tHEAD: createReference(currentCommitSha, repoPath, { refType: 'revision', message: message }),\n\t\t\t\t\t\tcurrent: current,\n\t\t\t\t\t\tincoming: createReference(currentCommitSha, repoPath, {\n\t\t\t\t\t\t\trefType: 'revision',\n\t\t\t\t\t\t\tmessage: message,\n\t\t\t\t\t\t}),\n\t\t\t\t\t} satisfies GitRevertStatus;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn status;\n\t}\n\n\t/** Memoized per repo by sha — forced status re-reads on FS noise (every file save while resolving\n\t * conflicts) would otherwise re-spawn `git log` for an unchanging commit. */\n\tprivate readonly _commitMessageCache = new Map<string, { sha: string; message: string | undefined }>();\n\n\tprivate async getCommitMessage(\n\t\trepoPath: string,\n\t\tsha: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tconst cached = this._commitMessageCache.get(repoPath);\n\t\tif (cached?.sha === sha) return cached.message;\n\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t'log',\n\t\t\t'-1',\n\t\t\t'--format=%B',\n\t\t\tsha,\n\t\t);\n\t\tconst message = result.stdout.trim() || undefined;\n\t\t// Don't cache a miss — a transient failure would otherwise stick for the operation's lifetime\n\t\tif (message != null) {\n\t\t\tthis._commitMessageCache.set(repoPath, { sha: sha, message: message });\n\t\t}\n\t\treturn message;\n\t}\n\n\tprivate async readDotGitFile(\n\t\tgitDir: GitDir,\n\t\tpathParts: string[],\n\t\toptions?: { numeric?: false; throw?: boolean; trim?: boolean },\n\t): Promise<string | undefined>;\n\tprivate async readDotGitFile(\n\t\tgitDir: GitDir,\n\t\tpathParts: string[],\n\t\toptions?: { numeric: true; throw?: boolean; trim?: boolean },\n\t): Promise<number | undefined>;\n\tprivate async readDotGitFile(\n\t\tgitDir: GitDir,\n\t\tpathParts: string[],\n\t\toptions?: { numeric?: boolean; throw?: boolean; trim?: boolean },\n\t): Promise<string | number | undefined> {\n\t\ttry {\n\t\t\tconst filePath = joinPaths(gitDir.uri.fsPath, ...pathParts);\n\t\t\tconst bytes = await readFile(filePath);\n\t\t\tlet contents = new TextDecoder('utf8').decode(bytes);\n\t\t\tcontents = (options?.trim ?? true) ? contents.trim() : contents;\n\n\t\t\tif (options?.numeric) {\n\t\t\t\tconst number = Number.parseInt(contents, 10);\n\t\t\t\treturn isNaN(number) ? undefined : number;\n\t\t\t}\n\n\t\t\treturn contents;\n\t\t} catch (ex) {\n\t\t\tif (options?.throw) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@gate((rp, o) => `${rp ?? ''}:${o?.quit ?? false}`)\n\t@debug()\n\tasync abortPausedOperation(repoPath: string, options?: { quit?: boolean }): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst status = await this.getPausedOperationStatus(repoPath);\n\t\tif (status == null) return;\n\n\t\tconst args = [status.type, options?.quit ? '--quit' : '--abort'];\n\n\t\ttry {\n\t\t\t// Unbounded like the operations it undoes — an abort of a large rebase can outrun the default\n\t\t\t// command timeout, and being SIGTERM'd partway through would leave the repo mid-abort.\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw', timeout: 0 }, ...args);\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'status');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['head', 'heads', 'index']);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'paused-operation-abort',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew PausedOperationAbortError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\toperation: status,\n\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tex,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\t@debug()\n\tasync continuePausedOperation(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tallowEmpty?: boolean;\n\t\t\tskip?: boolean;\n\t\t\tmessageEditor?: string;\n\t\t\teditorEnv?: Record<string, string>;\n\t\t},\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst status = await this.getPausedOperationStatus(repoPath);\n\t\tif (status == null) return;\n\n\t\tif (status.type === 'merge' && options?.skip) {\n\t\t\tthrow new Error(l10n.t('Skipping a merge is not supported'));\n\t\t}\n\n\t\tconst args = [status.type, options?.skip ? '--skip' : '--continue'];\n\n\t\t// Continuing after a conflicted step can open the commit-message editor (merge-backend rebases,\n\t\t// cherry-picks, and reverts). `GIT_EDITOR` is what git honors for that step, so set it on the\n\t\t// environment; also set `core.editor` config as a fallback.\n\t\tconst configs: string[] = [];\n\t\tlet env: Record<string, string | undefined> | undefined;\n\t\tif (options?.messageEditor) {\n\t\t\tconfigs.push('-c', `core.editor=${options.messageEditor}`);\n\t\t\tenv = { ...options.editorEnv, GIT_EDITOR: options.messageEditor };\n\t\t}\n\n\t\ttry {\n\t\t\tif (options?.allowEmpty) {\n\t\t\t\tconst commitArgs = ['commit', '--allow-empty', '--no-edit'];\n\t\t\t\ttry {\n\t\t\t\t\t// Git won't record the empty commit on its own; making it explicitly (`--no-edit` reuses the\n\t\t\t\t\t// message git already prepared) is what lets the operation move past it.\n\t\t\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw' }, ...commitArgs);\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tscope?.error(ex);\n\t\t\t\t\t// Same reason taxonomy, but attributed to the commit that actually failed\n\t\t\t\t\tthrow getGitCommandError(\n\t\t\t\t\t\t'paused-operation-continue',\n\t\t\t\t\t\tex,\n\t\t\t\t\t\treason =>\n\t\t\t\t\t\t\tnew PausedOperationContinueError(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\t\t\toperation: status,\n\t\t\t\t\t\t\t\t\tskip: false,\n\t\t\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath, args: commitArgs },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tex,\n\t\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\tawait this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\terrors: 'throw',\n\t\t\t\t\tconfigs: configs,\n\t\t\t\t\tenv: env,\n\t\t\t\t\t// A `--continue` that opens the commit-message editor blocks for as long as the user leaves\n\t\t\t\t\t// that tab open, which is unbounded — the default `advanced.git.timeout` would SIGTERM it\n\t\t\t\t\t// mid-operation. The start paths (merge/rebase/revert) opt out for the same reason.\n\t\t\t\t\ttimeout: 0,\n\t\t\t\t\t// The runner dedups in-flight commands by args only — it ignores per-call `configs`/`env`.\n\t\t\t\t\t// A headless continue (with `GIT_EDITOR`) and a plain `--continue` would therefore collapse\n\t\t\t\t\t// into one execution, so the plain one could silently run headless (auto-accepting a commit\n\t\t\t\t\t// message) or the headless one could ride a plain continue and open an editor that hangs the\n\t\t\t\t\t// loop. Tag the headless variant so it can't share a pending command with the plain one.\n\t\t\t\t\tcorrelationKey: options?.messageEditor ? 'paused-op-continue-headless' : undefined,\n\t\t\t\t},\n\t\t\t\t...args,\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tif (PausedOperationContinueError.is(ex)) throw ex;\n\n\t\t\tconst error = getGitCommandError(\n\t\t\t\t'paused-operation-continue',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew PausedOperationContinueError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\toperation: status,\n\t\t\t\t\t\t\tskip: options?.skip ?? false,\n\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tex,\n\t\t\t\t\t),\n\t\t\t);\n\n\t\t\t// An empty commit concludes a single-commit cherry-pick/revert outright, leaving its\n\t\t\t// `--continue` nothing to continue — the operation finished either way.\n\t\t\tif (!options?.allowEmpty || !PausedOperationContinueError.is(error, 'nothingToContinue')) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t} finally {\n\t\t\t// Notify unconditionally rather than only on success: a throwing `--continue` can still have\n\t\t\t// mutated the repo (committing the resolved step, then stopping on the NEXT step's conflict or\n\t\t\t// empty commit), and the error alone can't distinguish that from a no-op failure. Invalidating\n\t\t\t// after a genuine no-op only costs a re-read; not invalidating after a real advance leaves\n\t\t\t// consumers rendering a stale step.\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'status');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['head', 'heads', 'index']);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
@@ -2,13 +2,13 @@ import { CancellationError, isCancellationError } from "../../utils/cancellation
2
2
  import { iterateAsyncByDelimiter } from "../../utils/string.js";
3
3
  import { getScopedLogger } from "../../utils/logger.scoped.js";
4
4
  import { debug, trace } from "../../utils/decorators/log.js";
5
+ import { createDisposable } from "../../utils/disposable.js";
5
6
  import { toFsPath } from "../../utils/uri.js";
6
7
  import "../../git/models/revision.js";
7
8
  import { isSha, isShaWithOptionalRevisionSuffix, isUncommitted } from "../../git/utils/revision.utils.js";
8
9
  import { createReference } from "../../git/utils/reference.utils.js";
9
10
  import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
10
11
  import { ReferenceUpdateError } from "../../git/errors.js";
11
- import { createDisposable } from "../../utils/disposable.js";
12
12
  import { getGitCommandError, gitConfigsBranch, gitConfigsLog } from "../exec/git.js";
13
13
  import { maybeStopWatch } from "../../utils/stopwatch.js";
14
14
  import _usingCtx from "../../_virtual/@oxc-project+runtime/helpers/esm/usingCtx.js";
@@ -2,14 +2,14 @@ import { chunk } from "../../utils/iterable.js";
2
2
  import { countStringLength } from "../../utils/array.js";
3
3
  import { getScopedLogger } from "../../utils/logger.scoped.js";
4
4
  import { debug } from "../../utils/decorators/log.js";
5
+ import { mixinAsyncDisposable } from "../../utils/disposable.js";
5
6
  import { toFsPath } from "../../utils/uri.js";
6
7
  import { joinPaths } from "../../utils/path.js";
7
8
  import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
8
- import { mixinAsyncDisposable } from "../../utils/disposable.js";
9
9
  import { maxGitCliLength } from "../exec/git.js";
10
10
  import * as l10n from "@vscode/l10n";
11
- import { tmpdir } from "os";
12
11
  import { promises } from "fs";
12
+ import { tmpdir } from "os";
13
13
  //#region ../git-cli/src/providers/staging.ts
14
14
  var StagingGitSubProvider = class {
15
15
  context;
@@ -3,11 +3,11 @@ import { iterateByDelimiter } from "../../utils/string.js";
3
3
  import { getScopedLogger } from "../../utils/logger.scoped.js";
4
4
  import { getSettledValue } from "../../utils/promise.js";
5
5
  import { debug } from "../../utils/decorators/log.js";
6
+ import { createDisposable } from "../../utils/disposable.js";
6
7
  import { toFsPath } from "../../utils/uri.js";
7
8
  import { normalizePath, splitPath, stripFolderGlob } from "../../utils/path.js";
8
9
  import { PromiseMap } from "../../utils/promiseCache.js";
9
10
  import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
10
- import { createDisposable } from "../../utils/disposable.js";
11
11
  import { GitErrors, defaultExceptionHandler, gitConfigsStatus } from "../exec/git.js";
12
12
  import { GitFileWorkingTreeStatus } from "../../git/models/fileStatus.js";
13
13
  import _usingCtx from "../../_virtual/@oxc-project+runtime/helpers/esm/usingCtx.js";
@@ -33,6 +33,7 @@ function createCliGitService(options) {
33
33
  service.register(provider, () => true);
34
34
  service.watchService?.onDidChangeWorkingTree((repoPath) => provider.cache.onWorkingTreeChanged(repoPath));
35
35
  service.watchService?.onDidChangeRepository((e) => provider.cache.onRepositoryChanged(e.repoPath, e.changes));
36
+ service.watchService?.onDidChangeFetchHead((repoPath) => provider.cache.onRepositoryChanged(repoPath, ["lastFetched"]));
36
37
  return service;
37
38
  }
38
39
  //#endregion