@gitkraken/core-gitlens 0.13.0 → 0.14.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.
- package/CHANGELOG.md +23 -2
- package/dist/git/features.d.ts +1 -1
- package/dist/git/features.js +1 -0
- package/dist/git/features.js.map +1 -1
- package/dist/git/models/branch.d.ts +5 -0
- package/dist/git/models/branch.js +1 -1
- package/dist/git/models/branch.js.map +1 -1
- package/dist/git/models/reference.d.ts +3 -0
- package/dist/git/models/status.js +1 -1
- package/dist/git/parsers/diffParser.js +1 -1
- package/dist/git/providers/operations.d.ts +3 -2
- package/dist/git/providers/provider.d.ts +15 -4
- package/dist/git/providers/revision.d.ts +17 -3
- package/dist/git/run.types.d.ts +12 -0
- package/dist/git/utils/branch.utils.d.ts +4 -1
- package/dist/git/utils/branch.utils.js +20 -5
- package/dist/git/utils/branch.utils.js.map +1 -1
- package/dist/git/utils/reference.utils.d.ts +1 -0
- package/dist/git/utils/reference.utils.js.map +1 -1
- package/dist/git-cli/cliGitProvider.d.ts +8 -2
- package/dist/git-cli/cliGitProvider.js +75 -13
- package/dist/git-cli/cliGitProvider.js.map +1 -1
- package/dist/git-cli/exec/git.d.ts +5 -0
- package/dist/git-cli/exec/git.js +28 -5
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/exec/indexLock.d.ts +3 -2
- package/dist/git-cli/exec/indexLock.js +16 -6
- package/dist/git-cli/exec/indexLock.js.map +1 -1
- package/dist/git-cli/parsers/blameParser.js +2 -2
- package/dist/git-cli/parsers/refParser.js +4 -2
- package/dist/git-cli/parsers/refParser.js.map +1 -1
- package/dist/git-cli/parsers/statusParser.d.ts +6 -0
- package/dist/git-cli/parsers/statusParser.js +33 -3
- package/dist/git-cli/parsers/statusParser.js.map +1 -1
- package/dist/git-cli/providers/branchRemote.d.ts +14 -0
- package/dist/git-cli/providers/branchRemote.js +36 -0
- package/dist/git-cli/providers/branchRemote.js.map +1 -0
- package/dist/git-cli/providers/branches.js +6 -3
- package/dist/git-cli/providers/branches.js.map +1 -1
- package/dist/git-cli/providers/commits.js +2 -2
- package/dist/git-cli/providers/config.js +2 -2
- package/dist/git-cli/providers/contributors.js +1 -1
- package/dist/git-cli/providers/graph.js +9 -6
- package/dist/git-cli/providers/graph.js.map +1 -1
- package/dist/git-cli/providers/operations.js +20 -16
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/pausedOperations.js +2 -2
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/revision.d.ts +6 -2
- package/dist/git-cli/providers/revision.js +38 -12
- package/dist/git-cli/providers/revision.js.map +1 -1
- package/dist/git-cli/providers/staging.js +1 -1
- package/dist/git-cli/providers/status.js +2 -2
- package/dist/ipc/discovery.js +1 -1
- package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
- package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -1
- package/dist/plus/git-github/providers/github/revision.d.ts +6 -2
- package/dist/plus/git-github/providers/github/revision.js +15 -10
- package/dist/plus/git-github/providers/github/revision.js.map +1 -1
- package/dist/plus/git-github/providers/github/status.js +1 -1
- package/dist/plus/integrations/providers/azure/azure.js +1 -1
- package/dist/plus/integrations/providers/azure/workItemStateCategories.d.ts +5 -0
- package/dist/plus/integrations/providers/azure/workItemStateCategories.js +5 -0
- package/dist/plus/integrations/providers/azure/workItemStateCategories.js.map +1 -1
- package/dist/utils/env/node/exec.js +2 -2
- 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()\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()\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":"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"}
|
|
1
|
+
{"version":3,"file":"pausedOperations.js","names":[],"sources":["../../../../git-cli/src/providers/pausedOperations.ts"],"sourcesContent":["import { readdir } from 'fs';\nimport { readFile, stat } from 'fs/promises';\nimport * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { PausedOperationAbortError, PausedOperationContinueError } from '@gitlens/git/errors.js';\nimport type {\n\tGitCherryPickStatus,\n\tGitMergeStatus,\n\tGitPausedOperationStatus,\n\tGitRebaseStatus,\n\tGitRevertStatus,\n} from '@gitlens/git/models/pausedOperationStatus.js';\nimport type { GitBranchReference, GitTagReference } from '@gitlens/git/models/reference.js';\nimport type { GitDir } from '@gitlens/git/models/repository.js';\nimport type { GitPausedOperationsSubProvider } from '@gitlens/git/providers/pausedOperations.js';\nimport { createReference } from '@gitlens/git/utils/reference.utils.js';\nimport { CancellationError } from '@gitlens/utils/cancellation.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { joinPaths } from '@gitlens/utils/path.js';\nimport { getSettledValue } from '@gitlens/utils/promise.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { Git } from '../exec/git.js';\nimport { getGitCommandError } from '../exec/git.js';\n\nconst todoCommitRegex = /^(?:p(?:ick)?|revert)\\s+([a-f0-9]+)(?:\\s+(.+))?$/i;\n\ntype Operation = 'cherry-pick' | 'merge' | 'rebase-apply' | 'rebase-merge' | 'revert' | 'sequencer';\n\n// Note: 'sequencer' is checked after specific HEAD files since those take precedence\n// The sequencer directory is used for multi-commit cherry-picks/reverts\nconst orderedOperations: Operation[] = ['rebase-apply', 'rebase-merge', 'merge', 'cherry-pick', 'revert', 'sequencer'];\n\nexport class PausedOperationsGitSubProvider implements GitPausedOperationsSubProvider {\n\tconstructor(\n\t\tprivate readonly context: GitServiceContext,\n\t\tprivate readonly git: Git,\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: CliGitProviderInternal,\n\t) {}\n\n\t/**\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()\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()\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":"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"}
|
|
@@ -20,8 +20,12 @@ export declare class RevisionGitSubProvider implements GitRevisionSubProvider {
|
|
|
20
20
|
getRevisionContent(repoPath: string, path: string, rev: string): Promise<Uint8Array | undefined>;
|
|
21
21
|
getSubmoduleHead(repoPath: string, submodulePath: string): Promise<string | undefined>;
|
|
22
22
|
getTreeEntryForRevision(repoPath: string, path: string, rev: string): Promise<GitTreeEntry | undefined>;
|
|
23
|
-
getTrackedFiles(repoPath: string
|
|
24
|
-
|
|
23
|
+
getTrackedFiles(repoPath: string, options?: {
|
|
24
|
+
paths?: readonly string[];
|
|
25
|
+
}, cancellation?: AbortSignal): Promise<string[]>;
|
|
26
|
+
getTreeForRevision(repoPath: string, rev: string, options?: {
|
|
27
|
+
paths?: readonly string[];
|
|
28
|
+
}): Promise<GitTreeEntry[]>;
|
|
25
29
|
private getTreeForRevisionCore;
|
|
26
30
|
private showContentCore;
|
|
27
31
|
resolveShas(repoPath: string, shas: ReadonlySet<string>, cancellation?: AbortSignal): Promise<Set<string>>;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { first } from "../../utils/iterable.js";
|
|
2
|
+
import { CancellationError } from "../../utils/cancellation.js";
|
|
3
|
+
import { iterateByDelimiter } from "../../utils/string.js";
|
|
2
4
|
import { debug } from "../../utils/decorators/log.js";
|
|
3
5
|
import { toFsPath } from "../../utils/uri.js";
|
|
4
6
|
import { splitPath } from "../../utils/path.js";
|
|
@@ -6,7 +8,7 @@ import "../../git/models/revision.js";
|
|
|
6
8
|
import { isRevisionWithSuffix, isSha, isUncommitted, isUncommittedStaged, isUncommittedWithParentSuffix } from "../../git/utils/revision.utils.js";
|
|
7
9
|
import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
|
|
8
10
|
import { ShowError } from "../../git/errors.js";
|
|
9
|
-
import { GitErrors, defaultExceptionHandler, getGitCommandError, gitConfigsLog } from "../exec/git.js";
|
|
11
|
+
import { GitErrors, batchLiteralPathspecs, defaultExceptionHandler, getGitCommandError, gitConfigsLog } from "../exec/git.js";
|
|
10
12
|
import { getShaAndFileSummaryLogParser } from "../parsers/logParser.js";
|
|
11
13
|
import { gate } from "../../utils/decorators/gate.js";
|
|
12
14
|
import { parseGitLsFilesStaged } from "../parsers/indexParser.js";
|
|
@@ -94,19 +96,42 @@ var RevisionGitSubProvider = class {
|
|
|
94
96
|
const [entry] = await this.getTreeForRevisionCore(repoPath, rev, path);
|
|
95
97
|
return entry;
|
|
96
98
|
}
|
|
97
|
-
async getTrackedFiles(repoPath) {
|
|
99
|
+
async getTrackedFiles(repoPath, options, cancellation) {
|
|
98
100
|
if (!repoPath) return [];
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
const paths = options?.paths;
|
|
102
|
+
if (paths != null && !paths.length) return [];
|
|
103
|
+
const prefix = ["ls-files", "-z"];
|
|
104
|
+
const batches = paths != null ? batchLiteralPathspecs(paths, prefix) : [void 0];
|
|
105
|
+
const files = /* @__PURE__ */ new Set();
|
|
106
|
+
for (const batch of batches) {
|
|
107
|
+
const result = await this.git.run({
|
|
108
|
+
cwd: repoPath,
|
|
109
|
+
errors: "ignore",
|
|
110
|
+
cancellation
|
|
111
|
+
}, ...prefix, ...batch != null ? ["--", ...batch] : []);
|
|
112
|
+
if (result.completion.status === "cancelled" || cancellation?.aborted) throw new CancellationError();
|
|
113
|
+
for (const file of iterateByDelimiter(result.stdout, "\0")) if (file) files.add(file);
|
|
114
|
+
}
|
|
115
|
+
return [...files];
|
|
105
116
|
}
|
|
106
|
-
async getTreeForRevision(repoPath, rev) {
|
|
107
|
-
|
|
117
|
+
async getTreeForRevision(repoPath, rev, options) {
|
|
118
|
+
if (!repoPath) return [];
|
|
119
|
+
const paths = options?.paths;
|
|
120
|
+
if (paths == null) return this.getTreeForRevisionCore(repoPath, rev);
|
|
121
|
+
if (!paths.length) return [];
|
|
122
|
+
const seen = /* @__PURE__ */ new Set();
|
|
123
|
+
const entries = [];
|
|
124
|
+
for (const batch of batchLiteralPathspecs(paths, [
|
|
125
|
+
"ls-tree",
|
|
126
|
+
"-lrt",
|
|
127
|
+
rev
|
|
128
|
+
])) for (const entry of await this.getTreeForRevisionCore(repoPath, rev, void 0, batch)) if (!seen.has(entry.path)) {
|
|
129
|
+
seen.add(entry.path);
|
|
130
|
+
entries.push(entry);
|
|
131
|
+
}
|
|
132
|
+
return entries;
|
|
108
133
|
}
|
|
109
|
-
async getTreeForRevisionCore(repoPath, rev, path) {
|
|
134
|
+
async getTreeForRevisionCore(repoPath, rev, path, pathspecs) {
|
|
110
135
|
const hasPath = Boolean(path);
|
|
111
136
|
const args = hasPath ? [
|
|
112
137
|
"ls-tree",
|
|
@@ -118,7 +143,8 @@ var RevisionGitSubProvider = class {
|
|
|
118
143
|
"ls-tree",
|
|
119
144
|
"-lrt",
|
|
120
145
|
rev,
|
|
121
|
-
"--"
|
|
146
|
+
"--",
|
|
147
|
+
...pathspecs ?? []
|
|
122
148
|
];
|
|
123
149
|
const data = (await this.git.run({
|
|
124
150
|
cwd: repoPath,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revision.js","names":[],"sources":["../../../../git-cli/src/providers/revision.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { ShowError } from '@gitlens/git/errors.js';\nimport type { GitFileStatus } from '@gitlens/git/models/fileStatus.js';\nimport { deletedOrMissing } from '@gitlens/git/models/revision.js';\nimport type { GitTreeEntry } from '@gitlens/git/models/tree.js';\nimport type { GitRevisionSubProvider, ResolvedRevision } from '@gitlens/git/providers/revision.js';\nimport {\n\tisRevisionWithSuffix,\n\tisSha,\n\tisUncommitted,\n\tisUncommittedStaged,\n\tisUncommittedWithParentSuffix,\n} from '@gitlens/git/utils/revision.utils.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { first } from '@gitlens/utils/iterable.js';\nimport { splitPath } from '@gitlens/utils/path.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitErrorHandling, GitRunOptions } from '../exec/exec.types.js';\nimport type { Git } from '../exec/git.js';\nimport { defaultExceptionHandler, getGitCommandError, gitConfigsLog, GitErrors } from '../exec/git.js';\nimport { parseGitLsFilesStaged } from '../parsers/indexParser.js';\nimport { getShaAndFileSummaryLogParser } from '../parsers/logParser.js';\nimport { parseGitTree } from '../parsers/treeParser.js';\n\nconst emptyArray: readonly GitTreeEntry[] = Object.freeze([]);\n\nexport class RevisionGitSubProvider implements GitRevisionSubProvider {\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\texists(\n\t\trepoPath: string,\n\t\tpath: string,\n\t\trevOrOptions?: string | { untracked?: 'only' | 'include' },\n\t): Promise<boolean> {\n\t\tlet rev: string | undefined;\n\t\tlet untracked: 'only' | 'include' | undefined;\n\t\tif (typeof revOrOptions === 'string') {\n\t\t\trev = revOrOptions;\n\t\t} else if (revOrOptions != null) {\n\t\t\tuntracked = revOrOptions.untracked;\n\t\t}\n\n\t\tconst cacheKey = `${path}\\0${rev ?? ''}\\0${untracked ?? ''}`;\n\t\treturn this.cache.fileExistence.getOrCreate(repoPath, cacheKey, async () => {\n\t\t\tconst args = ['ls-files'];\n\t\t\tif (rev) {\n\t\t\t\tif (!isUncommitted(rev)) {\n\t\t\t\t\targs.push(`--with-tree=${rev}`);\n\t\t\t\t} else if (isUncommittedStaged(rev)) {\n\t\t\t\t\targs.push('--stage');\n\t\t\t\t}\n\t\t\t} else if (untracked === 'only') {\n\t\t\t\targs.push('-o');\n\t\t\t} else if (untracked === 'include') {\n\t\t\t\t// Tracked (cached) OR untracked (others)\n\t\t\t\targs.push('-c', '-o');\n\t\t\t}\n\n\t\t\tconst result = await this.git.run({ cwd: repoPath, errors: 'ignore' }, ...args, '--', path);\n\t\t\treturn Boolean(result.stdout.trim());\n\t\t});\n\t}\n\n\t/** `hash-object` without `-w` computes the id in the repository's format without storing anything */\n\t@debug()\n\tgetEmptyTreeSha(repoPath: string): Promise<string> {\n\t\treturn this.cache.getEmptyTreeSha(repoPath, async () => {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, stdin: '', errors: 'throw' },\n\t\t\t\t'hash-object',\n\t\t\t\t'-t',\n\t\t\t\t'tree',\n\t\t\t\t'--stdin',\n\t\t\t);\n\t\t\treturn result.stdout.trim();\n\t\t});\n\t}\n\n\t@gate()\n\t@debug()\n\tgetRevisionContent(repoPath: string, path: string, rev: string): Promise<Uint8Array | undefined> {\n\t\tconst [relativePath, root] = splitPath(path, repoPath);\n\t\treturn this.showContentCore<Buffer>(root, relativePath, rev, { encoding: 'buffer', errors: 'throw' });\n\t}\n\n\t@debug()\n\tasync getSubmoduleHead(repoPath: string, submodulePath: string): Promise<string | undefined> {\n\t\t// Verify the path is a submodule (gitlink commit) in the parent tree, not just a regular directory\n\t\tconst treeEntry = await this.getTreeEntryForRevision(repoPath, submodulePath, 'HEAD');\n\t\tif (treeEntry?.type !== 'commit') return undefined;\n\n\t\tconst [relativePath, root] = splitPath(submodulePath, repoPath);\n\t\tconst submoduleFullPath = this.provider.getAbsoluteUri(relativePath, root).fsPath;\n\n\t\tconst result = await this.git.run({ cwd: submoduleFullPath, errors: 'ignore' }, 'rev-parse', 'HEAD');\n\t\tconst sha = result.stdout.trim();\n\t\treturn sha || undefined;\n\t}\n\n\t@gate()\n\t@debug()\n\tasync getTreeEntryForRevision(repoPath: string, path: string, rev: string): Promise<GitTreeEntry | undefined> {\n\t\tif (!repoPath || !path) return undefined;\n\n\t\tconst [relativePath, root] = splitPath(path, repoPath);\n\n\t\tif (isUncommittedStaged(rev)) {\n\t\t\tlet result = await this.git.run(\n\t\t\t\t{ cwd: root, errors: 'ignore' },\n\t\t\t\t'ls-files',\n\t\t\t\t'-z',\n\t\t\t\t'--stage',\n\t\t\t\t'--',\n\t\t\t\trelativePath,\n\t\t\t);\n\n\t\t\tconst entries = parseGitLsFilesStaged(result.stdout, true);\n\t\t\tif (entries.length === 0) return undefined;\n\n\t\t\tconst entry = entries[0];\n\t\t\tresult = await this.git.run({ cwd: root }, 'cat-file', '-s', entry.oid);\n\t\t\tconst size = parseInt(result.stdout.trim(), 10) || 0;\n\n\t\t\treturn { ref: rev, oid: entry.oid, path: relativePath, size: size, type: 'blob' };\n\t\t}\n\n\t\tconst [entry] = await this.getTreeForRevisionCore(repoPath, rev, path);\n\t\treturn entry;\n\t}\n\n\t@debug()\n\tasync getTrackedFiles(repoPath: string): Promise<string[]> {\n\t\tif (!repoPath) return [];\n\n\t\tconst result = await this.git.run({ cwd: repoPath, errors: 'ignore' }, 'ls-files', '-z');\n\t\tconst data = result.stdout;\n\t\tif (!data) return [];\n\n\t\treturn [...new Set(data.split('\\0').filter(Boolean))];\n\t}\n\n\t@debug()\n\tasync getTreeForRevision(repoPath: string, rev: string): Promise<GitTreeEntry[]> {\n\t\treturn repoPath ? this.getTreeForRevisionCore(repoPath, rev) : [];\n\t}\n\n\t@gate()\n\tprivate async getTreeForRevisionCore(repoPath: string, rev: string, path?: string): Promise<GitTreeEntry[]> {\n\t\tconst hasPath = Boolean(path);\n\t\tconst args = hasPath ? ['ls-tree', '-l', rev, '--', path] : ['ls-tree', '-lrt', rev, '--'];\n\t\tconst result = await this.git.run({ cwd: repoPath, errors: 'ignore' }, ...args);\n\t\tconst data = result.stdout.trim();\n\t\tif (!data) return emptyArray as GitTreeEntry[];\n\n\t\treturn parseGitTree(data, rev, hasPath);\n\t}\n\n\tprivate async showContentCore<T extends string | Buffer>(\n\t\trepoPath: string | undefined,\n\t\tpath: string,\n\t\trev: string,\n\t\toptions?: {\n\t\t\tencoding?: string;\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t): Promise<T | undefined> {\n\t\tconst [file, root] = splitPath(path, repoPath, true);\n\n\t\tif (isUncommittedStaged(rev)) {\n\t\t\trev = ':';\n\t\t}\n\t\tif (isUncommitted(rev)) throw new Error(`ref=${rev} is uncommitted`);\n\n\t\tconst opts: GitRunOptions = {\n\t\t\tconfigs: gitConfigsLog,\n\t\t\tcwd: root,\n\t\t\tencoding: options?.encoding ?? 'utf8',\n\t\t\terrors: 'throw',\n\t\t};\n\t\tconst args = rev.endsWith(':') ? `${rev}./${file}` : `${rev}:./${file}`;\n\t\tconst params = ['show', '--textconv', args, '--'];\n\n\t\ttry {\n\t\t\tconst result = await this.git.run<T>(opts, ...params);\n\t\t\treturn result.stdout;\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif (rev === ':' && GitErrors.badRevision.test(msg)) {\n\t\t\t\treturn this.showContentCore<T>(repoPath, path, 'HEAD:', options);\n\t\t\t}\n\n\t\t\tconst error = getGitCommandError(\n\t\t\t\t'show',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew ShowError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason ?? 'other',\n\t\t\t\t\t\t\trev: rev,\n\t\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath ?? '', args: params },\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\tif (options?.errors === 'throw') throw error;\n\n\t\t\tif (\n\t\t\t\tShowError.is(error, 'invalidObject') ||\n\t\t\t\tShowError.is(error, 'invalidRevision') ||\n\t\t\t\tShowError.is(error, 'notFound') ||\n\t\t\t\tShowError.is(error, 'notInRevision')\n\t\t\t) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tdefaultExceptionHandler(ex, opts.cwd);\n\t\t\treturn '' as T;\n\t\t}\n\t}\n\n\t@debug({ args: (repoPath, shas) => ({ repoPath: repoPath, shas: `${shas.size} value(s)` }) })\n\tasync resolveShas(repoPath: string, shas: ReadonlySet<string>, cancellation?: AbortSignal): Promise<Set<string>> {\n\t\tconst resolved = new Set<string>();\n\t\tconst prefixes: string[] = [];\n\n\t\tfor (const value of shas) {\n\t\t\t// Pure hex 4-40 chars: resolve to full commit SHA(s) via disambiguation. Everything else\n\t\t\t// (refs, suffixed SHAs like `^`/`~1`/`:path`, non-hex, <4 hex) passes through unchanged.\n\t\t\tif (/^[0-9a-f]{4,40}$/i.test(value)) {\n\t\t\t\tprefixes.push(value);\n\t\t\t} else {\n\t\t\t\tresolved.add(value);\n\t\t\t}\n\t\t}\n\n\t\tif (prefixes.length) {\n\t\t\t// List every object (any type) whose id starts with any prefix (empty + exit 0 if none)\n\t\t\tconst rp = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t'rev-parse',\n\t\t\t\t...prefixes.map(p => `--disambiguate=${p}`),\n\t\t\t);\n\t\t\tconst oids = rp.stdout.split('\\n').filter(Boolean);\n\t\t\tif (oids.length) {\n\t\t\t\t// `--disambiguate` has no type filter, so keep only commit objects\n\t\t\t\tconst cf = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore', stdin: `${oids.join('\\n')}\\n` },\n\t\t\t\t\t'cat-file',\n\t\t\t\t\t'--batch-check=%(objectname) %(objecttype)',\n\t\t\t\t);\n\t\t\t\tfor (const line of cf.stdout.split('\\n')) {\n\t\t\t\t\tconst [oid, type] = line.split(' ');\n\t\t\t\t\tif (type === 'commit') {\n\t\t\t\t\t\tresolved.add(oid);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\t@debug()\n\tasync resolveRevision(\n\t\trepoPath: string,\n\t\tref: string,\n\t\tpathOrUri?: string | Uri,\n\t\toptions?: { force?: boolean },\n\t): Promise<ResolvedRevision> {\n\t\tconst path = pathOrUri != null ? toFsPath(pathOrUri) : undefined;\n\t\tif (!ref || ref === deletedOrMissing) return { sha: ref, revision: ref };\n\n\t\tif (path == null) {\n\t\t\tif (isSha(ref)) return { sha: ref, revision: ref };\n\t\t\tif (ref.endsWith('^3')) return { sha: ref, revision: ref };\n\t\t} else if (isUncommitted(ref)) {\n\t\t\t// Uncommitted refs depend on index/working-tree state — resolve without caching\n\t\t\treturn this.resolveRevisionCore(repoPath, ref, path);\n\t\t}\n\n\t\tconst key = path != null ? `${ref}|${this.provider.getRelativePath(path, repoPath)}` : ref;\n\t\tif (options?.force) {\n\t\t\t// Hard-delete first: a later caller must never join a read that started before this one.\n\t\t\tthis.cache.resolvedRevisions.delete(repoPath, key);\n\t\t}\n\n\t\treturn this.cache.resolvedRevisions.getOrCreate(repoPath, key, () =>\n\t\t\tthis.resolveRevisionCore(repoPath, ref, path, options?.force),\n\t\t);\n\t}\n\n\tprivate async resolveRevisionCore(\n\t\trepoPath: string,\n\t\tref: string,\n\t\tpath: string | undefined,\n\t\tforce?: boolean,\n\t): Promise<ResolvedRevision> {\n\t\tif (path == null) {\n\t\t\tconst sha = await this.provider.refs.validateReference(repoPath, ref, force ? { force: true } : undefined);\n\t\t\tif (sha == null) return { sha: ref, revision: ref };\n\n\t\t\treturn {\n\t\t\t\tsha: sha,\n\t\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\t\trevision: isRevisionWithSuffix(ref) ? sha : ref,\n\t\t\t};\n\t\t}\n\n\t\tif (isUncommittedWithParentSuffix(ref)) {\n\t\t\tref = 'HEAD';\n\t\t}\n\t\tconst relativePath = this.provider.getRelativePath(path, repoPath);\n\n\t\tif (isUncommitted(ref)) {\n\t\t\tif (!isUncommittedStaged(ref)) {\n\t\t\t\treturn { sha: ref, revision: ref };\n\t\t\t}\n\n\t\t\t// Ensure that the file is actually staged\n\t\t\tconst status = await this.provider.status.getStatusForFile?.(repoPath, relativePath, { renames: false });\n\t\t\tif (status?.indexStatus) return { sha: ref, revision: ref };\n\n\t\t\tref = 'HEAD';\n\t\t}\n\n\t\tconst resolvedRevisionCaching = { cache: this.cache.gitResults, options: { accessTTL: 5 * 60 * 1000 } };\n\n\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\tlet result = await this.git.run(\n\t\t\t// Forced here only: this read is keyed by `ref`, which can move; the follow-up below is keyed by a sha\n\t\t\t{ cwd: repoPath, errors: 'ignore', caching: { ...resolvedRevisionCaching, force: force } },\n\t\t\t'log',\n\t\t\t...parser.arguments,\n\t\t\t'-n1',\n\t\t\tref,\n\t\t\t'--',\n\t\t\trelativePath,\n\t\t);\n\n\t\tlet commit = first(parser.parse(result.stdout));\n\t\tlet file = commit?.files.find(f => f.path === relativePath);\n\t\tif (file == null) {\n\t\t\treturn {\n\t\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\t};\n\t\t}\n\n\t\tif (file.status === 'A') {\n\t\t\treturn {\n\t\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\t\tstatus: file.status as GitFileStatus,\n\t\t\t\toriginalPath: file.originalPath,\n\t\t\t};\n\t\t}\n\n\t\tif (file.status === 'D') {\n\t\t\t// If the file was deleted, check if it was moved or renamed\n\t\t\tresult = await this.git.run(\n\t\t\t\t{ cwd: repoPath, errors: 'ignore', caching: resolvedRevisionCaching },\n\t\t\t\t'log',\n\t\t\t\t...parser.arguments,\n\t\t\t\t'-n1',\n\n\t\t\t\tcommit!.sha,\n\t\t\t\t'--',\n\t\t\t);\n\n\t\t\tcommit = first(parser.parse(result.stdout));\n\t\t\tfile = commit?.files.find(f => f.path === relativePath || f.originalPath === relativePath);\n\t\t\tif (file == null) {\n\t\t\t\treturn {\n\t\t\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t\t// If it looks like non-sha like without a suffix then preserve it as the friendly name\n\t\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\t\tstatus: file.status as GitFileStatus,\n\t\t\t\tpath: file.path,\n\t\t\t\toriginalPath: file.originalPath,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\tstatus: file.status as GitFileStatus,\n\t\t\toriginalPath: file.originalPath,\n\t\t};\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"revision.js","names":[],"sources":["../../../../git-cli/src/providers/revision.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { ShowError } from '@gitlens/git/errors.js';\nimport type { GitFileStatus } from '@gitlens/git/models/fileStatus.js';\nimport { deletedOrMissing } from '@gitlens/git/models/revision.js';\nimport type { GitTreeEntry } from '@gitlens/git/models/tree.js';\nimport type { GitRevisionSubProvider, ResolvedRevision } from '@gitlens/git/providers/revision.js';\nimport {\n\tisRevisionWithSuffix,\n\tisSha,\n\tisUncommitted,\n\tisUncommittedStaged,\n\tisUncommittedWithParentSuffix,\n} from '@gitlens/git/utils/revision.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 { first } from '@gitlens/utils/iterable.js';\nimport { splitPath } from '@gitlens/utils/path.js';\nimport { iterateByDelimiter } 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 { GitErrorHandling, GitRunOptions } from '../exec/exec.types.js';\nimport type { Git } from '../exec/git.js';\nimport {\n\tbatchLiteralPathspecs,\n\tdefaultExceptionHandler,\n\tgetGitCommandError,\n\tgitConfigsLog,\n\tGitErrors,\n} from '../exec/git.js';\nimport { parseGitLsFilesStaged } from '../parsers/indexParser.js';\nimport { getShaAndFileSummaryLogParser } from '../parsers/logParser.js';\nimport { parseGitTree } from '../parsers/treeParser.js';\n\nconst emptyArray: readonly GitTreeEntry[] = Object.freeze([]);\n\nexport class RevisionGitSubProvider implements GitRevisionSubProvider {\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\texists(\n\t\trepoPath: string,\n\t\tpath: string,\n\t\trevOrOptions?: string | { untracked?: 'only' | 'include' },\n\t): Promise<boolean> {\n\t\tlet rev: string | undefined;\n\t\tlet untracked: 'only' | 'include' | undefined;\n\t\tif (typeof revOrOptions === 'string') {\n\t\t\trev = revOrOptions;\n\t\t} else if (revOrOptions != null) {\n\t\t\tuntracked = revOrOptions.untracked;\n\t\t}\n\n\t\tconst cacheKey = `${path}\\0${rev ?? ''}\\0${untracked ?? ''}`;\n\t\treturn this.cache.fileExistence.getOrCreate(repoPath, cacheKey, async () => {\n\t\t\tconst args = ['ls-files'];\n\t\t\tif (rev) {\n\t\t\t\tif (!isUncommitted(rev)) {\n\t\t\t\t\targs.push(`--with-tree=${rev}`);\n\t\t\t\t} else if (isUncommittedStaged(rev)) {\n\t\t\t\t\targs.push('--stage');\n\t\t\t\t}\n\t\t\t} else if (untracked === 'only') {\n\t\t\t\targs.push('-o');\n\t\t\t} else if (untracked === 'include') {\n\t\t\t\t// Tracked (cached) OR untracked (others)\n\t\t\t\targs.push('-c', '-o');\n\t\t\t}\n\n\t\t\tconst result = await this.git.run({ cwd: repoPath, errors: 'ignore' }, ...args, '--', path);\n\t\t\treturn Boolean(result.stdout.trim());\n\t\t});\n\t}\n\n\t/** `hash-object` without `-w` computes the id in the repository's format without storing anything */\n\t@debug()\n\tgetEmptyTreeSha(repoPath: string): Promise<string> {\n\t\treturn this.cache.getEmptyTreeSha(repoPath, async () => {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, stdin: '', errors: 'throw' },\n\t\t\t\t'hash-object',\n\t\t\t\t'-t',\n\t\t\t\t'tree',\n\t\t\t\t'--stdin',\n\t\t\t);\n\t\t\treturn result.stdout.trim();\n\t\t});\n\t}\n\n\t@gate()\n\t@debug()\n\tgetRevisionContent(repoPath: string, path: string, rev: string): Promise<Uint8Array | undefined> {\n\t\tconst [relativePath, root] = splitPath(path, repoPath);\n\t\treturn this.showContentCore<Buffer>(root, relativePath, rev, { encoding: 'buffer', errors: 'throw' });\n\t}\n\n\t@debug()\n\tasync getSubmoduleHead(repoPath: string, submodulePath: string): Promise<string | undefined> {\n\t\t// Verify the path is a submodule (gitlink commit) in the parent tree, not just a regular directory\n\t\tconst treeEntry = await this.getTreeEntryForRevision(repoPath, submodulePath, 'HEAD');\n\t\tif (treeEntry?.type !== 'commit') return undefined;\n\n\t\tconst [relativePath, root] = splitPath(submodulePath, repoPath);\n\t\tconst submoduleFullPath = this.provider.getAbsoluteUri(relativePath, root).fsPath;\n\n\t\tconst result = await this.git.run({ cwd: submoduleFullPath, errors: 'ignore' }, 'rev-parse', 'HEAD');\n\t\tconst sha = result.stdout.trim();\n\t\treturn sha || undefined;\n\t}\n\n\t@gate()\n\t@debug()\n\tasync getTreeEntryForRevision(repoPath: string, path: string, rev: string): Promise<GitTreeEntry | undefined> {\n\t\tif (!repoPath || !path) return undefined;\n\n\t\tconst [relativePath, root] = splitPath(path, repoPath);\n\n\t\tif (isUncommittedStaged(rev)) {\n\t\t\tlet result = await this.git.run(\n\t\t\t\t{ cwd: root, errors: 'ignore' },\n\t\t\t\t'ls-files',\n\t\t\t\t'-z',\n\t\t\t\t'--stage',\n\t\t\t\t'--',\n\t\t\t\trelativePath,\n\t\t\t);\n\n\t\t\tconst entries = parseGitLsFilesStaged(result.stdout, true);\n\t\t\tif (entries.length === 0) return undefined;\n\n\t\t\tconst entry = entries[0];\n\t\t\tresult = await this.git.run({ cwd: root }, 'cat-file', '-s', entry.oid);\n\t\t\tconst size = parseInt(result.stdout.trim(), 10) || 0;\n\n\t\t\treturn { ref: rev, oid: entry.oid, path: relativePath, size: size, type: 'blob' };\n\t\t}\n\n\t\tconst [entry] = await this.getTreeForRevisionCore(repoPath, rev, path);\n\t\treturn entry;\n\t}\n\n\t@debug()\n\tasync getTrackedFiles(\n\t\trepoPath: string,\n\t\toptions?: { paths?: readonly string[] },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string[]> {\n\t\tif (!repoPath) return [];\n\n\t\tconst paths = options?.paths;\n\t\t// No pathspec means \"everything\" to git, which is not what an empty list asks for\n\t\tif (paths != null && !paths.length) return [];\n\n\t\tconst prefix = ['ls-files', '-z'];\n\t\t// A single run when unscoped, otherwise batched to stay under the command-line length limit\n\t\tconst batches = paths != null ? batchLiteralPathspecs(paths, prefix) : [undefined];\n\n\t\t// Unmerged entries are listed once per stage, and a path can sit under more than one scope\n\t\tconst files = new Set<string>();\n\t\tfor (const batch of batches) {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, errors: 'ignore', cancellation: cancellation },\n\t\t\t\t...prefix,\n\t\t\t\t...(batch != null ? ['--', ...batch] : []),\n\t\t\t);\n\t\t\t// `errors: 'ignore'` resolves an abort as an empty listing, which would read as a folder with no files\n\t\t\tif (result.completion.status === 'cancelled' || cancellation?.aborted) throw new CancellationError();\n\n\t\t\tfor (const file of iterateByDelimiter(result.stdout, '\\0')) {\n\t\t\t\tif (file) {\n\t\t\t\t\tfiles.add(file);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn [...files];\n\t}\n\n\t@debug()\n\tasync getTreeForRevision(\n\t\trepoPath: string,\n\t\trev: string,\n\t\toptions?: { paths?: readonly string[] },\n\t): Promise<GitTreeEntry[]> {\n\t\tif (!repoPath) return [];\n\n\t\tconst paths = options?.paths;\n\t\tif (paths == null) return this.getTreeForRevisionCore(repoPath, rev);\n\t\t// No pathspec means \"everything\" to git, which is not what an empty list asks for\n\t\tif (!paths.length) return [];\n\n\t\t// A scope's ancestor folders are listed with it, and a path can sit under more than one scope\n\t\tconst seen = new Set<string>();\n\t\tconst entries: GitTreeEntry[] = [];\n\t\tfor (const batch of batchLiteralPathspecs(paths, ['ls-tree', '-lrt', rev])) {\n\t\t\tfor (const entry of await this.getTreeForRevisionCore(repoPath, rev, undefined, batch)) {\n\t\t\t\tif (!seen.has(entry.path)) {\n\t\t\t\t\tseen.add(entry.path);\n\t\t\t\t\tentries.push(entry);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn entries;\n\t}\n\n\t@gate()\n\tprivate async getTreeForRevisionCore(\n\t\trepoPath: string,\n\t\trev: string,\n\t\tpath?: string,\n\t\tpathspecs?: readonly string[],\n\t): Promise<GitTreeEntry[]> {\n\t\tconst hasPath = Boolean(path);\n\t\tconst args = hasPath\n\t\t\t? ['ls-tree', '-l', rev, '--', path]\n\t\t\t: ['ls-tree', '-lrt', rev, '--', ...(pathspecs ?? [])];\n\t\tconst result = await this.git.run({ cwd: repoPath, errors: 'ignore' }, ...args);\n\t\tconst data = result.stdout.trim();\n\t\tif (!data) return emptyArray as GitTreeEntry[];\n\n\t\treturn parseGitTree(data, rev, hasPath);\n\t}\n\n\tprivate async showContentCore<T extends string | Buffer>(\n\t\trepoPath: string | undefined,\n\t\tpath: string,\n\t\trev: string,\n\t\toptions?: {\n\t\t\tencoding?: string;\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t): Promise<T | undefined> {\n\t\tconst [file, root] = splitPath(path, repoPath, true);\n\n\t\tif (isUncommittedStaged(rev)) {\n\t\t\trev = ':';\n\t\t}\n\t\tif (isUncommitted(rev)) throw new Error(`ref=${rev} is uncommitted`);\n\n\t\tconst opts: GitRunOptions = {\n\t\t\tconfigs: gitConfigsLog,\n\t\t\tcwd: root,\n\t\t\tencoding: options?.encoding ?? 'utf8',\n\t\t\terrors: 'throw',\n\t\t};\n\t\tconst args = rev.endsWith(':') ? `${rev}./${file}` : `${rev}:./${file}`;\n\t\tconst params = ['show', '--textconv', args, '--'];\n\n\t\ttry {\n\t\t\tconst result = await this.git.run<T>(opts, ...params);\n\t\t\treturn result.stdout;\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif (rev === ':' && GitErrors.badRevision.test(msg)) {\n\t\t\t\treturn this.showContentCore<T>(repoPath, path, 'HEAD:', options);\n\t\t\t}\n\n\t\t\tconst error = getGitCommandError(\n\t\t\t\t'show',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew ShowError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason ?? 'other',\n\t\t\t\t\t\t\trev: rev,\n\t\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath ?? '', args: params },\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\tif (options?.errors === 'throw') throw error;\n\n\t\t\tif (\n\t\t\t\tShowError.is(error, 'invalidObject') ||\n\t\t\t\tShowError.is(error, 'invalidRevision') ||\n\t\t\t\tShowError.is(error, 'notFound') ||\n\t\t\t\tShowError.is(error, 'notInRevision')\n\t\t\t) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tdefaultExceptionHandler(ex, opts.cwd);\n\t\t\treturn '' as T;\n\t\t}\n\t}\n\n\t@debug({ args: (repoPath, shas) => ({ repoPath: repoPath, shas: `${shas.size} value(s)` }) })\n\tasync resolveShas(repoPath: string, shas: ReadonlySet<string>, cancellation?: AbortSignal): Promise<Set<string>> {\n\t\tconst resolved = new Set<string>();\n\t\tconst prefixes: string[] = [];\n\n\t\tfor (const value of shas) {\n\t\t\t// Pure hex 4-40 chars: resolve to full commit SHA(s) via disambiguation. Everything else\n\t\t\t// (refs, suffixed SHAs like `^`/`~1`/`:path`, non-hex, <4 hex) passes through unchanged.\n\t\t\tif (/^[0-9a-f]{4,40}$/i.test(value)) {\n\t\t\t\tprefixes.push(value);\n\t\t\t} else {\n\t\t\t\tresolved.add(value);\n\t\t\t}\n\t\t}\n\n\t\tif (prefixes.length) {\n\t\t\t// List every object (any type) whose id starts with any prefix (empty + exit 0 if none)\n\t\t\tconst rp = await this.git.run(\n\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore' },\n\t\t\t\t'rev-parse',\n\t\t\t\t...prefixes.map(p => `--disambiguate=${p}`),\n\t\t\t);\n\t\t\tconst oids = rp.stdout.split('\\n').filter(Boolean);\n\t\t\tif (oids.length) {\n\t\t\t\t// `--disambiguate` has no type filter, so keep only commit objects\n\t\t\t\tconst cf = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: cancellation, errors: 'ignore', stdin: `${oids.join('\\n')}\\n` },\n\t\t\t\t\t'cat-file',\n\t\t\t\t\t'--batch-check=%(objectname) %(objecttype)',\n\t\t\t\t);\n\t\t\t\tfor (const line of cf.stdout.split('\\n')) {\n\t\t\t\t\tconst [oid, type] = line.split(' ');\n\t\t\t\t\tif (type === 'commit') {\n\t\t\t\t\t\tresolved.add(oid);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\t@debug()\n\tasync resolveRevision(\n\t\trepoPath: string,\n\t\tref: string,\n\t\tpathOrUri?: string | Uri,\n\t\toptions?: { force?: boolean },\n\t): Promise<ResolvedRevision> {\n\t\tconst path = pathOrUri != null ? toFsPath(pathOrUri) : undefined;\n\t\tif (!ref || ref === deletedOrMissing) return { sha: ref, revision: ref };\n\n\t\tif (path == null) {\n\t\t\tif (isSha(ref)) return { sha: ref, revision: ref };\n\t\t\tif (ref.endsWith('^3')) return { sha: ref, revision: ref };\n\t\t} else if (isUncommitted(ref)) {\n\t\t\t// Uncommitted refs depend on index/working-tree state — resolve without caching\n\t\t\treturn this.resolveRevisionCore(repoPath, ref, path);\n\t\t}\n\n\t\tconst key = path != null ? `${ref}|${this.provider.getRelativePath(path, repoPath)}` : ref;\n\t\tif (options?.force) {\n\t\t\t// Hard-delete first: a later caller must never join a read that started before this one.\n\t\t\tthis.cache.resolvedRevisions.delete(repoPath, key);\n\t\t}\n\n\t\treturn this.cache.resolvedRevisions.getOrCreate(repoPath, key, () =>\n\t\t\tthis.resolveRevisionCore(repoPath, ref, path, options?.force),\n\t\t);\n\t}\n\n\tprivate async resolveRevisionCore(\n\t\trepoPath: string,\n\t\tref: string,\n\t\tpath: string | undefined,\n\t\tforce?: boolean,\n\t): Promise<ResolvedRevision> {\n\t\tif (path == null) {\n\t\t\tconst sha = await this.provider.refs.validateReference(repoPath, ref, force ? { force: true } : undefined);\n\t\t\tif (sha == null) return { sha: ref, revision: ref };\n\n\t\t\treturn {\n\t\t\t\tsha: sha,\n\t\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\t\trevision: isRevisionWithSuffix(ref) ? sha : ref,\n\t\t\t};\n\t\t}\n\n\t\tif (isUncommittedWithParentSuffix(ref)) {\n\t\t\tref = 'HEAD';\n\t\t}\n\t\tconst relativePath = this.provider.getRelativePath(path, repoPath);\n\n\t\tif (isUncommitted(ref)) {\n\t\t\tif (!isUncommittedStaged(ref)) {\n\t\t\t\treturn { sha: ref, revision: ref };\n\t\t\t}\n\n\t\t\t// Ensure that the file is actually staged\n\t\t\tconst status = await this.provider.status.getStatusForFile?.(repoPath, relativePath, { renames: false });\n\t\t\tif (status?.indexStatus) return { sha: ref, revision: ref };\n\n\t\t\tref = 'HEAD';\n\t\t}\n\n\t\tconst resolvedRevisionCaching = { cache: this.cache.gitResults, options: { accessTTL: 5 * 60 * 1000 } };\n\n\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\tlet result = await this.git.run(\n\t\t\t// Forced here only: this read is keyed by `ref`, which can move; the follow-up below is keyed by a sha\n\t\t\t{ cwd: repoPath, errors: 'ignore', caching: { ...resolvedRevisionCaching, force: force } },\n\t\t\t'log',\n\t\t\t...parser.arguments,\n\t\t\t'-n1',\n\t\t\tref,\n\t\t\t'--',\n\t\t\trelativePath,\n\t\t);\n\n\t\tlet commit = first(parser.parse(result.stdout));\n\t\tlet file = commit?.files.find(f => f.path === relativePath);\n\t\tif (file == null) {\n\t\t\treturn {\n\t\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\t};\n\t\t}\n\n\t\tif (file.status === 'A') {\n\t\t\treturn {\n\t\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\t\tstatus: file.status as GitFileStatus,\n\t\t\t\toriginalPath: file.originalPath,\n\t\t\t};\n\t\t}\n\n\t\tif (file.status === 'D') {\n\t\t\t// If the file was deleted, check if it was moved or renamed\n\t\t\tresult = await this.git.run(\n\t\t\t\t{ cwd: repoPath, errors: 'ignore', caching: resolvedRevisionCaching },\n\t\t\t\t'log',\n\t\t\t\t...parser.arguments,\n\t\t\t\t'-n1',\n\n\t\t\t\tcommit!.sha,\n\t\t\t\t'--',\n\t\t\t);\n\n\t\t\tcommit = first(parser.parse(result.stdout));\n\t\t\tfile = commit?.files.find(f => f.path === relativePath || f.originalPath === relativePath);\n\t\t\tif (file == null) {\n\t\t\t\treturn {\n\t\t\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t\t// If it looks like non-sha like without a suffix then preserve it as the friendly name\n\t\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\t\tstatus: file.status as GitFileStatus,\n\t\t\t\tpath: file.path,\n\t\t\t\toriginalPath: file.originalPath,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsha: commit?.sha ?? deletedOrMissing,\n\t\t\t// If it looks like non-sha like then preserve it as the friendly name\n\t\t\trevision: isRevisionWithSuffix(ref) ? (commit?.sha ?? ref) : ref,\n\t\t\tstatus: file.status as GitFileStatus,\n\t\t\toriginalPath: file.originalPath,\n\t\t};\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -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 { tmpdir } from "os";
|
|
12
11
|
import { promises } from "fs";
|
|
12
|
+
import { tmpdir } from "os";
|
|
13
13
|
//#region ../git-cli/src/providers/staging.ts
|
|
14
14
|
var StagingGitSubProvider = class {
|
|
15
15
|
context;
|
|
@@ -11,10 +11,10 @@ import { PromiseMap } from "../../utils/promiseCache.js";
|
|
|
11
11
|
import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
|
|
12
12
|
import { GitErrors, defaultExceptionHandler, gitConfigsStatus, maxGitCliLength } from "../exec/git.js";
|
|
13
13
|
import { GitFileWorkingTreeStatus } from "../../git/models/fileStatus.js";
|
|
14
|
-
import _usingCtx from "../../_virtual/@oxc-project+runtime/helpers/esm/usingCtx.js";
|
|
15
|
-
import { parseGitConflictFiles } from "../parsers/indexParser.js";
|
|
16
14
|
import { GitStatus } from "../../git/models/status.js";
|
|
15
|
+
import _usingCtx from "../../_virtual/@oxc-project+runtime/helpers/esm/usingCtx.js";
|
|
17
16
|
import { parseGitStatus } from "../parsers/statusParser.js";
|
|
17
|
+
import { parseGitConflictFiles } from "../parsers/indexParser.js";
|
|
18
18
|
//#region ../git-cli/src/providers/status.ts
|
|
19
19
|
/** Backstop when `advanced.git.timeout` is disabled (0). Independent of the command timeout so disabling it can't
|
|
20
20
|
* also disable deadlock recovery — mirrors `@gate`'s always-on 5-min force-clear. */
|
package/dist/ipc/discovery.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { join } from "path";
|
|
2
2
|
import { mkdir, readFile, readdir, unlink, writeFile } from "fs/promises";
|
|
3
|
-
import { tmpdir } from "os";
|
|
4
3
|
import { kill, ppid } from "process";
|
|
4
|
+
import { tmpdir } from "os";
|
|
5
5
|
//#region ../ipc/src/discovery.ts
|
|
6
6
|
/**
|
|
7
7
|
* Directory scanned by `gk` binaries (and `@gitkraken/core-gitlens` consumers) for the
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { basename, dirname, join } from "path";
|
|
2
|
-
import { open, readFile, readdir, stat } from "fs/promises";
|
|
3
|
-
import { homedir } from "os";
|
|
4
2
|
import { createReadStream } from "fs";
|
|
3
|
+
import { open, readFile, readdir as readdir$1, stat } from "fs/promises";
|
|
4
|
+
import { homedir } from "os";
|
|
5
5
|
import { createInterface } from "readline";
|
|
6
6
|
//#region ../plus/agents/src/providers/claudeCodeTranscript.ts
|
|
7
7
|
/** Bytes read from each end of a transcript when summarizing. Titles and prompts cluster at both
|
|
@@ -269,7 +269,7 @@ var ClaudeCodeTranscriptReader = class {
|
|
|
269
269
|
const cached = this._names.get(dir);
|
|
270
270
|
if (cached != null && Date.now() - cached.resolvedAt < listingCacheTtlMs) return cached.names;
|
|
271
271
|
const gen = this._listingGen;
|
|
272
|
-
const names = (await readdir(dir, { withFileTypes: true })).filter((d) => d.isFile() && d.name.endsWith(".jsonl")).map((d) => d.name);
|
|
272
|
+
const names = (await readdir$1(dir, { withFileTypes: true })).filter((d) => d.isFile() && d.name.endsWith(".jsonl")).map((d) => d.name);
|
|
273
273
|
if (gen === this._listingGen) this._names.set(dir, {
|
|
274
274
|
names,
|
|
275
275
|
resolvedAt: Date.now()
|
|
@@ -283,7 +283,7 @@ var ClaudeCodeTranscriptReader = class {
|
|
|
283
283
|
if (cached != null && Date.now() - cached.resolvedAt < listingCacheTtlMs) return cached.dirs;
|
|
284
284
|
const gen = this._listingGen;
|
|
285
285
|
const root = this.getProjectsRoot();
|
|
286
|
-
const dirs = (await readdir(root, { withFileTypes: true })).filter((d) => d.isDirectory()).map((d) => join(root, d.name));
|
|
286
|
+
const dirs = (await readdir$1(root, { withFileTypes: true })).filter((d) => d.isDirectory()).map((d) => join(root, d.name));
|
|
287
287
|
if (gen === this._listingGen) this._projectDirs = {
|
|
288
288
|
dirs,
|
|
289
289
|
resolvedAt: Date.now()
|
|
@@ -487,7 +487,7 @@ var ClaudeCodeTranscriptReader = class {
|
|
|
487
487
|
if (await directoryExists(exact)) return exact;
|
|
488
488
|
let dirs;
|
|
489
489
|
try {
|
|
490
|
-
dirs = await readdir(root);
|
|
490
|
+
dirs = await readdir$1(root);
|
|
491
491
|
} catch (ex) {
|
|
492
492
|
if (!isMissingEntry(ex)) throw ex;
|
|
493
493
|
return;
|
|
@@ -506,7 +506,7 @@ var ClaudeCodeTranscriptReader = class {
|
|
|
506
506
|
const root = this.getProjectsRoot();
|
|
507
507
|
let dirs;
|
|
508
508
|
try {
|
|
509
|
-
dirs = await readdir(root);
|
|
509
|
+
dirs = await readdir$1(root);
|
|
510
510
|
} catch (ex) {
|
|
511
511
|
if (!isMissingEntry(ex)) throw ex;
|
|
512
512
|
return;
|