@gitkraken/core-gitlens 0.25.0 → 0.26.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 (48) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/dist/git/providers/operations.d.ts +15 -0
  3. package/dist/git/watching/worktreeSummary.d.ts +15 -3
  4. package/dist/git/watching/worktreeSummary.js +179 -31
  5. package/dist/git/watching/worktreeSummary.js.map +1 -1
  6. package/dist/git-cli/cliGitProvider.d.ts +16 -0
  7. package/dist/git-cli/cliGitProvider.js +31 -6
  8. package/dist/git-cli/cliGitProvider.js.map +1 -1
  9. package/dist/git-cli/exec/git.d.ts +2 -0
  10. package/dist/git-cli/exec/git.js +4 -0
  11. package/dist/git-cli/exec/git.js.map +1 -1
  12. package/dist/git-cli/exec/gitDirResolver.d.ts +26 -0
  13. package/dist/git-cli/exec/gitDirResolver.js +181 -0
  14. package/dist/git-cli/exec/gitDirResolver.js.map +1 -0
  15. package/dist/git-cli/exec/headState.js +3 -3
  16. package/dist/git-cli/exec/headState.js.map +1 -1
  17. package/dist/git-cli/exec/indexRefresh.d.ts +78 -0
  18. package/dist/git-cli/exec/indexRefresh.js +159 -0
  19. package/dist/git-cli/exec/indexRefresh.js.map +1 -0
  20. package/dist/git-cli/providers/config.d.ts +2 -0
  21. package/dist/git-cli/providers/config.js +22 -3
  22. package/dist/git-cli/providers/config.js.map +1 -1
  23. package/dist/git-cli/providers/maintenance.js +1 -1
  24. package/dist/git-cli/providers/operations.d.ts +4 -1
  25. package/dist/git-cli/providers/operations.js +33 -25
  26. package/dist/git-cli/providers/operations.js.map +1 -1
  27. package/dist/git-cli/providers/pausedOperations.d.ts +3 -1
  28. package/dist/git-cli/providers/pausedOperations.js +10 -7
  29. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  30. package/dist/git-cli/providers/refs.js +25 -1
  31. package/dist/git-cli/providers/refs.js.map +1 -1
  32. package/dist/git-cli/providers/staging.js +1 -1
  33. package/dist/git-cli/providers/stash.d.ts +3 -1
  34. package/dist/git-cli/providers/stash.js +8 -5
  35. package/dist/git-cli/providers/stash.js.map +1 -1
  36. package/dist/git-cli/providers/worktrees.d.ts +6 -1
  37. package/dist/git-cli/providers/worktrees.js +6 -2
  38. package/dist/git-cli/providers/worktrees.js.map +1 -1
  39. package/dist/git-cli/service.d.ts +2 -0
  40. package/dist/git-cli/service.js +2 -1
  41. package/dist/git-cli/service.js.map +1 -1
  42. package/dist/ipc/discovery.js +1 -1
  43. package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
  44. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
  45. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -1
  46. package/dist/plus/integrations/providers/azure/azure.js +1 -1
  47. package/dist/utils/env/node/exec.js +2 -2
  48. package/package.json +1 -1
@@ -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/**\n\t * Whether git's dir holds a sentinel of an in-progress operation (presence only — no content is parsed,\n\t * so it also answers `true` for states `getPausedOperationStatus` can't describe, e.g. a stopped `git am`).\n\t * Rejects when git's dir can't be resolved or read\n\t */\n\t@debug({ quiet: true })\n\tasync hasPausedOperation(repoPath: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\tconst gitDir = await this.provider.config.getGitDir(repoPath);\n\t\tconst operations = await this.scanGitDir(gitDir);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tfor (const operation of operations) {\n\t\t\t// A bare leftover `sequencer` dir isn't in progress; git itself checks for `sequencer/todo`\n\t\t\tif (operation !== 'sequencer') return true;\n\t\t}\n\t\tif (!operations.has('sequencer')) return false;\n\n\t\ttry {\n\t\t\tawait stat(joinPaths(gitDir.uri.fsPath, 'sequencer', 'todo'));\n\t\t\treturn true;\n\t\t} catch (ex) {\n\t\t\tif ((ex as NodeJS.ErrnoException).code === 'ENOENT') return false;\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Lists the operation sentinels in git's dir; rejects if the dir can't be read */\n\tprivate scanGitDir(gitDir: GitDir): Promise<Set<Operation>> {\n\t\treturn new Promise<Set<Operation>>((resolve, reject) => {\n\t\t\treaddir(gitDir.uri.fsPath, { withFileTypes: true }, (err, entries) => {\n\t\t\t\tif (err != null) {\n\t\t\t\t\treject(err);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst operations = new Set<Operation>();\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tif (entry.isFile()) {\n\t\t\t\t\t\tswitch (entry.name) {\n\t\t\t\t\t\t\tcase 'CHERRY_PICK_HEAD':\n\t\t\t\t\t\t\t\toperations.add('cherry-pick');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'MERGE_HEAD':\n\t\t\t\t\t\t\t\toperations.add('merge');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'REVERT_HEAD':\n\t\t\t\t\t\t\t\toperations.add('revert');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (entry.isDirectory()) {\n\t\t\t\t\t\tswitch (entry.name) {\n\t\t\t\t\t\t\tcase 'rebase-apply':\n\t\t\t\t\t\t\t\toperations.add('rebase-apply');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'rebase-merge':\n\t\t\t\t\t\t\t\toperations.add('rebase-merge');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'sequencer':\n\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// We'll determine the type by reading the todo file later\n\t\t\t\t\t\t\t\toperations.add('sequencer');\n\t\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}\n\n\t\t\t\tresolve(operations);\n\t\t\t});\n\t\t});\n\t}\n\n\t@debug({ quiet: true })\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\t// An unreadable git dir reads as \"nothing paused\" here — the status is best-effort and self-heals\n\t\t\tconst operations = await this.scanGitDir(gitDir).catch(() => new Set<Operation>());\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} 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} finally {\n\t\t\t// An abort that fails or is cancelled partway can still have moved HEAD or reset the working tree\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\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":";;;;;;;;;;;;;;AA2BA,MAAM,kBAAkB;AAMxB,MAAM,oBAAiC;CAAC;CAAgB;CAAgB;CAAS;CAAe;CAAU;AAAW;AAErH,IAAa,iCAAb,MAAsF;CAEnE;CACA;CACA;CACA;CAJlB,YACC,SACA,KACA,OACA,UACC;EAJgB,KAAA,UAAA;EACA,KAAA,MAAA;EACA,KAAA,QAAA;EACA,KAAA,WAAA;CACf;;;;;;CAOH,MACM,mBAAmB,UAAkB,cAA8C;EACxF,MAAM,SAAS,MAAM,KAAK,SAAS,OAAO,UAAU,QAAQ;EAC5D,MAAM,aAAa,MAAM,KAAK,WAAW,MAAM;EAC/C,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;EAEvD,KAAK,MAAM,aAAa,YAEvB,IAAI,cAAc,aAAa,OAAO;EAEvC,IAAI,CAAC,WAAW,IAAI,WAAW,GAAG,OAAO;EAEzC,IAAI;GACH,MAAM,KAAK,UAAU,OAAO,IAAI,QAAQ,aAAa,MAAM,CAAC;GAC5D,OAAO;EACR,SAAS,IAAI;GACZ,IAAK,GAA6B,SAAS,UAAU,OAAO;GAC5D,MAAM;EACP;CACD;;CAGA,WAAmB,QAAyC;EAC3D,OAAO,IAAI,SAAyB,SAAS,WAAW;GACvD,QAAQ,OAAO,IAAI,QAAQ,EAAE,eAAe,KAAK,IAAI,KAAK,YAAY;IACrE,IAAI,OAAO,MAAM;KAChB,OAAO,GAAG;KACV;IACD;IAEA,MAAM,6BAAa,IAAI,IAAe;IACtC,KAAK,MAAM,SAAS,SACnB,IAAI,MAAM,OAAO,GAChB,QAAQ,MAAM,MAAd;KACC,KAAK;MACJ,WAAW,IAAI,aAAa;MAC5B;KACD,KAAK;MACJ,WAAW,IAAI,OAAO;MACtB;KACD,KAAK,eACJ,WAAW,IAAI,QAAQ;IAEzB;SACM,IAAI,MAAM,YAAY,GAC5B,QAAQ,MAAM,MAAd;KACC,KAAK;MACJ,WAAW,IAAI,cAAc;MAC7B;KACD,KAAK;MACJ,WAAW,IAAI,cAAc;MAC7B;KACD,KAAK,aAGJ,WAAW,IAAI,WAAW;IAE5B;IAIF,QAAQ,UAAU;GACnB,CAAC;EACF,CAAC;CACF;CAEA,yBAEC,UACA,SACA,cACgD;EAChD,MAAM,QAAQ,gBAAgB;EAK9B,IAAI,SAAS,OACZ,KAAK,MAAM,sBAAsB,OAAO,QAAQ;EAyWjD,OAtWe,KAAK,MAAM,sBAAsB,YAAY,UAAU,OAAM,iBAAgB;GAC3F,MAAM,SAAS,MAAM,KAAK,SAAS,OAAO,UAAU,QAAQ;GAG5D,MAAM,aAAa,MAAM,KAAK,WAAW,MAAM,CAAC,CAAC,4BAAY,IAAI,IAAe,CAAC;GAEjF,IAAI,CAAC,WAAW,MAAM,OAAO,KAAA;GAC7B,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;GAEvD,MAAM,mBAAmB,CAAC,GAAG,UAAU,CAAC,CAAC,MACvC,GAAG,MAAM,kBAAkB,QAAQ,CAAC,IAAI,kBAAkB,QAAQ,CAAC,CACrE;GACA,OAAO,KAAK,+BAA+B,iBAAiB,KAAK,IAAI,GAAG;GAExE,MAAM,YAAY,iBAAiB;GACnC,QAAQ,WAAR;IACC,KAAK,eAAe;KACnB,MAAM,SAAS,MAAM,KAAK,IAAI,IAC7B;MAAE,KAAK;MAAwB;MAAc,QAAQ;KAAS,GAC9D,aACA,WACA,YACA,kBACD;KACA,IAAI,OAAO,WAAW,WAAW,eAAe,cAAc,SAC7D,MAAM,IAAI,kBAAkB;KAG7B,MAAM,iBAAiB,OAAO,OAAO,KAAK;KAC1C,IAAI,CAAC,gBAAgB;MACpB,OAAO,YAAY,2BAA2B;MAC9C;KACD;KAEA,MAAM,CAAC,cAAc,iBAAiB,iBAAiB,MAAM,QAAQ,WAAW;MAC/E,KAAK,SAAS,SAAS,0BAA0B,UAAU,YAAY;MACvE,KAAK,SAAS,KAAK,aAAa,UAAU,oBAAoB,QAAQ,KAAA,GAAW,YAAY;MAC7F,KAAK,iBAAiB,UAAU,gBAAgB,YAAY;KAC7D,CAAC;KACD,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;KAEvD,MAAM,UAAU,gBAAgB,YAAY;KAC5C,MAAM,YAAY,gBAAgB,eAAe;KAEjD,MAAM,UAAU,gBAAgB,aAAa;KAE7C,OAAO;MACN,MAAM;MACI;MACC;MACX,MAAM,gBAAgB,gBAAgB,UAAU;OAAE,SAAS;OAAqB;MAAQ,CAAC;MAChF;MACT,UAAU,gBAAgB,gBAAgB,UAAU;OAAE,SAAS;OAAqB;MAAQ,CAAC;KAC9F;IACD;IACA,KAAK,SAAS;KACb,MAAM,SAAS,MAAM,KAAK,IAAI,IAC7B;MAAE,KAAK;MAAwB;MAAc,QAAQ;KAAS,GAC9D,aACA,WACA,YACA,YACD;KACA,IAAI,OAAO,WAAW,WAAW,eAAe,cAAc,SAC7D,MAAM,IAAI,kBAAkB;KAG7B,MAAM,YAAY,OAAO,OAAO,KAAK;KACrC,IAAI,CAAC,WAAW;MACf,OAAO,YAAY,qBAAqB;MACxC;KACD;KAEA,MAAM,CAAC,cAAc,iBAAiB,gCAAgC,MAAM,QAAQ,WAAW;MAC9F,KAAK,SAAS,SAAS,0BAA0B,UAAU,YAAY;MACvE,KAAK,SAAS,KAAK,aAAa,UAAU,cAAc,QAAQ,KAAA,GAAW,YAAY;MACvF,KAAK,SAAS,SAAS,uBACtB,UACA,CAAC,YAAY,GACb,KAAA,GACA;OAAE,KAAK;OAAM,MAAM;MAAW,GAC9B,YACD;KACD,CAAC;KAED,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;KAEvD,MAAM,UAAU,gBAAgB,YAAY;KAC5C,MAAM,YAAY,gBAAgB,eAAe;KACjD,MAAM,yBAAyB,gBAAgB,4BAA4B;KAE3E,OAAO;MACN,MAAM;MACI;MACC;MACX,MAAM,gBAAgB,WAAW,UAAU,EAAE,SAAS,WAAW,CAAC;MACzD;MACT,UACC,wBAAwB,WAAW,IAChC,gBAAgB,uBAAuB,IAAI,UAAU;OACrD,SAAS;OACT,MAAM,uBAAuB;OAC7B,QAAQ;MACT,CAAC,IACA,gBAAgB,WAAW,UAAU,EAAE,SAAS,WAAW,CAAC;KACjE;IACD;IACA,KAAK,UAAU;KACd,MAAM,SAAS,MAAM,KAAK,IAAI,IAC7B;MAAE,KAAK;MAAwB;MAAc,QAAQ;KAAS,GAC9D,aACA,WACA,YACA,aACD;KACA,IAAI,OAAO,WAAW,WAAW,eAAe,cAAc,SAC7D,MAAM,IAAI,kBAAkB;KAG7B,MAAM,aAAa,OAAO,OAAO,KAAK;KACtC,IAAI,CAAC,YAAY;MAChB,OAAO,YAAY,sBAAsB;MACzC;KACD;KAEA,MAAM,CAAC,cAAc,iBAAiB,iBAAiB,MAAM,QAAQ,WAAW;MAC/E,KAAK,SAAS,SAAS,0BAA0B,UAAU,YAAY;MACvE,KAAK,SAAS,KAAK,aAAa,UAAU,eAAe,QAAQ,KAAA,GAAW,YAAY;MACxF,KAAK,iBAAiB,UAAU,YAAY,YAAY;KACzD,CAAC;KACD,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;KAEvD,MAAM,UAAU,gBAAgB,YAAY;KAC5C,MAAM,YAAY,gBAAgB,eAAe;KAEjD,MAAM,UAAU,gBAAgB,aAAa;KAE7C,OAAO;MACN,MAAM;MACI;MACC;MACX,MAAM,gBAAgB,YAAY,UAAU;OAAE,SAAS;OAAqB;MAAQ,CAAC;MAC5E;MACT,UAAU,gBAAgB,YAAY,UAAU;OAAE,SAAS;OAAqB;MAAQ,CAAC;KAC1F;IACD;IACA,KAAK;IACL,KAAK,gBAAgB;KACpB,IAAI,SAAS,MAAM,KAAK,eAAe,QAAQ,CAAC,WAAW,WAAW,CAAC;KACvE,IAAI,CAAC,QAAQ;MACZ,OAAO,YAAY,OAAO,UAAU,kBAAkB;MACtD;KACD;KAEA,MAAM,CACL,kBACA,gBACA,YACA,mBACA,kBACA,oBACA,uBACG,MAAM,QAAQ,WAAW;MAC5B,KAAK,IAAI,IACR;OAAE,KAAK;OAAwB;OAAc,QAAQ;MAAS,GAC9D,aACA,WACA,YACA,aACD;MACA,KAAK,eAAe,QAAQ,CAAC,WAAW,WAAW,CAAC;MACpD,KAAK,eAAe,QAAQ,CAAC,WAAW,MAAM,CAAC;MAC/C,KAAK,eAAe,QAAQ,CAAC,WAAW,QAAQ,GAAG,EAAE,SAAS,KAAK,CAAC;MACpE,KAAK,eAAe,QAAQ,CAAC,WAAW,KAAK,GAAG,EAAE,SAAS,KAAK,CAAC;MACjE,KAAK,eAAe,QAAQ,CAAC,WAAW,SAAS,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,YACpE,KAAK,eAAe,QAAQ,CAAC,WAAW,kBAAkB,CAAC,CAC5D;MACA,KAAK,UAAU,OAAO,IAAI,QAAQ,WAAW,aAAa,CAAC,CAAC,CAAC,WACtD,YACA,KACP;KACD,CAAC;KAED,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;KAEvD,MAAM,WAAW,gBAAgB,cAAc;KAC/C,MAAM,OAAO,gBAAgB,UAAU;KACvC,IAAI,YAAY,QAAQ,QAAQ,MAAM;MACrC,OAAO,YAAY,YAAY,UAAU,mBAAmB,UAAU,aAAa;MACnF;KACD;KAEA,MAAM,aAAa,gBAAgB,gBAAgB,CAAC,EAAE,OAAO,KAAK;KAElE,IAAI,OAAO,WAAW,aAAa,GAClC,SAAS,OAAO,UAAU,EAAE,CAAC,CAAC,KAAK;KAGpC,MAAM,CAAC,iBAAiB,kBAAkB,iBAAiB,MAAM,QAAQ,WAAW;MACnF,aACG,KAAK,SAAS,KAAK,aAAa,UAAU,YAAY,QAAQ,KAAA,GAAW,YAAY,IACrF,KAAK,SAAS,KAAK,aAAa,UAAU,MAAM,UAAU,KAAA,GAAW,YAAY;MACpF,KAAK,SAAS,SAAS,uBACtB,UACA,CAAC,IAAI,GACL,KAAA,GACA;OACC,KAAK;OACL,MAAM;MACP,GACA,YACD;MACA,KAAK,SAAS,KAAK,kBAAkB,UAAU,MAAM,EAAE,MAAM,WAAW,GAAG,YAAY;KACxF,CAAC;KAED,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;KAEvD,MAAM,YAAY,gBAAgB,eAAe;KACjD,MAAM,aAAa,gBAAgB,gBAAgB;KACnD,MAAM,UAAU,gBAAgB,aAAa;KAE7C,IAAI;KACJ,IAAI,cAAc,MACjB,KAAK,MAAM,OAAO,YAAY;MAC7B,IAAI,IAAI,WAAW,sBAAsB,GAAG;MAE5C,UAAU,gBAAgB,KAAK,UAAU;OACxC,SAAS;OACT,MAAM;OACN,QAAQ;MACT,CAAC;MACD;KACD;KAED,IAAI,WAAW,QAAQ,WAAW,MACjC,KAAK,MAAM,OAAO,SAAS;MAC1B,IAAI,IAAI,WAAW,sBAAsB,GAAG;MAE5C,UAAU,gBAAgB,KAAK,UAAU;OACxC,SAAS;OACT,MAAM;MACP,CAAC;MACD;KACD;KAGD,MAAM,cAAc,gBAAgB,iBAAiB,KAAK;KAE1D,OAAO;MACN,MAAM;MACI;MACC;MACX,MAAM,gBAAgB,cAAc,UAAU,UAAU,EAAE,SAAS,WAAW,CAAC;MAC/E,MAAM,gBAAgB,MAAM,UAAU,EAAE,SAAS,WAAW,CAAC;MAC7D,QAAQ,gBAAgB,UAAU,UAAU,EAAE,SAAS,WAAW,CAAC;MACnE,SAAS;MACT,UAAU,gBAAgB,QAAQ,UAAU;OAC3C,SAAS;OACT,MAAM;OACN,QAAQ;MACT,CAAC;MACD,OAAO;OACN,SAAS;QACR,QAAQ;QACR,QAAQ,aACL,gBAAgB,YAAY,UAAU;SACtC,SAAS;SACT,SAAS,gBAAgB,kBAAkB;QAC5C,CAAC,IACA,KAAA;OACJ;OACA,OAAO,gBAAgB,gBAAgB,KAAK;MAC7C;MACA,YAAY,cAAc;MAE1B,UAAU,cAAc,KAAK,cAAc;MAE3C,eAAe,gBAAgB,mBAAmB,KAAK;KACxD;IACD;IACA,KAAK,aAAa;KAEjB,MAAM,cAAc,MAAM,KAAK,eAAe,QAAQ,CAAC,aAAa,MAAM,CAAC;KAC3E,IAAI,CAAC,aAAa;MACjB,OAAO,YAAY,8BAA8B;MACjD;KACD;KAGA,MAAM,YAAY,YAAY,MAAM,IAAI,CAAC,CAAC,EAAE,EAAE,KAAK;KACnD,IAAI,CAAC,WAAW;MACf,OAAO,YAAY,2BAA2B;MAC9C;KACD;KAIA,MAAM,eAAe,eAAe,KAAK,SAAS;KAClD,MAAM,WAAW,YAAY,KAAK,SAAS;KAE3C,IAAI,CAAC,gBAAgB,CAAC,UAAU;MAC/B,OAAO,YAAY,8BAA8B,WAAW;MAC5D;KACD;KAGA,MAAM,QAAQ,UAAU,MAAM,eAAe;KAC7C,MAAM,mBAAmB,QAAQ;KACjC,IAAI,CAAC,kBAAkB;MACtB,OAAO,YAAY,gDAAgD;MACnE;KACD;KAIA,MAAM,UAAU,QAAQ,EAAE,EAAE,KAAK,KAAK,KAAA;KAEtC,MAAM,CAAC,cAAc,mBAAmB,MAAM,QAAQ,WAAW,CAChE,KAAK,SAAS,SAAS,0BAA0B,UAAU,YAAY,GACvE,KAAK,SAAS,KAAK,aAAa,UAAU,kBAAkB,QAAQ,KAAA,GAAW,YAAY,CAC5F,CAAC;KACD,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;KAEvD,MAAM,UAAU,gBAAgB,YAAY;KAC5C,MAAM,YAAY,gBAAgB,eAAe;KAEjD,IAAI,cACH,OAAO;MACN,MAAM;MACI;MACC;MACX,MAAM,gBAAgB,kBAAkB,UAAU;OACjD,SAAS;OACA;MACV,CAAC;MACQ;MACT,UAAU,gBAAgB,kBAAkB,UAAU;OACrD,SAAS;OACA;MACV,CAAC;KACF;KAGD,OAAO;MACN,MAAM;MACI;MACC;MACX,MAAM,gBAAgB,kBAAkB,UAAU;OAAE,SAAS;OAAqB;MAAQ,CAAC;MAClF;MACT,UAAU,gBAAgB,kBAAkB,UAAU;OACrD,SAAS;OACA;MACV,CAAC;KACF;IACD;GACD;EACD,CAEY;CACb;;;CAIA,sCAAuC,IAAI,IAA0D;CAErG,MAAc,iBACb,UACA,KACA,cAC8B;EAC9B,MAAM,SAAS,KAAK,oBAAoB,IAAI,QAAQ;EACpD,IAAI,QAAQ,QAAQ,KAAK,OAAO,OAAO;EASvC,MAAM,WAAU,MAPK,KAAK,IAAI,IAC7B;GAAE,KAAK;GAAwB;GAAc,QAAQ;EAAS,GAC9D,OACA,MACA,eACA,GACD,EAAA,CACuB,OAAO,KAAK,KAAK,KAAA;EAExC,IAAI,WAAW,MACd,KAAK,oBAAoB,IAAI,UAAU;GAAO;GAAc;EAAQ,CAAC;EAEtE,OAAO;CACR;CAYA,MAAc,eACb,QACA,WACA,SACuC;EACvC,IAAI;GACH,MAAM,WAAW,UAAU,OAAO,IAAI,QAAQ,GAAG,SAAS;GAC1D,MAAM,QAAQ,MAAM,SAAS,QAAQ;GACrC,IAAI,WAAW,IAAI,YAAY,MAAM,CAAC,CAAC,OAAO,KAAK;GACnD,WAAY,SAAS,QAAQ,OAAQ,SAAS,KAAK,IAAI;GAEvD,IAAI,SAAS,SAAS;IACrB,MAAM,SAAS,OAAO,SAAS,UAAU,EAAE;IAC3C,OAAO,MAAM,MAAM,IAAI,KAAA,IAAY;GACpC;GAEA,OAAO;EACR,SAAS,IAAI;GACZ,IAAI,SAAS,OAAO,MAAM;GAE1B;EACD;CACD;CAEA,MAEM,qBAAqB,UAAkB,SAA6C;EACzF,MAAM,QAAQ,gBAAgB;EAE9B,MAAM,SAAS,MAAM,KAAK,yBAAyB,QAAQ;EAC3D,IAAI,UAAU,MAAM;EAEpB,MAAM,OAAO,CAAC,OAAO,MAAM,SAAS,OAAO,WAAW,SAAS;EAE/D,IAAI;GAGH,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAU,QAAQ;IAAS,SAAS;GAAE,GAAG,GAAG,IAAI;EAC3E,SAAS,IAAI;GACZ,OAAO,MAAM,EAAE;GACf,MAAM,mBACL,0BACA,KACA,WACC,IAAI,0BACH;IACS;IACR,WAAW;IACX,YAAY;KAAY;KAAgB;IAAK;GAC9C,GACA,EACD,CACF;EACD,UAAU;GAET,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,YAAY,QAAQ;GACnE,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU;IAAC;IAAQ;IAAS;GAAO,CAAC;EACjF;CACD;CAEA,MACM,wBACL,UACA,SAMgB;EAChB,MAAM,QAAQ,gBAAgB;EAE9B,MAAM,SAAS,MAAM,KAAK,yBAAyB,QAAQ;EAC3D,IAAI,UAAU,MAAM;EAEpB,IAAI,OAAO,SAAS,WAAW,SAAS,MACvC,MAAM,IAAI,MAAM,KAAK,EAAE,mCAAmC,CAAC;EAG5D,MAAM,OAAO,CAAC,OAAO,MAAM,SAAS,OAAO,WAAW,YAAY;EAKlE,MAAM,UAAoB,CAAC;EAC3B,IAAI;EACJ,IAAI,SAAS,eAAe;GAC3B,QAAQ,KAAK,MAAM,eAAe,QAAQ,eAAe;GACzD,MAAM;IAAE,GAAG,QAAQ;IAAW,YAAY,QAAQ;GAAc;EACjE;EAEA,IAAI;GACH,IAAI,SAAS,YAAY;IACxB,MAAM,aAAa;KAAC;KAAU;KAAiB;IAAW;IAC1D,IAAI;KAGH,MAAM,KAAK,IAAI,IAAI;MAAE,KAAK;MAAU,QAAQ;KAAQ,GAAG,GAAG,UAAU;IACrE,SAAS,IAAI;KACZ,OAAO,MAAM,EAAE;KAEf,MAAM,mBACL,6BACA,KACA,WACC,IAAI,6BACH;MACS;MACR,WAAW;MACX,MAAM;MACN,YAAY;OAAY;OAAU,MAAM;MAAW;KACpD,GACA,EACD,CACF;IACD;GACD;GAEA,MAAM,KAAK,IAAI,IACd;IACC,KAAK;IACL,QAAQ;IACC;IACJ;IAIL,SAAS;IAMT,gBAAgB,SAAS,gBAAgB,gCAAgC,KAAA;GAC1E,GACA,GAAG,IACJ;EACD,SAAS,IAAI;GACZ,IAAI,6BAA6B,GAAG,EAAE,GAAG,MAAM;GAE/C,MAAM,QAAQ,mBACb,6BACA,KACA,WACC,IAAI,6BACH;IACS;IACR,WAAW;IACX,MAAM,SAAS,QAAQ;IACvB,YAAY;KAAY;KAAgB;IAAK;GAC9C,GACA,EACD,CACF;GAIA,IAAI,CAAC,SAAS,cAAc,CAAC,6BAA6B,GAAG,OAAO,mBAAmB,GAAG;IACzF,OAAO,MAAM,EAAE;IACf,MAAM;GACP;EACD,UAAU;GAMT,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,YAAY,QAAQ;GACnE,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU;IAAC;IAAQ;IAAS;GAAO,CAAC;EACjF;CACD;AACD;AA1oBE,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,+BAAA,WAAA,sBAAA,IAAA;AAkErB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,+BAAA,WAAA,4BAAA,IAAA;AAqbrB,WAAA,CAAA,MAAM,IAAI,MAAM,GAAG,MAAM,GAAG,GAAG,GAAG,QAAQ,OAAO,GACjD,MAAM,CAAA,GAAA,+BAAA,WAAA,wBAAA,IAAA;AAmCN,WAAA,CAAA,MAAM,CAAA,GAAA,+BAAA,WAAA,2BAAA,IAAA"}
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';\nimport type { IndexRefresher } from '../exec/indexRefresh.js';\nimport { refreshIndexAfter } from '../exec/indexRefresh.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\tprivate readonly indexRefresher?: IndexRefresher,\n\t) {}\n\n\t/**\n\t * Whether git's dir holds a sentinel of an in-progress operation (presence only — no content is parsed,\n\t * so it also answers `true` for states `getPausedOperationStatus` can't describe, e.g. a stopped `git am`).\n\t * Rejects when git's dir can't be resolved or read\n\t */\n\t@debug({ quiet: true })\n\tasync hasPausedOperation(repoPath: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\tconst gitDir = await this.provider.config.getGitDir(repoPath);\n\t\tconst operations = await this.scanGitDir(gitDir);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tfor (const operation of operations) {\n\t\t\t// A bare leftover `sequencer` dir isn't in progress; git itself checks for `sequencer/todo`\n\t\t\tif (operation !== 'sequencer') return true;\n\t\t}\n\t\tif (!operations.has('sequencer')) return false;\n\n\t\ttry {\n\t\t\tawait stat(joinPaths(gitDir.uri.fsPath, 'sequencer', 'todo'));\n\t\t\treturn true;\n\t\t} catch (ex) {\n\t\t\tif ((ex as NodeJS.ErrnoException).code === 'ENOENT') return false;\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Lists the operation sentinels in git's dir; rejects if the dir can't be read */\n\tprivate scanGitDir(gitDir: GitDir): Promise<Set<Operation>> {\n\t\treturn new Promise<Set<Operation>>((resolve, reject) => {\n\t\t\treaddir(gitDir.uri.fsPath, { withFileTypes: true }, (err, entries) => {\n\t\t\t\tif (err != null) {\n\t\t\t\t\treject(err);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst operations = new Set<Operation>();\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tif (entry.isFile()) {\n\t\t\t\t\t\tswitch (entry.name) {\n\t\t\t\t\t\t\tcase 'CHERRY_PICK_HEAD':\n\t\t\t\t\t\t\t\toperations.add('cherry-pick');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'MERGE_HEAD':\n\t\t\t\t\t\t\t\toperations.add('merge');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'REVERT_HEAD':\n\t\t\t\t\t\t\t\toperations.add('revert');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (entry.isDirectory()) {\n\t\t\t\t\t\tswitch (entry.name) {\n\t\t\t\t\t\t\tcase 'rebase-apply':\n\t\t\t\t\t\t\t\toperations.add('rebase-apply');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'rebase-merge':\n\t\t\t\t\t\t\t\toperations.add('rebase-merge');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'sequencer':\n\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// We'll determine the type by reading the todo file later\n\t\t\t\t\t\t\t\toperations.add('sequencer');\n\t\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}\n\n\t\t\t\tresolve(operations);\n\t\t\t});\n\t\t});\n\t}\n\n\t@debug({ quiet: true })\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\t// An unreadable git dir reads as \"nothing paused\" here — the status is best-effort and self-heals\n\t\t\tconst operations = await this.scanGitDir(gitDir).catch(() => new Set<Operation>());\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 refreshIndexAfter(this.indexRefresher, repoPath, () =>\n\t\t\t\tthis.git.run({ cwd: repoPath, errors: 'throw', timeout: 0 }, ...args),\n\t\t\t);\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} finally {\n\t\t\t// An abort that fails or is cancelled partway can still have moved HEAD or reset the working tree\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\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 refreshIndexAfter(this.indexRefresher, repoPath, () =>\n\t\t\t\tthis.git.run(\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\terrors: 'throw',\n\t\t\t\t\t\tconfigs: configs,\n\t\t\t\t\t\tenv: env,\n\t\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\t// that tab open, which is unbounded — the default `advanced.git.timeout` would SIGTERM it\n\t\t\t\t\t\t// mid-operation. The start paths (merge/rebase/revert) opt out for the same reason.\n\t\t\t\t\t\ttimeout: 0,\n\t\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\t// A headless continue (with `GIT_EDITOR`) and a plain `--continue` would therefore collapse\n\t\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\t// message) or the headless one could ride a plain continue and open an editor that hangs the\n\t\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\t\tcorrelationKey: options?.messageEditor ? 'paused-op-continue-headless' : undefined,\n\t\t\t\t\t},\n\t\t\t\t\t...args,\n\t\t\t\t),\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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"}
@@ -48,12 +48,14 @@ var RefsGitSubProvider = class {
48
48
  async getRefs(repoPath, cancellation, options) {
49
49
  if (!repoPath) return [];
50
50
  const scope = getScopedLogger();
51
+ let previous;
51
52
  if (options?.force) {
52
53
  const commonPath = this.cache.getCommonPath(repoPath);
54
+ previous = this.cache.refs.get(commonPath);
53
55
  this.cache.refs.delete(commonPath);
54
56
  this.cache.refTips.delete(commonPath);
55
57
  }
56
- return this.cache.getRefs(repoPath, async (commonPath, cacheable, signal) => {
58
+ const records = await this.cache.getRefs(repoPath, async (commonPath, cacheable, signal) => {
57
59
  try {
58
60
  try {
59
61
  var _usingCtx$1 = _usingCtx();
@@ -89,6 +91,14 @@ var RefsGitSubProvider = class {
89
91
  return [];
90
92
  }
91
93
  }, cancellation);
94
+ if (options?.force && !await areRefTipsEqual(previous, records)) {
95
+ const commonPath = this.cache.getCommonPath(repoPath);
96
+ for (const path of /* @__PURE__ */ new Set([repoPath, ...this.cache.getWorktreePaths(commonPath)])) {
97
+ this.cache.leftRightCommitCount.delete(path);
98
+ this.cache.mergeBase.delete(path);
99
+ }
100
+ }
101
+ return records;
92
102
  }
93
103
  async getRefTips(repoPath, options, cancellation) {
94
104
  if (!repoPath) return [];
@@ -487,6 +497,20 @@ __decorate([debug({ quiet: true })], RefsGitSubProvider.prototype, "isValidRefer
487
497
  __decorate([trace({ quiet: true })], RefsGitSubProvider.prototype, "validateReference", null);
488
498
  __decorate([debug()], RefsGitSubProvider.prototype, "deleteReference", null);
489
499
  __decorate([debug()], RefsGitSubProvider.prototype, "updateReference", null);
500
+ /** Whether `records` hold the same refs at the same commits as the read `previous`; `false` when it is unknown or failed */
501
+ async function areRefTipsEqual(previous, records) {
502
+ let before;
503
+ try {
504
+ if (previous == null) return false;
505
+ before = await previous;
506
+ } catch {
507
+ return false;
508
+ }
509
+ if (before.length !== records.length) return false;
510
+ const tips = /* @__PURE__ */ new Map();
511
+ for (const record of before) tips.set(record.name, record.objectname);
512
+ return records.every((r) => tips.get(r.name) === r.objectname);
513
+ }
490
514
  //#endregion
491
515
  export { RefsGitSubProvider };
492
516
 
@@ -1 +1 @@
1
- {"version":3,"file":"refs.js","names":[],"sources":["../../../../git-cli/src/providers/refs.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { ReferenceUpdateError } from '@gitlens/git/errors.js';\nimport type { GitBranch } from '@gitlens/git/models/branch.js';\nimport type { GitReference, GitRefTip, RefRecord } from '@gitlens/git/models/reference.js';\nimport type { GitReflogEntry } from '@gitlens/git/models/reflog.js';\nimport { deletedOrMissing } from '@gitlens/git/models/revision.js';\nimport type { GitTag } from '@gitlens/git/models/tag.js';\nimport type { GitRefsSubProvider } from '@gitlens/git/providers/refs.js';\nimport type { GitCommandPriority } from '@gitlens/git/run.types.js';\nimport { isRemoteHEAD } from '@gitlens/git/utils/branch.utils.js';\nimport { createReference } from '@gitlens/git/utils/reference.utils.js';\nimport { isSha, isShaWithOptionalRevisionSuffix, isUncommitted } from '@gitlens/git/utils/revision.utils.js';\nimport { compareRefTips } from '@gitlens/git/utils/sorting.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { debug, trace } from '@gitlens/utils/decorators/log.js';\nimport { createDisposable } from '@gitlens/utils/disposable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport { iterateAsyncByDelimiter } from '@gitlens/utils/string.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult } from '../exec/exec.types.js';\nimport type { Git, GitError } from '../exec/git.js';\nimport { getGitCommandError, gitConfigsBranch, gitConfigsLog } from '../exec/git.js';\nimport { getReflogEntryParser } from '../parsers/reflogParser.js';\nimport { getRefParser } from '../parsers/refParser.js';\n\nexport class RefsGitSubProvider implements GitRefsSubProvider {\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({ quiet: true })\n\tasync checkIfCouldBeValidBranchOrTagName(repoPath: string, ref: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst result = await this.git.run({ cwd: repoPath, errors: 'throw' }, 'check-ref-format', '--branch', ref);\n\t\t\treturn Boolean(result.stdout.trim());\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Raw `git for-each-ref` records covering branches, remotes, tags, and replace-refs in a single\n\t * pass. CLI-internal — siblings call via `this.provider.refs.getRefs(...)`. The `RefRecord` shape\n\t * is `for-each-ref`-specific and intentionally absent from the public `GitRefsSubProvider`\n\t * interface.\n\t */\n\t@debug({ quiet: true })\n\tasync getRefs(repoPath: string, cancellation?: AbortSignal, options?: { force?: boolean }): Promise<RefRecord[]> {\n\t\tif (!repoPath) return [];\n\n\t\tconst scope = getScopedLogger();\n\n\t\t// Forces a fresh enumeration: evicts the shared cache entry (and the derived `refTips` projection,\n\t\t// which would otherwise still answer from the old records) so the factory below re-runs and\n\t\t// repopulates both from one spawn. Deliberately `delete`, not `invalidate` — soft-invalidation\n\t\t// leaves an in-flight entry rideable, so a caller needing a point-in-time read (the graph's tip\n\t\t// gate) could join an enumeration that started before the change it's trying to detect. Evicting\n\t\t// is safe mid-flight: the in-flight factory's settle is ownership-guarded and won't evict the\n\t\t// successor installed here.\n\t\tif (options?.force) {\n\t\t\tconst commonPath = this.cache.getCommonPath(repoPath);\n\t\t\tthis.cache.refs.delete(commonPath);\n\t\t\tthis.cache.refTips.delete(commonPath);\n\t\t}\n\n\t\treturn this.cache.getRefs(\n\t\t\trepoPath,\n\t\t\tasync (commonPath, cacheable, signal) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst supported = await this.git.supported('git:for-each-ref');\n\t\t\t\t\tconst parser = getRefParser(supported);\n\t\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t\t{ cwd: commonPath, cancellation: signal, configs: gitConfigsBranch, errors: 'ignore' },\n\t\t\t\t\t\t'for-each-ref',\n\t\t\t\t\t\t...parser.arguments,\n\t\t\t\t\t\t'refs/heads/',\n\t\t\t\t\t\t'refs/remotes/',\n\t\t\t\t\t\t'refs/tags/',\n\t\t\t\t\t\t// `git replace`/grafts — not surfaced to branch/tag/refTip consumers (filtered by\n\t\t\t\t\t\t// refname prefix), but needed by the graph's replace-ref change gate (graph.ts).\n\t\t\t\t\t\t'refs/replace/',\n\t\t\t\t\t);\n\t\t\t\t\t// Under `errors: 'ignore'` a cancelled run RESOLVES empty rather than throwing, so the\n\t\t\t\t\t// catch below never sees it and an empty enumeration would be cached as a real answer —\n\t\t\t\t\t// permanently, since this map has no TTL. Same guard `git.run`'s own caching path uses.\n\t\t\t\t\t// The graph's tip gate calls this with `force: true` and supersedes itself freely, so it\n\t\t\t\t\t// is routinely the sole registrant on the aggregate whose abort kills the spawn.\n\t\t\t\t\t// Covers a FAILED enumeration too, not just a cancelled one: a transient `for-each-ref`\n\t\t\t\t\t// failure (a lingering `index.lock`, EMFILE, the git dir briefly unavailable) also\n\t\t\t\t\t// resolves empty, and caching that `[]` would blank every branch, tag and ref-tip\n\t\t\t\t\t// consumer for the rest of the session. A genuinely ref-less repo still exits cleanly\n\t\t\t\t\t// with empty stdout, so it caches as before.\n\t\t\t\t\tif (result.completion.status !== 'exited' || result.exitCode !== 0 || signal?.aborted) {\n\t\t\t\t\t\tcacheable?.invalidate();\n\t\t\t\t\t\treturn [];\n\t\t\t\t\t}\n\t\t\t\t\tif (!result?.stdout) return [];\n\n\t\t\t\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\t\t\t\tconst records = [...parser.parse(result.stdout)];\n\n\t\t\t\t\tsw?.stop({ suffix: ` parsed ${records.length} ref records` });\n\n\t\t\t\t\treturn records;\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tcacheable?.invalidate();\n\t\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\t\tscope?.error(ex);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@debug({ quiet: true })\n\tasync getRefTips(\n\t\trepoPath: string,\n\t\toptions?: { include?: ReadonlyArray<'heads' | 'remotes' | 'tags'> },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitRefTip[]> {\n\t\tif (!repoPath) return [];\n\n\t\tconst scope = getScopedLogger();\n\n\t\t// Cache always holds the full set; subset filtering is applied on read so callers asking\n\t\t// for different subsets share one cache entry.\n\t\tconst all = await this.cache.getRefTips(\n\t\t\trepoPath,\n\t\t\tasync (_commonPath, _cacheable, signal) => {\n\t\t\t\tconst records = await this.getRefs(repoPath, signal);\n\n\t\t\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\t\t\tconst tips: GitRefTip[] = [];\n\t\t\t\tfor (const record of records) {\n\t\t\t\t\tconst fullName = record.name;\n\t\t\t\t\tif (!fullName) continue;\n\t\t\t\t\t// Skip refs/remotes/<remote>/HEAD — symbolic, not a real tip.\n\t\t\t\t\tif (isRemoteHEAD(fullName)) continue;\n\n\t\t\t\t\tlet type: GitRefTip['type'];\n\t\t\t\t\tlet name: string;\n\t\t\t\t\tif (fullName.startsWith('refs/heads/')) {\n\t\t\t\t\t\ttype = 'branch';\n\t\t\t\t\t\tname = fullName.substring(11);\n\t\t\t\t\t} else if (fullName.startsWith('refs/remotes/')) {\n\t\t\t\t\t\ttype = 'remote';\n\t\t\t\t\t\tname = fullName.substring(13);\n\t\t\t\t\t} else if (fullName.startsWith('refs/tags/')) {\n\t\t\t\t\t\ttype = 'tag';\n\t\t\t\t\t\tname = fullName.substring(10);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Annotated tags: peeledObjectname is the commit SHA; objectname is the tag-object SHA.\n\t\t\t\t\t// Lightweight tags / branches: peeledObjectname is empty; objectname is already the commit SHA.\n\t\t\t\t\tconst sha = record.peeledObjectname || record.objectname;\n\n\t\t\t\t\ttips.push({ type: type, name: name, fullName: fullName, sha: sha });\n\t\t\t\t}\n\n\t\t\t\tsw?.stop({ suffix: ` projected ${tips.length} ref tips` });\n\n\t\t\t\treturn tips;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\n\t\tconst include = options?.include;\n\t\tif (include == null || (include.includes('heads') && include.includes('remotes') && include.includes('tags'))) {\n\t\t\treturn all;\n\t\t}\n\n\t\treturn all.filter(r => {\n\t\t\tswitch (r.type) {\n\t\t\t\tcase 'branch':\n\t\t\t\t\treturn include.includes('heads');\n\t\t\t\tcase 'remote':\n\t\t\t\t\treturn include.includes('remotes');\n\t\t\t\tcase 'tag':\n\t\t\t\t\treturn include.includes('tags');\n\t\t\t}\n\t\t});\n\t}\n\n\t@debug({ quiet: true })\n\tasync getRefsContainingShas(\n\t\trepoPath: string,\n\t\tshas: ReadonlySet<string> | readonly string[],\n\t\toldestSha: string,\n\t\toptions?: { include?: ReadonlyArray<'heads' | 'remotes' | 'tags'> },\n\t\tcancellation?: AbortSignal,\n\t): Promise<Map<string, GitRefTip[]>> {\n\t\tconst targetShas = shas instanceof Set ? shas : new Set(shas);\n\t\tif (!targetShas.size || !oldestSha) return new Map();\n\n\t\tconst scope = getScopedLogger();\n\n\t\tconst tips = await this.getRefTips(repoPath, options, cancellation);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\tif (!tips.length) return new Map();\n\n\t\t// Index tips by full ref name (for projection back to GitRefTip later) and seed the\n\t\t// propagation map by tip SHA. Multiple refs sharing a tip (e.g. local + remote-tracking)\n\t\t// collapse into one Set entry whose union covers all of them.\n\t\tconst tipsByName = new Map<string, GitRefTip>();\n\t\tconst propMap = new Map<string, Set<string>>();\n\t\tfor (const tip of tips) {\n\t\t\ttipsByName.set(tip.fullName, tip);\n\t\t\tlet names = propMap.get(tip.sha);\n\t\t\tif (names == null) {\n\t\t\t\tnames = new Set();\n\t\t\t\tpropMap.set(tip.sha, names);\n\t\t\t}\n\t\t\tnames.add(tip.fullName);\n\t\t}\n\n\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\t// `^<oldestSha>^@` excludes the parents of <oldestSha> and everything older. When <oldestSha>\n\t\t// is a root commit, `^@` resolves to nothing and the walk is naturally unbounded — git\n\t\t// doesn't error in that case (no negative refs to apply).\n\t\tconst stream = this.git.stream(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsBranch },\n\t\t\t'rev-list',\n\t\t\t'--topo-order',\n\t\t\t'--parents',\n\t\t\t'--all',\n\t\t\t`^${oldestSha}^@`,\n\t\t);\n\t\tusing _streamDisposer = createDisposable(() => void stream.return?.(undefined));\n\n\t\t// Topological propagation: `--topo-order` emits all children of X before X's own line, so\n\t\t// by the time we process \"X P1 P2...\" every child has already merged its set into X. We\n\t\t// then forward X's accumulated set to each parent — one-pass and correct.\n\t\ttry {\n\t\t\tfor await (const line of iterateAsyncByDelimiter(stream, '\\n')) {\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\t\t\tif (!line) continue;\n\n\t\t\t\tconst firstSpace = line.indexOf(' ');\n\t\t\t\tconst sha = firstSpace === -1 ? line : line.substring(0, firstSpace);\n\t\t\t\tif (!sha) continue;\n\n\t\t\t\tconst refs = propMap.get(sha);\n\t\t\t\tif (!refs?.size) continue;\n\n\t\t\t\tif (firstSpace === -1) continue; // No parents — nothing to propagate to\n\n\t\t\t\t// Walk parent SHAs by index without splitting the whole line.\n\t\t\t\tlet start = firstSpace + 1;\n\t\t\t\twhile (start < line.length) {\n\t\t\t\t\tconst next = line.indexOf(' ', start);\n\t\t\t\t\tconst parentSha = next === -1 ? line.substring(start) : line.substring(start, next);\n\t\t\t\t\tif (parentSha) {\n\t\t\t\t\t\tlet parentRefs = propMap.get(parentSha);\n\t\t\t\t\t\tif (parentRefs == null) {\n\t\t\t\t\t\t\tparentRefs = new Set(refs);\n\t\t\t\t\t\t\tpropMap.set(parentSha, parentRefs);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfor (const name of refs) {\n\t\t\t\t\t\t\t\tparentRefs.add(name);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (next === -1) break;\n\n\t\t\t\t\tstart = next + 1;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tscope?.error(ex);\n\t\t\treturn new Map();\n\t\t}\n\n\t\t// Project to targets, materialize GitRefTip[], sort.\n\t\tconst result = new Map<string, GitRefTip[]>();\n\t\tfor (const sha of targetShas) {\n\t\t\tconst names = propMap.get(sha);\n\t\t\tif (!names?.size) continue;\n\n\t\t\tconst refs: GitRefTip[] = [];\n\t\t\tfor (const name of names) {\n\t\t\t\tconst tip = tipsByName.get(name);\n\t\t\t\tif (tip != null) {\n\t\t\t\t\trefs.push(tip);\n\t\t\t\t}\n\t\t\t}\n\t\t\trefs.sort(compareRefTips);\n\t\t\tresult.set(sha, refs);\n\t\t}\n\n\t\tsw?.stop({ suffix: ` resolved ${result.size}/${targetShas.size} target shas` });\n\n\t\treturn result;\n\t}\n\n\t@debug({ quiet: true })\n\tasync getMergeBase(\n\t\trepoPath: string,\n\t\tref1: string,\n\t\tref2: string,\n\t\toptions?: { forkPoint?: boolean; priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\t// Why: ref1/ref2 are usually branch names; correctness relies on the gitResults cache being\n\t\t\t\t\t// cleared on 'heads'/'remotes' events when refs move. Web (no fs watcher) sees up to\n\t\t\t\t\t// `accessTTL` of staleness — acceptable trade-off for the perf win on graph/branch reads.\n\t\t\t\t\tcaching: { cache: this.cache.gitResults, options: { accessTTL: 5 * 60 * 1000 } },\n\t\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t\t},\n\t\t\t\t'merge-base',\n\t\t\t\toptions?.forkPoint ? '--fork-point' : undefined,\n\t\t\t\tref1,\n\t\t\t\tref2,\n\t\t\t);\n\t\t\tif (!result.stdout) return undefined;\n\n\t\t\treturn result.stdout.split('\\n')[0].trim() || undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug({ quiet: true })\n\tasync getReflogEntries(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { grep?: string; priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitReflogEntry[]> {\n\t\t// `show` so a branch named `delete`, `expire` or `exists` isn't read as that subcommand, and the trailing\n\t\t// `--` so one named like a tracked file isn't rejected as ambiguous\n\t\tconst parser = getReflogEntryParser();\n\t\tconst args = ['reflog', 'show', ...parser.arguments];\n\t\tif (options?.grep) {\n\t\t\t// A basic regex whatever the user's `grep.patternType`, which as `fixed` would match no pattern at all\n\t\t\targs.push('--basic-regexp', `--grep-reflog=${options.grep}`);\n\t\t}\n\t\targs.push(ref, '--');\n\n\t\tconst result = await this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\terrors: 'throw',\n\t\t\t\tcancellation: cancellation,\n\t\t\t\t// A user's `log.showSignature` would print gpg output into the records\n\t\t\t\tconfigs: gitConfigsLog,\n\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t},\n\t\t\t...args,\n\t\t);\n\n\t\tconst entries: GitReflogEntry[] = [];\n\t\tfor (const entry of parser.parse(result.stdout)) {\n\t\t\tentries.push({ sha: entry.sha, message: entry.subject });\n\t\t}\n\t\treturn entries;\n\t}\n\n\t@debug({ quiet: true })\n\tasync getReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { force?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitReference | undefined> {\n\t\tif (!ref || ref === deletedOrMissing) return undefined;\n\n\t\tconst valid = options?.force\n\t\t\t? await this.validateReference(repoPath, ref, { force: true }, cancellation)\n\t\t\t: await this.isValidReference(repoPath, ref, undefined, cancellation);\n\t\tif (!valid) return undefined;\n\n\t\tif (ref !== 'HEAD' && !isShaWithOptionalRevisionSuffix(ref)) {\n\t\t\tconst branch = await this.provider.branches.getBranch(\n\t\t\t\trepoPath,\n\t\t\t\tref,\n\t\t\t\toptions?.force ? { force: true } : undefined,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (branch != null) {\n\t\t\t\treturn createReference(branch.ref, repoPath, {\n\t\t\t\t\tid: branch.id,\n\t\t\t\t\trefType: 'branch',\n\t\t\t\t\tname: branch.name,\n\t\t\t\t\tremote: branch.remote,\n\t\t\t\t\tupstream: branch.upstream,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Not forced: a tag that moves is rare enough that `force` is scoped to branches and validation.\n\t\t\tconst tag = await this.provider.tags.getTag(repoPath, ref, cancellation);\n\t\t\tif (tag != null) {\n\t\t\t\treturn createReference(tag.ref, repoPath, {\n\t\t\t\t\tid: tag.id,\n\t\t\t\t\trefType: 'tag',\n\t\t\t\t\tname: tag.name,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn createReference(ref, repoPath, { refType: 'revision' });\n\t}\n\n\t@debug({ quiet: true })\n\tasync getSymbolicReferenceName(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tconst result = await this.runSymbolicReferenceName(repoPath, ref, options, cancellation);\n\t\treturn result.stdout.trim() || undefined;\n\t}\n\n\t/**\n\t * Like {@link getSymbolicReferenceName}, but tells a ref git confirmed doesn't exist (`rev-parse --verify` exit 1)\n\t * apart from a read that didn't complete (timeout, error, cancellation), which never reports `missing`.\n\t * Shares the same cached `rev-parse`, though only a found ref is cached: a missing one re-runs on every call.\n\t */\n\t@debug({ quiet: true })\n\tasync getSymbolicReferenceNameOrMissing(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<{ name: string | undefined; missing: boolean }> {\n\t\tconst result = await this.runSymbolicReferenceName(repoPath, ref, options, cancellation);\n\t\treturn {\n\t\t\tname: result.stdout.trim() || undefined,\n\t\t\tmissing: result.completion.status === 'exited' && result.completion.code === 1,\n\t\t};\n\t}\n\n\tprivate async runSymbolicReferenceName(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitResult> {\n\t\tconst supportsEndOfOptions = await this.git.supports('git:rev-parse:end-of-options');\n\n\t\treturn this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\terrors: 'ignore',\n\t\t\t\t// Why: a fixed ref name's symbolic name is itself stable; only HEAD's, or whether the ref exists\n\t\t\t\t// at all, changes — and the gitResults cache is cleared on those ref events. 60s TTL is the failsafe\n\t\t\t\t// for watcher latency / web — matches the other \"resolve symbolic state\" calls in commits.ts.\n\t\t\t\tcaching: { cache: this.cache.gitResults, options: { accessTTL: 60 * 1000 } },\n\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t},\n\t\t\t'rev-parse',\n\t\t\t'--verify',\n\t\t\t'--quiet',\n\t\t\t'--symbolic-full-name',\n\t\t\t'--abbrev-ref',\n\t\t\tsupportsEndOfOptions ? '--end-of-options' : undefined,\n\t\t\tref,\n\t\t);\n\t}\n\n\t@debug({ quiet: true, args: repoPath => ({ repoPath: repoPath }) })\n\tasync hasBranchOrTag(\n\t\trepoPath: string | undefined,\n\t\toptions?: {\n\t\t\tfilter?: { branches?: (b: GitBranch) => boolean; tags?: (t: GitTag) => boolean };\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tif (repoPath == null) return false;\n\n\t\tconst [{ values: branches }, { values: tags }] = await Promise.all([\n\t\t\tthis.provider.branches.getBranches(\n\t\t\t\trepoPath,\n\t\t\t\t{ filter: options?.filter?.branches, sort: false },\n\t\t\t\tcancellation,\n\t\t\t),\n\t\t\tthis.provider.tags.getTags(repoPath, { filter: options?.filter?.tags, sort: false }, cancellation),\n\t\t]);\n\n\t\treturn branches.length !== 0 || tags.length !== 0;\n\t}\n\n\t@debug({ quiet: true })\n\tasync isValidReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\tpathOrUri?: string | Uri,\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tconst path = pathOrUri != null ? toFsPath(pathOrUri) : undefined;\n\t\tconst relativePath = path ? this.provider.getRelativePath(path, repoPath) : undefined;\n\t\treturn Boolean(\n\t\t\t(await this.validateReference(repoPath, ref, { relativePath: relativePath }, cancellation))?.length,\n\t\t);\n\t}\n\n\t@trace({ quiet: true })\n\tasync validateReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { relativePath?: string; force?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tif (!ref) return undefined;\n\t\tif (ref === deletedOrMissing || isUncommitted(ref)) return ref;\n\n\t\tconst relativePath = options?.relativePath;\n\t\tconst supportsEndOfOptions = await this.git.supports('git:rev-parse:end-of-options');\n\n\t\t// Why: a SHA-only validation (no path suffix) is effectively immutable — 5-min TTL is safe.\n\t\t// Otherwise the resolved SHA can shift on ref move (or working-tree change for path-scoped\n\t\t// validation); rely on gitResults being cleared on 'head'/'heads'/'remotes' events, with 60s\n\t\t// TTL as the failsafe for watcher latency / web.\n\t\tconst stable = relativePath == null && isSha(ref);\n\t\tconst result = await this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\terrors: 'ignore',\n\t\t\t\tcaching: {\n\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\toptions: { accessTTL: stable ? 5 * 60 * 1000 : 60 * 1000 },\n\t\t\t\t\tforce: options?.force,\n\t\t\t\t},\n\t\t\t},\n\t\t\t'rev-parse',\n\t\t\t'--verify',\n\t\t\tsupportsEndOfOptions ? '--end-of-options' : undefined,\n\t\t\trelativePath ? `${ref}:./${relativePath}` : `${ref}^{commit}`,\n\t\t);\n\t\treturn result.stdout.trim() || undefined;\n\t}\n\n\t@debug()\n\tasync deleteReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { expected?: string },\n\t\tcancellation?: AbortSignal,\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\t// `--no-deref`: without it git deletes what a symbolic ref points to rather than the ref itself, so\n\t\t// deleting `refs/remotes/origin/HEAD` would take `origin/main` with it\n\t\tconst args = ['update-ref', '-d', '--no-deref', ref];\n\t\tif (options?.expected != null) {\n\t\t\targs.push(options.expected);\n\t\t}\n\n\t\t// `HEAD` is either the checked-out branch or, detached, the repository's own HEAD file — neither\n\t\t// may be deleted\n\t\tif (ref === 'HEAD') {\n\t\t\tthrow new ReferenceUpdateError({\n\t\t\t\treason: 'checkedOut',\n\t\t\t\taction: 'delete',\n\t\t\t\tref: ref,\n\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t});\n\t\t}\n\n\t\t// `update-ref -d` has none of `git branch -d`'s guards or cleanup, so a local branch gets them here:\n\t\t// deleting one checked out in a worktree would leave that worktree on a branch that no longer exists.\n\t\tconst branch = ref.startsWith('refs/heads/') ? ref.substring('refs/heads/'.length) : undefined;\n\t\tif (branch != null) {\n\t\t\t// Read git's worktree list directly rather than the cached one: that names a worktree's branch\n\t\t\t// only when the separately cached branch list has it, so a worktree or branch made outside core\n\t\t\t// since the last read would slip past this guard.\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'throw' },\n\t\t\t\t'worktree',\n\t\t\t\t'list',\n\t\t\t\t'--porcelain',\n\t\t\t);\n\t\t\tif (result.stdout.split('\\n').some(l => l.trim() === `branch ${ref}`)) {\n\t\t\t\tthrow new ReferenceUpdateError({\n\t\t\t\t\treason: 'checkedOut',\n\t\t\t\t\taction: 'delete',\n\t\t\t\t\tref: ref,\n\t\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// `errors: 'throw'`: the default handler resolves a `GitWarnings` match (e.g. \"not a git\n\t\t\t// repository\"), which would report a write that never happened as done\n\t\t\tawait this.git.run({ cwd: repoPath, cancellation: cancellation, errors: 'throw' }, ...args);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'update-ref-delete',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew ReferenceUpdateError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\taction: 'delete',\n\t\t\t\t\t\t\tref: ref,\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 as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (branch != null) {\n\t\t\ttry {\n\t\t\t\t// What `git branch -d` removes itself (the upstream and other per-branch settings), then GitLens's own\n\t\t\t\tawait this.git.run(\n\t\t\t\t\t{ cwd: repoPath, errors: 'ignore' },\n\t\t\t\t\t'config',\n\t\t\t\t\t'--remove-section',\n\t\t\t\t\t`branch.${branch}`,\n\t\t\t\t);\n\t\t\t\tawait this.provider.branches.forgetDeletedBranch(repoPath, branch);\n\t\t\t} finally {\n\t\t\t\t// The ref is already gone, so announce even if the cleanup above fails. A single combined\n\t\t\t\t// reset/announce rather than this plus `fireReferenceChanged`'s own `'branches'`/`['heads']` —\n\t\t\t\t// a branch delete only needs one of each. The config change is the branch's own section.\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'config');\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['config', 'heads'], [ref], {\n\t\t\t\t\tconfigConfinedToRefs: true,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.fireReferenceChanged(repoPath, ref, false);\n\t}\n\n\t@debug()\n\tasync updateReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\tsha: string,\n\t\toptions?: { expected?: string | 'absent' },\n\t\tcancellation?: AbortSignal,\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst args = ['update-ref', ref, sha];\n\t\tif (options?.expected != null) {\n\t\t\t// Git's own compare-and-swap old-value argument, which makes the update atomic against a\n\t\t\t// concurrent writer. An EMPTY old value is how git spells \"the ref must not exist yet\"; the\n\t\t\t// empty string has to reach argv intact, which it does because the executor drops only\n\t\t\t// null/undefined.\n\t\t\targs.push(options.expected === 'absent' ? '' : options.expected);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, cancellation: cancellation, errors: 'throw' }, ...args);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'update-ref',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew ReferenceUpdateError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\taction: 'update',\n\t\t\t\t\t\t\tref: ref,\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 as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tthis.fireReferenceChanged(repoPath, ref, true);\n\t}\n\n\t/**\n\t * Announces a ref mutation to the cache and repository hooks. `deref` says git followed a symbolic `ref` (no\n\t * `--no-deref`), so a remote's `HEAD` moved the branch it points to and stays unnamed.\n\t */\n\tprivate fireReferenceChanged(repoPath: string, ref: string, deref: boolean): void {\n\t\tconst refs = deref && ref.endsWith('/HEAD') ? undefined : [ref];\n\t\tif (ref === 'HEAD') {\n\t\t\t// `update-ref HEAD` moves whatever HEAD resolves to — the checked-out branch, or a detached HEAD\n\t\t\t// — which also changes what the index and working tree are compared against.\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'status');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['head', 'heads']);\n\t\t} else if (ref.startsWith('refs/heads/')) {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['heads'], refs);\n\t\t} else if (ref.startsWith('refs/tags/')) {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'tags');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['tags'], refs);\n\t\t} else if (ref.startsWith('refs/remotes/')) {\n\t\t\t// Remote-tracking branches are read through the branch and ref-tip caches, which `'branches'`\n\t\t\t// clears; `'remotes'` covers only the configured remotes, which a ref write cannot change.\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['remotes'], refs);\n\t\t} else if (ref === 'refs/stash') {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash'], refs);\n\t\t}\n\t\t// A ref outside those namespaces (a consumer's own bookkeeping under `refs/<tool>/`) is in no cached ref\n\t\t// list, and announcing it as an unknown change would make a host refresh everything for it. Only a\n\t\t// `git log --all` walk (graph, search, contributors) sees one, when it points at a commit, so a row it\n\t\t// adds or drops can stay stale until the next heads change.\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"refs.js","names":[],"sources":["../../../../git-cli/src/providers/refs.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { ReferenceUpdateError } from '@gitlens/git/errors.js';\nimport type { GitBranch } from '@gitlens/git/models/branch.js';\nimport type { GitReference, GitRefTip, RefRecord } from '@gitlens/git/models/reference.js';\nimport type { GitReflogEntry } from '@gitlens/git/models/reflog.js';\nimport { deletedOrMissing } from '@gitlens/git/models/revision.js';\nimport type { GitTag } from '@gitlens/git/models/tag.js';\nimport type { GitRefsSubProvider } from '@gitlens/git/providers/refs.js';\nimport type { GitCommandPriority } from '@gitlens/git/run.types.js';\nimport { isRemoteHEAD } from '@gitlens/git/utils/branch.utils.js';\nimport { createReference } from '@gitlens/git/utils/reference.utils.js';\nimport { isSha, isShaWithOptionalRevisionSuffix, isUncommitted } from '@gitlens/git/utils/revision.utils.js';\nimport { compareRefTips } from '@gitlens/git/utils/sorting.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { debug, trace } from '@gitlens/utils/decorators/log.js';\nimport { createDisposable } from '@gitlens/utils/disposable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport { iterateAsyncByDelimiter } from '@gitlens/utils/string.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult } from '../exec/exec.types.js';\nimport type { Git, GitError } from '../exec/git.js';\nimport { getGitCommandError, gitConfigsBranch, gitConfigsLog } from '../exec/git.js';\nimport { getReflogEntryParser } from '../parsers/reflogParser.js';\nimport { getRefParser } from '../parsers/refParser.js';\n\nexport class RefsGitSubProvider implements GitRefsSubProvider {\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({ quiet: true })\n\tasync checkIfCouldBeValidBranchOrTagName(repoPath: string, ref: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst result = await this.git.run({ cwd: repoPath, errors: 'throw' }, 'check-ref-format', '--branch', ref);\n\t\t\treturn Boolean(result.stdout.trim());\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Raw `git for-each-ref` records covering branches, remotes, tags, and replace-refs in a single\n\t * pass. CLI-internal — siblings call via `this.provider.refs.getRefs(...)`. The `RefRecord` shape\n\t * is `for-each-ref`-specific and intentionally absent from the public `GitRefsSubProvider`\n\t * interface.\n\t */\n\t@debug({ quiet: true })\n\tasync getRefs(repoPath: string, cancellation?: AbortSignal, options?: { force?: boolean }): Promise<RefRecord[]> {\n\t\tif (!repoPath) return [];\n\n\t\tconst scope = getScopedLogger();\n\n\t\t// Forces a fresh enumeration: evicts the shared cache entry (and the derived `refTips` projection,\n\t\t// which would otherwise still answer from the old records) so the factory below re-runs and\n\t\t// repopulates both from one spawn. Deliberately `delete`, not `invalidate` — soft-invalidation\n\t\t// leaves an in-flight entry rideable, so a caller needing a point-in-time read (the graph's tip\n\t\t// gate) could join an enumeration that started before the change it's trying to detect. Evicting\n\t\t// is safe mid-flight: the in-flight factory's settle is ownership-guarded and won't evict the\n\t\t// successor installed here.\n\t\tlet previous: Promise<RefRecord[]> | undefined;\n\t\tif (options?.force) {\n\t\t\tconst commonPath = this.cache.getCommonPath(repoPath);\n\t\t\tprevious = this.cache.refs.get(commonPath);\n\t\t\tthis.cache.refs.delete(commonPath);\n\t\t\tthis.cache.refTips.delete(commonPath);\n\t\t}\n\n\t\tconst records = await this.cache.getRefs(\n\t\t\trepoPath,\n\t\t\tasync (commonPath, cacheable, signal) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst supported = await this.git.supported('git:for-each-ref');\n\t\t\t\t\tconst parser = getRefParser(supported);\n\t\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t\t{ cwd: commonPath, cancellation: signal, configs: gitConfigsBranch, errors: 'ignore' },\n\t\t\t\t\t\t'for-each-ref',\n\t\t\t\t\t\t...parser.arguments,\n\t\t\t\t\t\t'refs/heads/',\n\t\t\t\t\t\t'refs/remotes/',\n\t\t\t\t\t\t'refs/tags/',\n\t\t\t\t\t\t// `git replace`/grafts — not surfaced to branch/tag/refTip consumers (filtered by\n\t\t\t\t\t\t// refname prefix), but needed by the graph's replace-ref change gate (graph.ts).\n\t\t\t\t\t\t'refs/replace/',\n\t\t\t\t\t);\n\t\t\t\t\t// Under `errors: 'ignore'` a cancelled run RESOLVES empty rather than throwing, so the\n\t\t\t\t\t// catch below never sees it and an empty enumeration would be cached as a real answer —\n\t\t\t\t\t// permanently, since this map has no TTL. Same guard `git.run`'s own caching path uses.\n\t\t\t\t\t// The graph's tip gate calls this with `force: true` and supersedes itself freely, so it\n\t\t\t\t\t// is routinely the sole registrant on the aggregate whose abort kills the spawn.\n\t\t\t\t\t// Covers a FAILED enumeration too, not just a cancelled one: a transient `for-each-ref`\n\t\t\t\t\t// failure (a lingering `index.lock`, EMFILE, the git dir briefly unavailable) also\n\t\t\t\t\t// resolves empty, and caching that `[]` would blank every branch, tag and ref-tip\n\t\t\t\t\t// consumer for the rest of the session. A genuinely ref-less repo still exits cleanly\n\t\t\t\t\t// with empty stdout, so it caches as before.\n\t\t\t\t\tif (result.completion.status !== 'exited' || result.exitCode !== 0 || signal?.aborted) {\n\t\t\t\t\t\tcacheable?.invalidate();\n\t\t\t\t\t\treturn [];\n\t\t\t\t\t}\n\t\t\t\t\tif (!result?.stdout) return [];\n\n\t\t\t\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\t\t\t\tconst records = [...parser.parse(result.stdout)];\n\n\t\t\t\t\tsw?.stop({ suffix: ` parsed ${records.length} ref records` });\n\n\t\t\t\t\treturn records;\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tcacheable?.invalidate();\n\t\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\t\tscope?.error(ex);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t\tif (options?.force && !(await areRefTipsEqual(previous, records))) {\n\t\t\t// Keyed by ref names in each checkout, as a tag move clears them, so a count or merge base taken before a\n\t\t\t// ref moved can't be paired with the tips read now; the graph forces this read on every build, so only a\n\t\t\t// read that found a ref moved drops them\n\t\t\tconst commonPath = this.cache.getCommonPath(repoPath);\n\t\t\tfor (const path of new Set([repoPath, ...this.cache.getWorktreePaths(commonPath)])) {\n\t\t\t\tthis.cache.leftRightCommitCount.delete(path);\n\t\t\t\tthis.cache.mergeBase.delete(path);\n\t\t\t}\n\t\t}\n\t\treturn records;\n\t}\n\n\t@debug({ quiet: true })\n\tasync getRefTips(\n\t\trepoPath: string,\n\t\toptions?: { include?: ReadonlyArray<'heads' | 'remotes' | 'tags'> },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitRefTip[]> {\n\t\tif (!repoPath) return [];\n\n\t\tconst scope = getScopedLogger();\n\n\t\t// Cache always holds the full set; subset filtering is applied on read so callers asking\n\t\t// for different subsets share one cache entry.\n\t\tconst all = await this.cache.getRefTips(\n\t\t\trepoPath,\n\t\t\tasync (_commonPath, _cacheable, signal) => {\n\t\t\t\tconst records = await this.getRefs(repoPath, signal);\n\n\t\t\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\t\t\tconst tips: GitRefTip[] = [];\n\t\t\t\tfor (const record of records) {\n\t\t\t\t\tconst fullName = record.name;\n\t\t\t\t\tif (!fullName) continue;\n\t\t\t\t\t// Skip refs/remotes/<remote>/HEAD — symbolic, not a real tip.\n\t\t\t\t\tif (isRemoteHEAD(fullName)) continue;\n\n\t\t\t\t\tlet type: GitRefTip['type'];\n\t\t\t\t\tlet name: string;\n\t\t\t\t\tif (fullName.startsWith('refs/heads/')) {\n\t\t\t\t\t\ttype = 'branch';\n\t\t\t\t\t\tname = fullName.substring(11);\n\t\t\t\t\t} else if (fullName.startsWith('refs/remotes/')) {\n\t\t\t\t\t\ttype = 'remote';\n\t\t\t\t\t\tname = fullName.substring(13);\n\t\t\t\t\t} else if (fullName.startsWith('refs/tags/')) {\n\t\t\t\t\t\ttype = 'tag';\n\t\t\t\t\t\tname = fullName.substring(10);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Annotated tags: peeledObjectname is the commit SHA; objectname is the tag-object SHA.\n\t\t\t\t\t// Lightweight tags / branches: peeledObjectname is empty; objectname is already the commit SHA.\n\t\t\t\t\tconst sha = record.peeledObjectname || record.objectname;\n\n\t\t\t\t\ttips.push({ type: type, name: name, fullName: fullName, sha: sha });\n\t\t\t\t}\n\n\t\t\t\tsw?.stop({ suffix: ` projected ${tips.length} ref tips` });\n\n\t\t\t\treturn tips;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\n\t\tconst include = options?.include;\n\t\tif (include == null || (include.includes('heads') && include.includes('remotes') && include.includes('tags'))) {\n\t\t\treturn all;\n\t\t}\n\n\t\treturn all.filter(r => {\n\t\t\tswitch (r.type) {\n\t\t\t\tcase 'branch':\n\t\t\t\t\treturn include.includes('heads');\n\t\t\t\tcase 'remote':\n\t\t\t\t\treturn include.includes('remotes');\n\t\t\t\tcase 'tag':\n\t\t\t\t\treturn include.includes('tags');\n\t\t\t}\n\t\t});\n\t}\n\n\t@debug({ quiet: true })\n\tasync getRefsContainingShas(\n\t\trepoPath: string,\n\t\tshas: ReadonlySet<string> | readonly string[],\n\t\toldestSha: string,\n\t\toptions?: { include?: ReadonlyArray<'heads' | 'remotes' | 'tags'> },\n\t\tcancellation?: AbortSignal,\n\t): Promise<Map<string, GitRefTip[]>> {\n\t\tconst targetShas = shas instanceof Set ? shas : new Set(shas);\n\t\tif (!targetShas.size || !oldestSha) return new Map();\n\n\t\tconst scope = getScopedLogger();\n\n\t\tconst tips = await this.getRefTips(repoPath, options, cancellation);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\tif (!tips.length) return new Map();\n\n\t\t// Index tips by full ref name (for projection back to GitRefTip later) and seed the\n\t\t// propagation map by tip SHA. Multiple refs sharing a tip (e.g. local + remote-tracking)\n\t\t// collapse into one Set entry whose union covers all of them.\n\t\tconst tipsByName = new Map<string, GitRefTip>();\n\t\tconst propMap = new Map<string, Set<string>>();\n\t\tfor (const tip of tips) {\n\t\t\ttipsByName.set(tip.fullName, tip);\n\t\t\tlet names = propMap.get(tip.sha);\n\t\t\tif (names == null) {\n\t\t\t\tnames = new Set();\n\t\t\t\tpropMap.set(tip.sha, names);\n\t\t\t}\n\t\t\tnames.add(tip.fullName);\n\t\t}\n\n\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\t// `^<oldestSha>^@` excludes the parents of <oldestSha> and everything older. When <oldestSha>\n\t\t// is a root commit, `^@` resolves to nothing and the walk is naturally unbounded — git\n\t\t// doesn't error in that case (no negative refs to apply).\n\t\tconst stream = this.git.stream(\n\t\t\t{ cwd: repoPath, cancellation: cancellation, configs: gitConfigsBranch },\n\t\t\t'rev-list',\n\t\t\t'--topo-order',\n\t\t\t'--parents',\n\t\t\t'--all',\n\t\t\t`^${oldestSha}^@`,\n\t\t);\n\t\tusing _streamDisposer = createDisposable(() => void stream.return?.(undefined));\n\n\t\t// Topological propagation: `--topo-order` emits all children of X before X's own line, so\n\t\t// by the time we process \"X P1 P2...\" every child has already merged its set into X. We\n\t\t// then forward X's accumulated set to each parent — one-pass and correct.\n\t\ttry {\n\t\t\tfor await (const line of iterateAsyncByDelimiter(stream, '\\n')) {\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\t\t\tif (!line) continue;\n\n\t\t\t\tconst firstSpace = line.indexOf(' ');\n\t\t\t\tconst sha = firstSpace === -1 ? line : line.substring(0, firstSpace);\n\t\t\t\tif (!sha) continue;\n\n\t\t\t\tconst refs = propMap.get(sha);\n\t\t\t\tif (!refs?.size) continue;\n\n\t\t\t\tif (firstSpace === -1) continue; // No parents — nothing to propagate to\n\n\t\t\t\t// Walk parent SHAs by index without splitting the whole line.\n\t\t\t\tlet start = firstSpace + 1;\n\t\t\t\twhile (start < line.length) {\n\t\t\t\t\tconst next = line.indexOf(' ', start);\n\t\t\t\t\tconst parentSha = next === -1 ? line.substring(start) : line.substring(start, next);\n\t\t\t\t\tif (parentSha) {\n\t\t\t\t\t\tlet parentRefs = propMap.get(parentSha);\n\t\t\t\t\t\tif (parentRefs == null) {\n\t\t\t\t\t\t\tparentRefs = new Set(refs);\n\t\t\t\t\t\t\tpropMap.set(parentSha, parentRefs);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfor (const name of refs) {\n\t\t\t\t\t\t\t\tparentRefs.add(name);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (next === -1) break;\n\n\t\t\t\t\tstart = next + 1;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tscope?.error(ex);\n\t\t\treturn new Map();\n\t\t}\n\n\t\t// Project to targets, materialize GitRefTip[], sort.\n\t\tconst result = new Map<string, GitRefTip[]>();\n\t\tfor (const sha of targetShas) {\n\t\t\tconst names = propMap.get(sha);\n\t\t\tif (!names?.size) continue;\n\n\t\t\tconst refs: GitRefTip[] = [];\n\t\t\tfor (const name of names) {\n\t\t\t\tconst tip = tipsByName.get(name);\n\t\t\t\tif (tip != null) {\n\t\t\t\t\trefs.push(tip);\n\t\t\t\t}\n\t\t\t}\n\t\t\trefs.sort(compareRefTips);\n\t\t\tresult.set(sha, refs);\n\t\t}\n\n\t\tsw?.stop({ suffix: ` resolved ${result.size}/${targetShas.size} target shas` });\n\n\t\treturn result;\n\t}\n\n\t@debug({ quiet: true })\n\tasync getMergeBase(\n\t\trepoPath: string,\n\t\tref1: string,\n\t\tref2: string,\n\t\toptions?: { forkPoint?: boolean; priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tcancellation: cancellation,\n\t\t\t\t\t// Why: ref1/ref2 are usually branch names; correctness relies on the gitResults cache being\n\t\t\t\t\t// cleared on 'heads'/'remotes' events when refs move. Web (no fs watcher) sees up to\n\t\t\t\t\t// `accessTTL` of staleness — acceptable trade-off for the perf win on graph/branch reads.\n\t\t\t\t\tcaching: { cache: this.cache.gitResults, options: { accessTTL: 5 * 60 * 1000 } },\n\t\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t\t},\n\t\t\t\t'merge-base',\n\t\t\t\toptions?.forkPoint ? '--fork-point' : undefined,\n\t\t\t\tref1,\n\t\t\t\tref2,\n\t\t\t);\n\t\t\tif (!result.stdout) return undefined;\n\n\t\t\treturn result.stdout.split('\\n')[0].trim() || undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug({ quiet: true })\n\tasync getReflogEntries(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { grep?: string; priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitReflogEntry[]> {\n\t\t// `show` so a branch named `delete`, `expire` or `exists` isn't read as that subcommand, and the trailing\n\t\t// `--` so one named like a tracked file isn't rejected as ambiguous\n\t\tconst parser = getReflogEntryParser();\n\t\tconst args = ['reflog', 'show', ...parser.arguments];\n\t\tif (options?.grep) {\n\t\t\t// A basic regex whatever the user's `grep.patternType`, which as `fixed` would match no pattern at all\n\t\t\targs.push('--basic-regexp', `--grep-reflog=${options.grep}`);\n\t\t}\n\t\targs.push(ref, '--');\n\n\t\tconst result = await this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\terrors: 'throw',\n\t\t\t\tcancellation: cancellation,\n\t\t\t\t// A user's `log.showSignature` would print gpg output into the records\n\t\t\t\tconfigs: gitConfigsLog,\n\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t},\n\t\t\t...args,\n\t\t);\n\n\t\tconst entries: GitReflogEntry[] = [];\n\t\tfor (const entry of parser.parse(result.stdout)) {\n\t\t\tentries.push({ sha: entry.sha, message: entry.subject });\n\t\t}\n\t\treturn entries;\n\t}\n\n\t@debug({ quiet: true })\n\tasync getReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { force?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitReference | undefined> {\n\t\tif (!ref || ref === deletedOrMissing) return undefined;\n\n\t\tconst valid = options?.force\n\t\t\t? await this.validateReference(repoPath, ref, { force: true }, cancellation)\n\t\t\t: await this.isValidReference(repoPath, ref, undefined, cancellation);\n\t\tif (!valid) return undefined;\n\n\t\tif (ref !== 'HEAD' && !isShaWithOptionalRevisionSuffix(ref)) {\n\t\t\tconst branch = await this.provider.branches.getBranch(\n\t\t\t\trepoPath,\n\t\t\t\tref,\n\t\t\t\toptions?.force ? { force: true } : undefined,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (branch != null) {\n\t\t\t\treturn createReference(branch.ref, repoPath, {\n\t\t\t\t\tid: branch.id,\n\t\t\t\t\trefType: 'branch',\n\t\t\t\t\tname: branch.name,\n\t\t\t\t\tremote: branch.remote,\n\t\t\t\t\tupstream: branch.upstream,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Not forced: a tag that moves is rare enough that `force` is scoped to branches and validation.\n\t\t\tconst tag = await this.provider.tags.getTag(repoPath, ref, cancellation);\n\t\t\tif (tag != null) {\n\t\t\t\treturn createReference(tag.ref, repoPath, {\n\t\t\t\t\tid: tag.id,\n\t\t\t\t\trefType: 'tag',\n\t\t\t\t\tname: tag.name,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn createReference(ref, repoPath, { refType: 'revision' });\n\t}\n\n\t@debug({ quiet: true })\n\tasync getSymbolicReferenceName(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tconst result = await this.runSymbolicReferenceName(repoPath, ref, options, cancellation);\n\t\treturn result.stdout.trim() || undefined;\n\t}\n\n\t/**\n\t * Like {@link getSymbolicReferenceName}, but tells a ref git confirmed doesn't exist (`rev-parse --verify` exit 1)\n\t * apart from a read that didn't complete (timeout, error, cancellation), which never reports `missing`.\n\t * Shares the same cached `rev-parse`, though only a found ref is cached: a missing one re-runs on every call.\n\t */\n\t@debug({ quiet: true })\n\tasync getSymbolicReferenceNameOrMissing(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<{ name: string | undefined; missing: boolean }> {\n\t\tconst result = await this.runSymbolicReferenceName(repoPath, ref, options, cancellation);\n\t\treturn {\n\t\t\tname: result.stdout.trim() || undefined,\n\t\t\tmissing: result.completion.status === 'exited' && result.completion.code === 1,\n\t\t};\n\t}\n\n\tprivate async runSymbolicReferenceName(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { priority?: GitCommandPriority },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitResult> {\n\t\tconst supportsEndOfOptions = await this.git.supports('git:rev-parse:end-of-options');\n\n\t\treturn this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\terrors: 'ignore',\n\t\t\t\t// Why: a fixed ref name's symbolic name is itself stable; only HEAD's, or whether the ref exists\n\t\t\t\t// at all, changes — and the gitResults cache is cleared on those ref events. 60s TTL is the failsafe\n\t\t\t\t// for watcher latency / web — matches the other \"resolve symbolic state\" calls in commits.ts.\n\t\t\t\tcaching: { cache: this.cache.gitResults, options: { accessTTL: 60 * 1000 } },\n\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t},\n\t\t\t'rev-parse',\n\t\t\t'--verify',\n\t\t\t'--quiet',\n\t\t\t'--symbolic-full-name',\n\t\t\t'--abbrev-ref',\n\t\t\tsupportsEndOfOptions ? '--end-of-options' : undefined,\n\t\t\tref,\n\t\t);\n\t}\n\n\t@debug({ quiet: true, args: repoPath => ({ repoPath: repoPath }) })\n\tasync hasBranchOrTag(\n\t\trepoPath: string | undefined,\n\t\toptions?: {\n\t\t\tfilter?: { branches?: (b: GitBranch) => boolean; tags?: (t: GitTag) => boolean };\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tif (repoPath == null) return false;\n\n\t\tconst [{ values: branches }, { values: tags }] = await Promise.all([\n\t\t\tthis.provider.branches.getBranches(\n\t\t\t\trepoPath,\n\t\t\t\t{ filter: options?.filter?.branches, sort: false },\n\t\t\t\tcancellation,\n\t\t\t),\n\t\t\tthis.provider.tags.getTags(repoPath, { filter: options?.filter?.tags, sort: false }, cancellation),\n\t\t]);\n\n\t\treturn branches.length !== 0 || tags.length !== 0;\n\t}\n\n\t@debug({ quiet: true })\n\tasync isValidReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\tpathOrUri?: string | Uri,\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tconst path = pathOrUri != null ? toFsPath(pathOrUri) : undefined;\n\t\tconst relativePath = path ? this.provider.getRelativePath(path, repoPath) : undefined;\n\t\treturn Boolean(\n\t\t\t(await this.validateReference(repoPath, ref, { relativePath: relativePath }, cancellation))?.length,\n\t\t);\n\t}\n\n\t@trace({ quiet: true })\n\tasync validateReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { relativePath?: string; force?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tif (!ref) return undefined;\n\t\tif (ref === deletedOrMissing || isUncommitted(ref)) return ref;\n\n\t\tconst relativePath = options?.relativePath;\n\t\tconst supportsEndOfOptions = await this.git.supports('git:rev-parse:end-of-options');\n\n\t\t// Why: a SHA-only validation (no path suffix) is effectively immutable — 5-min TTL is safe.\n\t\t// Otherwise the resolved SHA can shift on ref move (or working-tree change for path-scoped\n\t\t// validation); rely on gitResults being cleared on 'head'/'heads'/'remotes' events, with 60s\n\t\t// TTL as the failsafe for watcher latency / web.\n\t\tconst stable = relativePath == null && isSha(ref);\n\t\tconst result = await this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\terrors: 'ignore',\n\t\t\t\tcaching: {\n\t\t\t\t\tcache: this.cache.gitResults,\n\t\t\t\t\toptions: { accessTTL: stable ? 5 * 60 * 1000 : 60 * 1000 },\n\t\t\t\t\tforce: options?.force,\n\t\t\t\t},\n\t\t\t},\n\t\t\t'rev-parse',\n\t\t\t'--verify',\n\t\t\tsupportsEndOfOptions ? '--end-of-options' : undefined,\n\t\t\trelativePath ? `${ref}:./${relativePath}` : `${ref}^{commit}`,\n\t\t);\n\t\treturn result.stdout.trim() || undefined;\n\t}\n\n\t@debug()\n\tasync deleteReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { expected?: string },\n\t\tcancellation?: AbortSignal,\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\t// `--no-deref`: without it git deletes what a symbolic ref points to rather than the ref itself, so\n\t\t// deleting `refs/remotes/origin/HEAD` would take `origin/main` with it\n\t\tconst args = ['update-ref', '-d', '--no-deref', ref];\n\t\tif (options?.expected != null) {\n\t\t\targs.push(options.expected);\n\t\t}\n\n\t\t// `HEAD` is either the checked-out branch or, detached, the repository's own HEAD file — neither\n\t\t// may be deleted\n\t\tif (ref === 'HEAD') {\n\t\t\tthrow new ReferenceUpdateError({\n\t\t\t\treason: 'checkedOut',\n\t\t\t\taction: 'delete',\n\t\t\t\tref: ref,\n\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t});\n\t\t}\n\n\t\t// `update-ref -d` has none of `git branch -d`'s guards or cleanup, so a local branch gets them here:\n\t\t// deleting one checked out in a worktree would leave that worktree on a branch that no longer exists.\n\t\tconst branch = ref.startsWith('refs/heads/') ? ref.substring('refs/heads/'.length) : undefined;\n\t\tif (branch != null) {\n\t\t\t// Read git's worktree list directly rather than the cached one: that names a worktree's branch\n\t\t\t// only when the separately cached branch list has it, so a worktree or branch made outside core\n\t\t\t// since the last read would slip past this guard.\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'throw' },\n\t\t\t\t'worktree',\n\t\t\t\t'list',\n\t\t\t\t'--porcelain',\n\t\t\t);\n\t\t\tif (result.stdout.split('\\n').some(l => l.trim() === `branch ${ref}`)) {\n\t\t\t\tthrow new ReferenceUpdateError({\n\t\t\t\t\treason: 'checkedOut',\n\t\t\t\t\taction: 'delete',\n\t\t\t\t\tref: ref,\n\t\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// `errors: 'throw'`: the default handler resolves a `GitWarnings` match (e.g. \"not a git\n\t\t\t// repository\"), which would report a write that never happened as done\n\t\t\tawait this.git.run({ cwd: repoPath, cancellation: cancellation, errors: 'throw' }, ...args);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'update-ref-delete',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew ReferenceUpdateError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\taction: 'delete',\n\t\t\t\t\t\t\tref: ref,\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 as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (branch != null) {\n\t\t\ttry {\n\t\t\t\t// What `git branch -d` removes itself (the upstream and other per-branch settings), then GitLens's own\n\t\t\t\tawait this.git.run(\n\t\t\t\t\t{ cwd: repoPath, errors: 'ignore' },\n\t\t\t\t\t'config',\n\t\t\t\t\t'--remove-section',\n\t\t\t\t\t`branch.${branch}`,\n\t\t\t\t);\n\t\t\t\tawait this.provider.branches.forgetDeletedBranch(repoPath, branch);\n\t\t\t} finally {\n\t\t\t\t// The ref is already gone, so announce even if the cleanup above fails. A single combined\n\t\t\t\t// reset/announce rather than this plus `fireReferenceChanged`'s own `'branches'`/`['heads']` —\n\t\t\t\t// a branch delete only needs one of each. The config change is the branch's own section.\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'config');\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['config', 'heads'], [ref], {\n\t\t\t\t\tconfigConfinedToRefs: true,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.fireReferenceChanged(repoPath, ref, false);\n\t}\n\n\t@debug()\n\tasync updateReference(\n\t\trepoPath: string,\n\t\tref: string,\n\t\tsha: string,\n\t\toptions?: { expected?: string | 'absent' },\n\t\tcancellation?: AbortSignal,\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst args = ['update-ref', ref, sha];\n\t\tif (options?.expected != null) {\n\t\t\t// Git's own compare-and-swap old-value argument, which makes the update atomic against a\n\t\t\t// concurrent writer. An EMPTY old value is how git spells \"the ref must not exist yet\"; the\n\t\t\t// empty string has to reach argv intact, which it does because the executor drops only\n\t\t\t// null/undefined.\n\t\t\targs.push(options.expected === 'absent' ? '' : options.expected);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, cancellation: cancellation, errors: 'throw' }, ...args);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'update-ref',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew ReferenceUpdateError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\taction: 'update',\n\t\t\t\t\t\t\tref: ref,\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 as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tthis.fireReferenceChanged(repoPath, ref, true);\n\t}\n\n\t/**\n\t * Announces a ref mutation to the cache and repository hooks. `deref` says git followed a symbolic `ref` (no\n\t * `--no-deref`), so a remote's `HEAD` moved the branch it points to and stays unnamed.\n\t */\n\tprivate fireReferenceChanged(repoPath: string, ref: string, deref: boolean): void {\n\t\tconst refs = deref && ref.endsWith('/HEAD') ? undefined : [ref];\n\t\tif (ref === 'HEAD') {\n\t\t\t// `update-ref HEAD` moves whatever HEAD resolves to — the checked-out branch, or a detached HEAD\n\t\t\t// — which also changes what the index and working tree are compared against.\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'status');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['head', 'heads']);\n\t\t} else if (ref.startsWith('refs/heads/')) {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['heads'], refs);\n\t\t} else if (ref.startsWith('refs/tags/')) {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'tags');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['tags'], refs);\n\t\t} else if (ref.startsWith('refs/remotes/')) {\n\t\t\t// Remote-tracking branches are read through the branch and ref-tip caches, which `'branches'`\n\t\t\t// clears; `'remotes'` covers only the configured remotes, which a ref write cannot change.\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['remotes'], refs);\n\t\t} else if (ref === 'refs/stash') {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash'], refs);\n\t\t}\n\t\t// A ref outside those namespaces (a consumer's own bookkeeping under `refs/<tool>/`) is in no cached ref\n\t\t// list, and announcing it as an unknown change would make a host refresh everything for it. Only a\n\t\t// `git log --all` walk (graph, search, contributors) sees one, when it points at a commit, so a row it\n\t\t// adds or drops can stay stale until the next heads change.\n\t}\n}\n\n/** Whether `records` hold the same refs at the same commits as the read `previous`; `false` when it is unknown or failed */\nasync function areRefTipsEqual(previous: Promise<RefRecord[]> | undefined, records: RefRecord[]): Promise<boolean> {\n\tlet before: RefRecord[];\n\ttry {\n\t\tif (previous == null) return false;\n\n\t\tbefore = await previous;\n\t} catch {\n\t\treturn false;\n\t}\n\tif (before.length !== records.length) return false;\n\n\tconst tips = new Map<string, string>();\n\tfor (const record of before) {\n\t\ttips.set(record.name, record.objectname);\n\t}\n\treturn records.every(r => tips.get(r.name) === r.objectname);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA6BA,IAAa,qBAAb,MAA8D;CAE3C;CACA;CACA;CACA;CAJlB,YACC,SACA,KACA,OACA,UACC;EAJgB,KAAA,UAAA;EACA,KAAA,MAAA;EACA,KAAA,QAAA;EACA,KAAA,WAAA;CACf;CAEH,MACM,mCAAmC,UAAkB,KAA+B;EACzF,IAAI;GACH,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAU,QAAQ;GAAQ,GAAG,oBAAoB,YAAY,GAAG;GACzG,OAAO,QAAQ,OAAO,OAAO,KAAK,CAAC;EACpC,QAAQ;GACP,OAAO;EACR;CACD;;;;;;;CAQA,MACM,QAAQ,UAAkB,cAA4B,SAAqD;EAChH,IAAI,CAAC,UAAU,OAAO,CAAC;EAEvB,MAAM,QAAQ,gBAAgB;EAS9B,IAAI;EACJ,IAAI,SAAS,OAAO;GACnB,MAAM,aAAa,KAAK,MAAM,cAAc,QAAQ;GACpD,WAAW,KAAK,MAAM,KAAK,IAAI,UAAU;GACzC,KAAK,MAAM,KAAK,OAAO,UAAU;GACjC,KAAK,MAAM,QAAQ,OAAO,UAAU;EACrC;EAEA,MAAM,UAAU,MAAM,KAAK,MAAM,QAChC,UACA,OAAO,YAAY,WAAW,WAAW;GACxC,IAAI;;;KACH,MAAM,YAAY,MAAM,KAAK,IAAI,UAAU,kBAAkB;KAC7D,MAAM,SAAS,aAAa,SAAS;KACrC,MAAM,SAAS,MAAM,KAAK,IAAI,IAC7B;MAAE,KAAK;MAAY,cAAc;MAAQ,SAAS;MAAkB,QAAQ;KAAS,GACrF,gBACA,GAAG,OAAO,WACV,eACA,iBACA,cAGA,eACD;KAWA,IAAI,OAAO,WAAW,WAAW,YAAY,OAAO,aAAa,KAAK,QAAQ,SAAS;MACtF,WAAW,WAAW;MACtB,OAAO,CAAC;KACT;KACA,IAAI,CAAC,QAAQ,QAAQ,OAAO,CAAC;KAE7B,MAAM,KAAA,YAAA,EAAK,eAAe,OAAO,EAAE,KAAK;MAAE,UAAU;MAAM,OAAO;KAAQ,EAAE,CAAC,CAAA;KAE5E,MAAM,UAAU,CAAC,GAAG,OAAO,MAAM,OAAO,MAAM,CAAC;KAE/C,IAAI,KAAK,EAAE,QAAQ,WAAW,QAAQ,OAAO,cAAc,CAAC;KAE5D,OAAO;;;;;;GACR,SAAS,IAAI;IACZ,WAAW,WAAW;IACtB,IAAI,oBAAoB,EAAE,GAAG,MAAM;IAEnC,OAAO,MAAM,EAAE;IACf,OAAO,CAAC;GACT;EACD,GACA,YACD;EACA,IAAI,SAAS,SAAS,CAAE,MAAM,gBAAgB,UAAU,OAAO,GAAI;GAIlE,MAAM,aAAa,KAAK,MAAM,cAAc,QAAQ;GACpD,KAAK,MAAM,wBAAQ,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,MAAM,iBAAiB,UAAU,CAAC,CAAC,GAAG;IACnF,KAAK,MAAM,qBAAqB,OAAO,IAAI;IAC3C,KAAK,MAAM,UAAU,OAAO,IAAI;GACjC;EACD;EACA,OAAO;CACR;CAEA,MACM,WACL,UACA,SACA,cACuB;EACvB,IAAI,CAAC,UAAU,OAAO,CAAC;EAEvB,MAAM,QAAQ,gBAAgB;EAI9B,MAAM,MAAM,MAAM,KAAK,MAAM,WAC5B,UACA,OAAO,aAAa,YAAY,WAAW;;;IAC1C,MAAM,UAAU,MAAM,KAAK,QAAQ,UAAU,MAAM;IAEnD,MAAM,KAAA,WAAA,EAAK,eAAe,OAAO,EAAE,KAAK;KAAE,UAAU;KAAM,OAAO;IAAQ,EAAE,CAAC,CAAA;IAE5E,MAAM,OAAoB,CAAC;IAC3B,KAAK,MAAM,UAAU,SAAS;KAC7B,MAAM,WAAW,OAAO;KACxB,IAAI,CAAC,UAAU;KAEf,IAAI,aAAa,QAAQ,GAAG;KAE5B,IAAI;KACJ,IAAI;KACJ,IAAI,SAAS,WAAW,aAAa,GAAG;MACvC,OAAO;MACP,OAAO,SAAS,UAAU,EAAE;KAC7B,OAAO,IAAI,SAAS,WAAW,eAAe,GAAG;MAChD,OAAO;MACP,OAAO,SAAS,UAAU,EAAE;KAC7B,OAAO,IAAI,SAAS,WAAW,YAAY,GAAG;MAC7C,OAAO;MACP,OAAO,SAAS,UAAU,EAAE;KAC7B,OACC;KAKD,MAAM,MAAM,OAAO,oBAAoB,OAAO;KAE9C,KAAK,KAAK;MAAQ;MAAY;MAAgB;MAAe;KAAI,CAAC;IACnE;IAEA,IAAI,KAAK,EAAE,QAAQ,cAAc,KAAK,OAAO,WAAW,CAAC;IAEzD,OAAO;;;;;;EACR,GACA,YACD;EAEA,MAAM,UAAU,SAAS;EACzB,IAAI,WAAW,QAAS,QAAQ,SAAS,OAAO,KAAK,QAAQ,SAAS,SAAS,KAAK,QAAQ,SAAS,MAAM,GAC1G,OAAO;EAGR,OAAO,IAAI,QAAO,MAAK;GACtB,QAAQ,EAAE,MAAV;IACC,KAAK,UACJ,OAAO,QAAQ,SAAS,OAAO;IAChC,KAAK,UACJ,OAAO,QAAQ,SAAS,SAAS;IAClC,KAAK,OACJ,OAAO,QAAQ,SAAS,MAAM;GAChC;EACD,CAAC;CACF;CAEA,MACM,sBACL,UACA,MACA,WACA,SACA,cACoC;;;GACpC,MAAM,aAAa,gBAAgB,MAAM,OAAO,IAAI,IAAI,IAAI;GAC5D,IAAI,CAAC,WAAW,QAAQ,CAAC,WAAW,uBAAO,IAAI,IAAI;GAEnD,MAAM,QAAQ,gBAAgB;GAE9B,MAAM,OAAO,MAAM,KAAK,WAAW,UAAU,SAAS,YAAY;GAClE,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;GACvD,IAAI,CAAC,KAAK,QAAQ,uBAAO,IAAI,IAAI;GAKjC,MAAM,6BAAa,IAAI,IAAuB;GAC9C,MAAM,0BAAU,IAAI,IAAyB;GAC7C,KAAK,MAAM,OAAO,MAAM;IACvB,WAAW,IAAI,IAAI,UAAU,GAAG;IAChC,IAAI,QAAQ,QAAQ,IAAI,IAAI,GAAG;IAC/B,IAAI,SAAS,MAAM;KAClB,wBAAQ,IAAI,IAAI;KAChB,QAAQ,IAAI,IAAI,KAAK,KAAK;IAC3B;IACA,MAAM,IAAI,IAAI,QAAQ;GACvB;GAEA,MAAM,KAAA,WAAA,EAAK,eAAe,OAAO,EAAE,KAAK;IAAE,UAAU;IAAM,OAAO;GAAQ,EAAE,CAAC,CAAA;GAK5E,MAAM,SAAS,KAAK,IAAI,OACvB;IAAE,KAAK;IAAwB;IAAc,SAAS;GAAiB,GACvE,YACA,gBACA,aACA,SACA,IAAI,UAAU,GACf;GACwB,WAAA,EAAA,uBAAuB,KAAK,OAAO,SAAS,KAAA,CAAS,CAAC,CAAA;GAK9E,IAAI;IACH,WAAW,MAAM,QAAQ,wBAAwB,QAAQ,IAAI,GAAG;KAC/D,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;KACvD,IAAI,CAAC,MAAM;KAEX,MAAM,aAAa,KAAK,QAAQ,GAAG;KACnC,MAAM,MAAM,eAAe,KAAK,OAAO,KAAK,UAAU,GAAG,UAAU;KACnE,IAAI,CAAC,KAAK;KAEV,MAAM,OAAO,QAAQ,IAAI,GAAG;KAC5B,IAAI,CAAC,MAAM,MAAM;KAEjB,IAAI,eAAe,IAAI;KAGvB,IAAI,QAAQ,aAAa;KACzB,OAAO,QAAQ,KAAK,QAAQ;MAC3B,MAAM,OAAO,KAAK,QAAQ,KAAK,KAAK;MACpC,MAAM,YAAY,SAAS,KAAK,KAAK,UAAU,KAAK,IAAI,KAAK,UAAU,OAAO,IAAI;MAClF,IAAI,WAAW;OACd,IAAI,aAAa,QAAQ,IAAI,SAAS;OACtC,IAAI,cAAc,MAAM;QACvB,aAAa,IAAI,IAAI,IAAI;QACzB,QAAQ,IAAI,WAAW,UAAU;OAClC,OACC,KAAK,MAAM,QAAQ,MAClB,WAAW,IAAI,IAAI;MAGtB;MACA,IAAI,SAAS,IAAI;MAEjB,QAAQ,OAAO;KAChB;IACD;GACD,SAAS,IAAI;IACZ,IAAI,oBAAoB,EAAE,GAAG,MAAM;IAEnC,OAAO,MAAM,EAAE;IACf,uBAAO,IAAI,IAAI;GAChB;GAGA,MAAM,yBAAS,IAAI,IAAyB;GAC5C,KAAK,MAAM,OAAO,YAAY;IAC7B,MAAM,QAAQ,QAAQ,IAAI,GAAG;IAC7B,IAAI,CAAC,OAAO,MAAM;IAElB,MAAM,OAAoB,CAAC;IAC3B,KAAK,MAAM,QAAQ,OAAO;KACzB,MAAM,MAAM,WAAW,IAAI,IAAI;KAC/B,IAAI,OAAO,MACV,KAAK,KAAK,GAAG;IAEf;IACA,KAAK,KAAK,cAAc;IACxB,OAAO,IAAI,KAAK,IAAI;GACrB;GAEA,IAAI,KAAK,EAAE,QAAQ,aAAa,OAAO,KAAK,GAAG,WAAW,KAAK,cAAc,CAAC;GAE9E,OAAO;;;;;;CACR;CAEA,MACM,aACL,UACA,MACA,MACA,SACA,cAC8B;EAC9B,MAAM,QAAQ,gBAAgB;EAE9B,IAAI;GACH,MAAM,SAAS,MAAM,KAAK,IAAI,IAC7B;IACC,KAAK;IACS;IAId,SAAS;KAAE,OAAO,KAAK,MAAM;KAAY,SAAS,EAAE,WAAW,IAAc;IAAE;IAC/E,GAAI,SAAS,YAAY,OAAO,EAAE,UAAU,QAAQ,SAAS,IAAI,KAAA;GAClE,GACA,cACA,SAAS,YAAY,iBAAiB,KAAA,GACtC,MACA,IACD;GACA,IAAI,CAAC,OAAO,QAAQ,OAAO,KAAA;GAE3B,OAAO,OAAO,OAAO,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,KAAK,KAAA;EAC/C,SAAS,IAAI;GACZ,OAAO,MAAM,EAAE;GACf,IAAI,oBAAoB,EAAE,GAAG,MAAM;GAEnC;EACD;CACD;CAEA,MACM,iBACL,UACA,KACA,SACA,cAC4B;EAG5B,MAAM,SAAS,qBAAqB;EACpC,MAAM,OAAO;GAAC;GAAU;GAAQ,GAAG,OAAO;EAAS;EACnD,IAAI,SAAS,MAEZ,KAAK,KAAK,kBAAkB,iBAAiB,QAAQ,MAAM;EAE5D,KAAK,KAAK,KAAK,IAAI;EAEnB,MAAM,SAAS,MAAM,KAAK,IAAI,IAC7B;GACC,KAAK;GACL,QAAQ;GACM;GAEd,SAAS;GACT,GAAI,SAAS,YAAY,OAAO,EAAE,UAAU,QAAQ,SAAS,IAAI,KAAA;EAClE,GACA,GAAG,IACJ;EAEA,MAAM,UAA4B,CAAC;EACnC,KAAK,MAAM,SAAS,OAAO,MAAM,OAAO,MAAM,GAC7C,QAAQ,KAAK;GAAE,KAAK,MAAM;GAAK,SAAS,MAAM;EAAQ,CAAC;EAExD,OAAO;CACR;CAEA,MACM,aACL,UACA,KACA,SACA,cACoC;EACpC,IAAI,CAAC,OAAO,QAAA,6CAA0B,OAAO,KAAA;EAK7C,IAAI,EAHU,SAAS,QACpB,MAAM,KAAK,kBAAkB,UAAU,KAAK,EAAE,OAAO,KAAK,GAAG,YAAY,IACzE,MAAM,KAAK,iBAAiB,UAAU,KAAK,KAAA,GAAW,YAAY,IACzD,OAAO,KAAA;EAEnB,IAAI,QAAQ,UAAU,CAAC,gCAAgC,GAAG,GAAG;GAC5D,MAAM,SAAS,MAAM,KAAK,SAAS,SAAS,UAC3C,UACA,KACA,SAAS,QAAQ,EAAE,OAAO,KAAK,IAAI,KAAA,GACnC,YACD;GACA,IAAI,UAAU,MACb,OAAO,gBAAgB,OAAO,KAAK,UAAU;IAC5C,IAAI,OAAO;IACX,SAAS;IACT,MAAM,OAAO;IACb,QAAQ,OAAO;IACf,UAAU,OAAO;GAClB,CAAC;GAIF,MAAM,MAAM,MAAM,KAAK,SAAS,KAAK,OAAO,UAAU,KAAK,YAAY;GACvE,IAAI,OAAO,MACV,OAAO,gBAAgB,IAAI,KAAK,UAAU;IACzC,IAAI,IAAI;IACR,SAAS;IACT,MAAM,IAAI;GACX,CAAC;EAEH;EAEA,OAAO,gBAAgB,KAAK,UAAU,EAAE,SAAS,WAAW,CAAC;CAC9D;CAEA,MACM,yBACL,UACA,KACA,SACA,cAC8B;EAE9B,QAAO,MADc,KAAK,yBAAyB,UAAU,KAAK,SAAS,YAAY,EAAA,CACzE,OAAO,KAAK,KAAK,KAAA;CAChC;;;;;;CAOA,MACM,kCACL,UACA,KACA,SACA,cAC0D;EAC1D,MAAM,SAAS,MAAM,KAAK,yBAAyB,UAAU,KAAK,SAAS,YAAY;EACvF,OAAO;GACN,MAAM,OAAO,OAAO,KAAK,KAAK,KAAA;GAC9B,SAAS,OAAO,WAAW,WAAW,YAAY,OAAO,WAAW,SAAS;EAC9E;CACD;CAEA,MAAc,yBACb,UACA,KACA,SACA,cACqB;EACrB,MAAM,uBAAuB,MAAM,KAAK,IAAI,SAAS,8BAA8B;EAEnF,OAAO,KAAK,IAAI,IACf;GACC,KAAK;GACS;GACd,QAAQ;GAIR,SAAS;IAAE,OAAO,KAAK,MAAM;IAAY,SAAS,EAAE,WAAW,IAAU;GAAE;GAC3E,GAAI,SAAS,YAAY,OAAO,EAAE,UAAU,QAAQ,SAAS,IAAI,KAAA;EAClE,GACA,aACA,YACA,WACA,wBACA,gBACA,uBAAuB,qBAAqB,KAAA,GAC5C,GACD;CACD;CAEA,MACM,eACL,UACA,SAGA,cACmB;EACnB,IAAI,YAAY,MAAM,OAAO;EAE7B,MAAM,CAAC,EAAE,QAAQ,YAAY,EAAE,QAAQ,UAAU,MAAM,QAAQ,IAAI,CAClE,KAAK,SAAS,SAAS,YACtB,UACA;GAAE,QAAQ,SAAS,QAAQ;GAAU,MAAM;EAAM,GACjD,YACD,GACA,KAAK,SAAS,KAAK,QAAQ,UAAU;GAAE,QAAQ,SAAS,QAAQ;GAAM,MAAM;EAAM,GAAG,YAAY,CAClG,CAAC;EAED,OAAO,SAAS,WAAW,KAAK,KAAK,WAAW;CACjD;CAEA,MACM,iBACL,UACA,KACA,WACA,cACmB;EACnB,MAAM,OAAO,aAAa,OAAO,SAAS,SAAS,IAAI,KAAA;EACvD,MAAM,eAAe,OAAO,KAAK,SAAS,gBAAgB,MAAM,QAAQ,IAAI,KAAA;EAC5E,OAAO,SACL,MAAM,KAAK,kBAAkB,UAAU,KAAK,EAAgB,aAAa,GAAG,YAAY,EAAA,EAAI,MAC9F;CACD;CAEA,MACM,kBACL,UACA,KACA,SACA,cAC8B;EAC9B,IAAI,CAAC,KAAK,OAAO,KAAA;EACjB,IAAI,QAAA,+CAA4B,cAAc,GAAG,GAAG,OAAO;EAE3D,MAAM,eAAe,SAAS;EAC9B,MAAM,uBAAuB,MAAM,KAAK,IAAI,SAAS,8BAA8B;EAMnF,MAAM,SAAS,gBAAgB,QAAQ,MAAM,GAAG;EAiBhD,QAAO,MAhBc,KAAK,IAAI,IAC7B;GACC,KAAK;GACS;GACd,QAAQ;GACR,SAAS;IACR,OAAO,KAAK,MAAM;IAClB,SAAS,EAAE,WAAW,SAAS,MAAgB,IAAU;IACzD,OAAO,SAAS;GACjB;EACD,GACA,aACA,YACA,uBAAuB,qBAAqB,KAAA,GAC5C,eAAe,GAAG,IAAI,KAAK,iBAAiB,GAAG,IAAI,UACpD,EAAA,CACc,OAAO,KAAK,KAAK,KAAA;CAChC;CAEA,MACM,gBACL,UACA,KACA,SACA,cACgB;EAChB,MAAM,QAAQ,gBAAgB;EAI9B,MAAM,OAAO;GAAC;GAAc;GAAM;GAAc;EAAG;EACnD,IAAI,SAAS,YAAY,MACxB,KAAK,KAAK,QAAQ,QAAQ;EAK3B,IAAI,QAAQ,QACX,MAAM,IAAI,qBAAqB;GAC9B,QAAQ;GACR,QAAQ;GACH;GACL,YAAY;IAAY;IAAgB;GAAK;EAC9C,CAAC;EAKF,MAAM,SAAS,IAAI,WAAW,aAAa,IAAI,IAAI,UAAU,EAAoB,IAAI,KAAA;EACrF,IAAI,UAAU,MAUT;QAAA,MANiB,KAAK,IAAI,IAC7B;IAAE,KAAK;IAAwB;IAAc,QAAQ;GAAQ,GAC7D,YACA,QACA,aACD,EAAA,CACW,OAAO,MAAM,IAAI,CAAC,CAAC,MAAK,MAAK,EAAE,KAAK,MAAM,UAAU,KAAK,GACnE,MAAM,IAAI,qBAAqB;IAC9B,QAAQ;IACR,QAAQ;IACH;IACL,YAAY;KAAY;KAAgB;IAAK;GAC9C,CAAC;EAAA;EAIH,IAAI;GAGH,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAwB;IAAc,QAAQ;GAAQ,GAAG,GAAG,IAAI;EAC3F,SAAS,IAAI;GACZ,OAAO,MAAM,EAAE;GACf,IAAI,oBAAoB,EAAE,GAAG,MAAM;GAEnC,MAAM,mBACL,qBACA,KACA,WACC,IAAI,qBACH;IACS;IACR,QAAQ;IACH;IACL,YAAY;KAAY;KAAgB;IAAK;GAC9C,GACA,EACD,CACF;EACD;EAEA,IAAI,UAAU,MAAM;GACnB,IAAI;IAEH,MAAM,KAAK,IAAI,IACd;KAAE,KAAK;KAAU,QAAQ;IAAS,GAClC,UACA,oBACA,UAAU,QACX;IACA,MAAM,KAAK,SAAS,SAAS,oBAAoB,UAAU,MAAM;GAClE,UAAU;IAIT,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,YAAY,QAAQ;IACnE,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,UAAU,OAAO,GAAG,CAAC,GAAG,GAAG,EACjF,sBAAsB,KACvB,CAAC;GACF;GACA;EACD;EAEA,KAAK,qBAAqB,UAAU,KAAK,KAAK;CAC/C;CAEA,MACM,gBACL,UACA,KACA,KACA,SACA,cACgB;EAChB,MAAM,QAAQ,gBAAgB;EAE9B,MAAM,OAAO;GAAC;GAAc;GAAK;EAAG;EACpC,IAAI,SAAS,YAAY,MAKxB,KAAK,KAAK,QAAQ,aAAa,WAAW,KAAK,QAAQ,QAAQ;EAGhE,IAAI;GACH,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAwB;IAAc,QAAQ;GAAQ,GAAG,GAAG,IAAI;EAC3F,SAAS,IAAI;GACZ,OAAO,MAAM,EAAE;GACf,IAAI,oBAAoB,EAAE,GAAG,MAAM;GAEnC,MAAM,mBACL,cACA,KACA,WACC,IAAI,qBACH;IACS;IACR,QAAQ;IACH;IACL,YAAY;KAAY;KAAgB;IAAK;GAC9C,GACA,EACD,CACF;EACD;EAEA,KAAK,qBAAqB,UAAU,KAAK,IAAI;CAC9C;;;;;CAMA,qBAA6B,UAAkB,KAAa,OAAsB;EACjF,MAAM,OAAO,SAAS,IAAI,SAAS,OAAO,IAAI,KAAA,IAAY,CAAC,GAAG;EAC9D,IAAI,QAAQ,QAAQ;GAGnB,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,YAAY,QAAQ;GACnE,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,QAAQ,OAAO,CAAC;EACxE,OAAO,IAAI,IAAI,WAAW,aAAa,GAAG;GACzC,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,UAAU;GACzD,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,OAAO,GAAG,IAAI;EACtE,OAAO,IAAI,IAAI,WAAW,YAAY,GAAG;GACxC,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,MAAM;GACrD,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,MAAM,GAAG,IAAI;EACrE,OAAO,IAAI,IAAI,WAAW,eAAe,GAAG;GAG3C,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,UAAU;GACzD,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,SAAS,GAAG,IAAI;EACxE,OAAO,IAAI,QAAQ,cAAc;GAChC,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,SAAS;GACxD,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,OAAO,GAAG,IAAI;EACtE;CAKD;AACD;AAtsBE,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,sCAAA,IAAA;AAgBrB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,WAAA,IAAA;AAoFrB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,cAAA,IAAA;AAwErB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,yBAAA,IAAA;AAkHrB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,gBAAA,IAAA;AAqCrB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,oBAAA,IAAA;AAoCrB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,gBAAA,IAAA;AA6CrB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,4BAAA,IAAA;AAgBrB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,qCAAA,IAAA;AA2CrB,WAAA,CAAA,MAAM;CAAE,OAAO;CAAM,OAAM,cAAa,EAAY,SAAS;AAAG,CAAC,CAAA,GAAA,mBAAA,WAAA,kBAAA,IAAA;AAsBjE,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,oBAAA,IAAA;AAcrB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,mBAAA,WAAA,qBAAA,IAAA;AAqCrB,WAAA,CAAA,MAAM,CAAA,GAAA,mBAAA,WAAA,mBAAA,IAAA;AAmGN,WAAA,CAAA,MAAM,CAAA,GAAA,mBAAA,WAAA,mBAAA,IAAA;;AA8ER,eAAe,gBAAgB,UAA4C,SAAwC;CAClH,IAAI;CACJ,IAAI;EACH,IAAI,YAAY,MAAM,OAAO;EAE7B,SAAS,MAAM;CAChB,QAAQ;EACP,OAAO;CACR;CACA,IAAI,OAAO,WAAW,QAAQ,QAAQ,OAAO;CAE7C,MAAM,uBAAO,IAAI,IAAoB;CACrC,KAAK,MAAM,UAAU,QACpB,KAAK,IAAI,OAAO,MAAM,OAAO,UAAU;CAExC,OAAO,QAAQ,OAAM,MAAK,KAAK,IAAI,EAAE,IAAI,MAAM,EAAE,UAAU;AAC5D"}
@@ -8,8 +8,8 @@ import { joinPaths } from "../../utils/path.js";
8
8
  import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
9
9
  import { maxGitCliLength } from "../exec/git.js";
10
10
  import * as l10n from "@vscode/l10n";
11
- import { promises } from "fs";
12
11
  import { tmpdir } from "os";
12
+ import { promises } from "fs";
13
13
  //#region ../git-cli/src/providers/staging.ts
14
14
  var StagingGitSubProvider = class {
15
15
  context;
@@ -7,6 +7,7 @@ import { Cache } from "../../git/cache.js";
7
7
  import { GitOperationRunOptions } from "../../git/providers/operations.js";
8
8
  import { GitStashSubProvider, StashApplyResult } from "../../git/providers/stash.js";
9
9
  import { Git } from "../exec/git.js";
10
+ import { IndexRefresher } from "../exec/indexRefresh.js";
10
11
  import { CliGitProviderInternal } from "../cliGitProvider.js";
11
12
  //#region ../git-cli/src/providers/stash.d.ts
12
13
  export declare class StashGitSubProvider implements GitStashSubProvider {
@@ -14,7 +15,8 @@ export declare class StashGitSubProvider implements GitStashSubProvider {
14
15
  private readonly git;
15
16
  private readonly cache;
16
17
  private readonly provider;
17
- constructor(context: GitServiceContext, git: Git, cache: Cache, provider: CliGitProviderInternal);
18
+ private readonly indexRefresher?;
19
+ constructor(context: GitServiceContext, git: Git, cache: Cache, provider: CliGitProviderInternal, indexRefresher?: IndexRefresher | undefined);
18
20
  applyStash(repoPath: string, stashNameOrSha: string, options?: {
19
21
  deleteAfter?: boolean;
20
22
  index?: boolean;
@@ -9,6 +9,7 @@ import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate
9
9
  import { StashApplyError, StashPushError } from "../../git/errors.js";
10
10
  import { gitFeaturesByVersion } from "../../git/features.js";
11
11
  import { GitError, GitErrors, getGitCommandError, isRunHookFailure } from "../exec/git.js";
12
+ import { refreshIndexAfter } from "../exec/indexRefresh.js";
12
13
  import { GitFileWorkingTreeStatus } from "../../git/models/fileStatus.js";
13
14
  import { GitFileChange } from "../../git/models/fileChange.js";
14
15
  import { GitCommit, GitCommitIdentity } from "../../git/models/commit.js";
@@ -24,11 +25,13 @@ var StashGitSubProvider = class {
24
25
  git;
25
26
  cache;
26
27
  provider;
27
- constructor(context, git, cache, provider) {
28
+ indexRefresher;
29
+ constructor(context, git, cache, provider, indexRefresher) {
28
30
  this.context = context;
29
31
  this.git = git;
30
32
  this.cache = cache;
31
33
  this.provider = provider;
34
+ this.indexRefresher = indexRefresher;
32
35
  }
33
36
  async applyStash(repoPath, stashNameOrSha, options, runOptions) {
34
37
  if (!stashNameOrSha) return { conflicted: false };
@@ -40,10 +43,10 @@ var StashGitSubProvider = class {
40
43
  async applyStashCore(repoPath, args, conflictCommand, runOptions) {
41
44
  let dropped = false;
42
45
  try {
43
- await this.git.run({
46
+ await refreshIndexAfter(this.indexRefresher, repoPath, () => this.git.run({
44
47
  cwd: repoPath,
45
48
  ...runOptions
46
- }, ...args);
49
+ }, ...args));
47
50
  dropped = conflictCommand === "stash-pop";
48
51
  return { conflicted: false };
49
52
  } catch (ex) {
@@ -214,11 +217,11 @@ var StashGitSubProvider = class {
214
217
  } else params.push("--");
215
218
  let nothingToSave = false;
216
219
  try {
217
- const result = await this.git.run({
220
+ const result = await refreshIndexAfter(this.indexRefresher, repoPath, () => this.git.run({
218
221
  cwd: repoPath,
219
222
  ...runOptions,
220
223
  stdin
221
- }, ...params);
224
+ }, ...params));
222
225
  if (GitErrors.stashNothingToSave.test(result.stdout)) {
223
226
  nothingToSave = true;
224
227
  throw new StashPushError({