@gitkraken/core-gitlens 0.12.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.
Files changed (198) hide show
  1. package/CHANGELOG.md +78 -1
  2. package/dist/git/cache.d.ts +84 -29
  3. package/dist/git/cache.js +188 -54
  4. package/dist/git/cache.js.map +1 -1
  5. package/dist/git/features.d.ts +1 -1
  6. package/dist/git/features.js +5 -0
  7. package/dist/git/features.js.map +1 -1
  8. package/dist/git/models/branch.d.ts +20 -2
  9. package/dist/git/models/branch.js +28 -6
  10. package/dist/git/models/branch.js.map +1 -1
  11. package/dist/git/models/reference.d.ts +3 -0
  12. package/dist/git/models/status.js +2 -2
  13. package/dist/git/models/worktree.d.ts +4 -1
  14. package/dist/git/models/worktree.js +4 -2
  15. package/dist/git/models/worktree.js.map +1 -1
  16. package/dist/git/parsers/diffParser.js +1 -1
  17. package/dist/git/providers/branches.d.ts +73 -8
  18. package/dist/git/providers/operations.d.ts +3 -2
  19. package/dist/git/providers/pausedOperations.d.ts +6 -0
  20. package/dist/git/providers/provider.d.ts +45 -2
  21. package/dist/git/providers/revision.d.ts +17 -3
  22. package/dist/git/providers/status.d.ts +8 -2
  23. package/dist/git/remotes/azure-devops.js +61 -53
  24. package/dist/git/remotes/azure-devops.js.map +1 -1
  25. package/dist/git/run.types.d.ts +12 -0
  26. package/dist/git/service.d.ts +8 -5
  27. package/dist/git/service.js +16 -8
  28. package/dist/git/service.js.map +1 -1
  29. package/dist/git/utils/branch.utils.d.ts +12 -2
  30. package/dist/git/utils/branch.utils.js +49 -5
  31. package/dist/git/utils/branch.utils.js.map +1 -1
  32. package/dist/git/utils/reference.utils.d.ts +1 -0
  33. package/dist/git/utils/reference.utils.js.map +1 -1
  34. package/dist/git/watching/changeEvent.d.ts +13 -2
  35. package/dist/git/watching/changeEvent.js +17 -3
  36. package/dist/git/watching/changeEvent.js.map +1 -1
  37. package/dist/git/watching/gitDirPoller.d.ts +111 -0
  38. package/dist/git/watching/gitDirPoller.js +266 -0
  39. package/dist/git/watching/gitDirPoller.js.map +1 -0
  40. package/dist/git/watching/provider.d.ts +16 -0
  41. package/dist/git/watching/watchGroup.d.ts +40 -4
  42. package/dist/git/watching/watchGroup.js +143 -17
  43. package/dist/git/watching/watchGroup.js.map +1 -1
  44. package/dist/git/watching/watchService.d.ts +70 -1
  45. package/dist/git/watching/watchService.js +158 -13
  46. package/dist/git/watching/watchService.js.map +1 -1
  47. package/dist/git/watching/watchSession.d.ts +44 -0
  48. package/dist/git/watching/watchSession.js +91 -6
  49. package/dist/git/watching/watchSession.js.map +1 -1
  50. package/dist/git/watching/watcherPatterns.d.ts +21 -0
  51. package/dist/git/watching/watcherPatterns.js +67 -1
  52. package/dist/git/watching/watcherPatterns.js.map +1 -1
  53. package/dist/git/watching/worktreeSummary.d.ts +34 -7
  54. package/dist/git/watching/worktreeSummary.js +39 -12
  55. package/dist/git/watching/worktreeSummary.js.map +1 -1
  56. package/dist/git-cli/cliGitProvider.d.ts +40 -2
  57. package/dist/git-cli/cliGitProvider.js +182 -18
  58. package/dist/git-cli/cliGitProvider.js.map +1 -1
  59. package/dist/git-cli/exec/commandClassifier.d.ts +15 -0
  60. package/dist/git-cli/exec/commandClassifier.js +48 -2
  61. package/dist/git-cli/exec/commandClassifier.js.map +1 -1
  62. package/dist/git-cli/exec/git.d.ts +20 -3
  63. package/dist/git-cli/exec/git.js +63 -19
  64. package/dist/git-cli/exec/git.js.map +1 -1
  65. package/dist/git-cli/exec/gitQueue.d.ts +2 -0
  66. package/dist/git-cli/exec/gitQueue.js +2 -1
  67. package/dist/git-cli/exec/gitQueue.js.map +1 -1
  68. package/dist/git-cli/exec/indexLock.d.ts +39 -0
  69. package/dist/git-cli/exec/indexLock.js +160 -0
  70. package/dist/git-cli/exec/indexLock.js.map +1 -0
  71. package/dist/git-cli/parsers/blameParser.js +2 -2
  72. package/dist/git-cli/parsers/refParser.js +4 -2
  73. package/dist/git-cli/parsers/refParser.js.map +1 -1
  74. package/dist/git-cli/parsers/statusParser.d.ts +6 -0
  75. package/dist/git-cli/parsers/statusParser.js +33 -3
  76. package/dist/git-cli/parsers/statusParser.js.map +1 -1
  77. package/dist/git-cli/parsers/worktreeParser.js +42 -2
  78. package/dist/git-cli/parsers/worktreeParser.js.map +1 -1
  79. package/dist/git-cli/providers/branchRemote.d.ts +14 -0
  80. package/dist/git-cli/providers/branchRemote.js +36 -0
  81. package/dist/git-cli/providers/branchRemote.js.map +1 -0
  82. package/dist/git-cli/providers/branches.d.ts +109 -10
  83. package/dist/git-cli/providers/branches.js +630 -134
  84. package/dist/git-cli/providers/branches.js.map +1 -1
  85. package/dist/git-cli/providers/commits.js +2 -2
  86. package/dist/git-cli/providers/config.d.ts +9 -5
  87. package/dist/git-cli/providers/config.js +58 -25
  88. package/dist/git-cli/providers/config.js.map +1 -1
  89. package/dist/git-cli/providers/contributors.js +1 -1
  90. package/dist/git-cli/providers/graph.js +9 -6
  91. package/dist/git-cli/providers/graph.js.map +1 -1
  92. package/dist/git-cli/providers/operations.d.ts +17 -0
  93. package/dist/git-cli/providers/operations.js +172 -111
  94. package/dist/git-cli/providers/operations.js.map +1 -1
  95. package/dist/git-cli/providers/pausedOperations.d.ts +8 -0
  96. package/dist/git-cli/providers/pausedOperations.js +59 -39
  97. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  98. package/dist/git-cli/providers/refs.js +11 -8
  99. package/dist/git-cli/providers/refs.js.map +1 -1
  100. package/dist/git-cli/providers/remotes.js +19 -10
  101. package/dist/git-cli/providers/remotes.js.map +1 -1
  102. package/dist/git-cli/providers/revision.d.ts +6 -2
  103. package/dist/git-cli/providers/revision.js +38 -12
  104. package/dist/git-cli/providers/revision.js.map +1 -1
  105. package/dist/git-cli/providers/staging.js +39 -14
  106. package/dist/git-cli/providers/staging.js.map +1 -1
  107. package/dist/git-cli/providers/stash.d.ts +2 -0
  108. package/dist/git-cli/providers/stash.js +33 -18
  109. package/dist/git-cli/providers/stash.js.map +1 -1
  110. package/dist/git-cli/providers/status.d.ts +3 -1
  111. package/dist/git-cli/providers/status.js +40 -22
  112. package/dist/git-cli/providers/status.js.map +1 -1
  113. package/dist/git-cli/providers/tags.js +6 -4
  114. package/dist/git-cli/providers/tags.js.map +1 -1
  115. package/dist/git-cli/providers/worktrees.d.ts +1 -0
  116. package/dist/git-cli/providers/worktrees.js +60 -31
  117. package/dist/git-cli/providers/worktrees.js.map +1 -1
  118. package/dist/git-cli/service.d.ts +6 -0
  119. package/dist/git-cli/service.js +5 -2
  120. package/dist/git-cli/service.js.map +1 -1
  121. package/dist/plus/git-github/providers/github/revision.d.ts +6 -2
  122. package/dist/plus/git-github/providers/github/revision.js +15 -10
  123. package/dist/plus/git-github/providers/github/revision.js.map +1 -1
  124. package/dist/plus/git-github/providers/github/status.d.ts +3 -1
  125. package/dist/plus/git-github/providers/github/status.js +2 -2
  126. package/dist/plus/git-github/providers/github/status.js.map +1 -1
  127. package/dist/plus/integrations/collectionMetadata.d.ts +13 -2
  128. package/dist/plus/integrations/collectionMetadata.js +14 -2
  129. package/dist/plus/integrations/collectionMetadata.js.map +1 -1
  130. package/dist/plus/integrations/index.d.ts +2 -2
  131. package/dist/plus/integrations/index.js.map +1 -1
  132. package/dist/plus/integrations/integrationService.d.ts +1 -0
  133. package/dist/plus/integrations/integrationService.js +1 -1
  134. package/dist/plus/integrations/integrationService.js.map +1 -1
  135. package/dist/plus/integrations/manager.d.ts +1 -0
  136. package/dist/plus/integrations/models/gitHostIntegration.d.ts +41 -5
  137. package/dist/plus/integrations/models/gitHostIntegration.js +106 -29
  138. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  139. package/dist/plus/integrations/models/issueReads.d.ts +17 -4
  140. package/dist/plus/integrations/providers/apiClients.d.ts +2 -0
  141. package/dist/plus/integrations/providers/apiClients.js +7 -1
  142. package/dist/plus/integrations/providers/apiClients.js.map +1 -1
  143. package/dist/plus/integrations/providers/azure/azure.d.ts +5 -4
  144. package/dist/plus/integrations/providers/azure/azure.js +36 -76
  145. package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
  146. package/dist/plus/integrations/providers/azure/azure.utils.js +20 -17
  147. package/dist/plus/integrations/providers/azure/azure.utils.js.map +1 -1
  148. package/dist/plus/integrations/providers/azure/models.d.ts +2 -2
  149. package/dist/plus/integrations/providers/azure/models.js +4 -4
  150. package/dist/plus/integrations/providers/azure/models.js.map +1 -1
  151. package/dist/plus/integrations/providers/azure/workItemStateCategories.d.ts +21 -12
  152. package/dist/plus/integrations/providers/azure/workItemStateCategories.js +74 -17
  153. package/dist/plus/integrations/providers/azure/workItemStateCategories.js.map +1 -1
  154. package/dist/plus/integrations/providers/azureDevOps.d.ts +44 -0
  155. package/dist/plus/integrations/providers/azureDevOps.js +108 -17
  156. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  157. package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +45 -1
  158. package/dist/plus/integrations/providers/azureDevOpsServer.js +121 -6
  159. package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
  160. package/dist/plus/integrations/providers/jira-server.js +18 -14
  161. package/dist/plus/integrations/providers/jira-server.js.map +1 -1
  162. package/dist/plus/integrations/providers/jira.js +18 -14
  163. package/dist/plus/integrations/providers/jira.js.map +1 -1
  164. package/dist/plus/integrations/providers/models.d.ts +1 -2
  165. package/dist/plus/integrations/providers/models.js +9 -2
  166. package/dist/plus/integrations/providers/models.js.map +1 -1
  167. package/dist/plus/integrations/providers/providersApi.d.ts +7 -17
  168. package/dist/plus/integrations/providers/providersApi.js +85 -78
  169. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  170. package/dist/plus/integrations/providers/utils/jiraIssueDrains.d.ts +22 -0
  171. package/dist/plus/integrations/providers/utils/jiraIssueDrains.js +69 -9
  172. package/dist/plus/integrations/providers/utils/jiraIssueDrains.js.map +1 -1
  173. package/dist/plus/integrations/providers/utils/providerPaging.js +8 -2
  174. package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
  175. package/dist/plus/integrations/reads/filters.d.ts +3 -3
  176. package/dist/plus/integrations/reads/filters.js.map +1 -1
  177. package/dist/plus/integrations/reads/issueBatch.d.ts +2 -1
  178. package/dist/plus/integrations/reads/issueBatch.js +1 -1
  179. package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
  180. package/dist/plus/integrations/reads/issueTracker.js +23 -14
  181. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  182. package/dist/plus/integrations/reads/issues.d.ts +2 -1
  183. package/dist/plus/integrations/reads/issues.js +18 -3
  184. package/dist/plus/integrations/reads/issues.js.map +1 -1
  185. package/dist/plus/integrations/reads/pullRequestBatch.js +1 -1
  186. package/dist/plus/integrations/reads/resolveRepository.js +12 -3
  187. package/dist/plus/integrations/reads/resolveRepository.js.map +1 -1
  188. package/dist/plus/integrations/reads/warnings.d.ts +11 -4
  189. package/dist/plus/integrations/reads/warnings.js +15 -5
  190. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  191. package/dist/plus/integrations/results.d.ts +36 -2
  192. package/dist/plus/integrations/results.js +33 -13
  193. package/dist/plus/integrations/results.js.map +1 -1
  194. package/dist/utils/promiseCache.d.ts +10 -0
  195. package/dist/utils/promiseCache.js +17 -2
  196. package/dist/utils/promiseCache.js.map +1 -1
  197. package/docs/integrations.md +52 -20
  198. package/package.json +2 -2
@@ -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 data = (await this.git.run({
100
- cwd: repoPath,
101
- errors: "ignore"
102
- }, "ls-files", "-z")).stdout;
103
- if (!data) return [];
104
- return [...new Set(data.split("\0").filter(Boolean))];
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
- return repoPath ? this.getTreeForRevisionCore(repoPath, rev) : [];
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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"}
@@ -71,8 +71,12 @@ var StagingGitSubProvider = class {
71
71
  }
72
72
  }
73
73
  async stageFile(repoPath, pathOrUri) {
74
- await this.git.run({ cwd: repoPath }, "add", "-A", "--", toFsPath(pathOrUri));
75
- this.announceIndexChanged(repoPath);
74
+ const path = toFsPath(pathOrUri);
75
+ try {
76
+ await this.git.run({ cwd: repoPath }, "add", "-A", "--", path);
77
+ } finally {
78
+ this.announceIndexChanged(repoPath);
79
+ }
76
80
  }
77
81
  async stageFiles(repoPath, pathsOrUris, options) {
78
82
  const paths = pathsOrUris.map(toFsPath);
@@ -90,12 +94,20 @@ var StagingGitSubProvider = class {
90
94
  }
91
95
  }
92
96
  async stageDirectory(repoPath, directoryOrUri) {
93
- await this.git.run({ cwd: repoPath }, "add", "-A", "--", toFsPath(directoryOrUri));
94
- this.announceIndexChanged(repoPath);
97
+ const path = toFsPath(directoryOrUri);
98
+ try {
99
+ await this.git.run({ cwd: repoPath }, "add", "-A", "--", path);
100
+ } finally {
101
+ this.announceIndexChanged(repoPath);
102
+ }
95
103
  }
96
104
  async unstageFile(repoPath, pathOrUri) {
97
- await this.git.run({ cwd: repoPath }, "reset", "-q", "--", toFsPath(pathOrUri));
98
- this.announceIndexChanged(repoPath);
105
+ const path = toFsPath(pathOrUri);
106
+ try {
107
+ await this.git.run({ cwd: repoPath }, "reset", "-q", "--", path);
108
+ } finally {
109
+ this.announceIndexChanged(repoPath);
110
+ }
99
111
  }
100
112
  async unstageFiles(repoPath, pathsOrUris) {
101
113
  const paths = pathsOrUris.map(toFsPath);
@@ -110,15 +122,22 @@ var StagingGitSubProvider = class {
110
122
  }
111
123
  }
112
124
  async unstageDirectory(repoPath, directoryOrUri) {
113
- await this.git.run({ cwd: repoPath }, "reset", "-q", "--", toFsPath(directoryOrUri));
114
- this.announceIndexChanged(repoPath);
125
+ const path = toFsPath(directoryOrUri);
126
+ try {
127
+ await this.git.run({ cwd: repoPath }, "reset", "-q", "--", path);
128
+ } finally {
129
+ this.announceIndexChanged(repoPath);
130
+ }
115
131
  }
116
132
  async removeFile(repoPath, pathOrUri, options) {
117
133
  const args = ["rm"];
118
134
  if (options?.force) args.push("-f");
119
135
  args.push("--", toFsPath(pathOrUri));
120
- await this.git.run({ cwd: repoPath }, ...args);
121
- this.announceIndexChanged(repoPath);
136
+ try {
137
+ await this.git.run({ cwd: repoPath }, ...args);
138
+ } finally {
139
+ this.announceIndexChanged(repoPath);
140
+ }
122
141
  }
123
142
  async removeFiles(repoPath, pathsOrUris, options) {
124
143
  const paths = pathsOrUris.map(toFsPath);
@@ -136,12 +155,18 @@ var StagingGitSubProvider = class {
136
155
  }
137
156
  }
138
157
  async stageAll(repoPath) {
139
- await this.git.run({ cwd: repoPath }, "add", "-A");
140
- this.announceIndexChanged(repoPath);
158
+ try {
159
+ await this.git.run({ cwd: repoPath }, "add", "-A");
160
+ } finally {
161
+ this.announceIndexChanged(repoPath);
162
+ }
141
163
  }
142
164
  async unstageAll(repoPath) {
143
- await this.git.run({ cwd: repoPath }, "reset", "-q");
144
- this.announceIndexChanged(repoPath);
165
+ try {
166
+ await this.git.run({ cwd: repoPath }, "reset", "-q");
167
+ } finally {
168
+ this.announceIndexChanged(repoPath);
169
+ }
145
170
  }
146
171
  async clean(repoPath, options, runOptions) {
147
172
  const args = ["clean"];
@@ -1 +1 @@
1
- {"version":3,"file":"staging.js","names":["fs"],"sources":["../../../../git-cli/src/providers/staging.ts"],"sourcesContent":["import { promises as fs } from 'fs';\nimport { tmpdir } from 'os';\nimport * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport type { GitOperationRunOptions } from '@gitlens/git/providers/operations.js';\nimport type { DisposableTemporaryGitIndex, GitStagingSubProvider } from '@gitlens/git/providers/staging.js';\nimport { countStringLength } from '@gitlens/utils/array.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { mixinAsyncDisposable } from '@gitlens/utils/disposable.js';\nimport { chunk } from '@gitlens/utils/iterable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { joinPaths } 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 { Git } from '../exec/git.js';\nimport { maxGitCliLength } from '../exec/git.js';\n\nexport class StagingGitSubProvider implements GitStagingSubProvider {\n\tconstructor(\n\t\tprivate readonly context: GitServiceContext,\n\t\tprivate readonly git: Git,\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: CliGitProviderInternal,\n\t) {}\n\n\t@debug()\n\tasync createTemporaryIndex(\n\t\trepoPath: string,\n\t\tfrom: 'empty' | 'current' | 'ref',\n\t\tref?: string,\n\t): Promise<DisposableTemporaryGitIndex> {\n\t\tconst scope = getScopedLogger();\n\n\t\t// Create a temporary index file\n\t\tconst tempDir = await fs.mkdtemp(joinPaths(tmpdir(), 'gl-'));\n\t\tconst tempIndex = joinPaths(tempDir, 'index');\n\n\t\tasync function dispose() {\n\t\t\t// Delete the temporary index file\n\t\t\ttry {\n\t\t\t\tawait fs.rm(tempDir, { recursive: true });\n\t\t\t} catch {\n\t\t\t\t// ignore cleanup errors\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// Tell Git to use our soon to be created index file\n\t\t\tconst env = { GIT_INDEX_FILE: tempIndex };\n\n\t\t\tswitch (from) {\n\t\t\t\tcase 'empty':\n\t\t\t\t\t// Leave the temp index empty\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'current': {\n\t\t\t\t\t// Copy the current index to preserve staged state\n\t\t\t\t\tconst gitDir = await this.provider.config.getGitDir?.(repoPath);\n\t\t\t\t\tif (gitDir == null) throw new Error(l10n.t('Unable to determine git directory for {0}', repoPath));\n\n\t\t\t\t\tconst currentIndex = joinPaths(gitDir.uri.fsPath, 'index');\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait fs.copyFile(currentIndex, tempIndex);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t// A repo that has never staged anything has no index file yet; git reads a missing\n\t\t\t\t\t\t// `GIT_INDEX_FILE` as an empty index, which is what 'current' means there. Any other\n\t\t\t\t\t\t// failure is real — don't silently hand back an index claiming everything is deleted.\n\t\t\t\t\t\tif ((ex as NodeJS.ErrnoException)?.code !== 'ENOENT') throw ex;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'ref': {\n\t\t\t\t\tif (ref == null) throw new Error(l10n.t(\"ref is required when from is 'ref'\"));\n\n\t\t\t\t\t// Create the temp index file from a base ref/sha\n\t\t\t\t\tconst newIndexResult = await this.git.run(\n\t\t\t\t\t\t{ cwd: repoPath, env: env },\n\t\t\t\t\t\t'ls-tree',\n\t\t\t\t\t\t'-z',\n\t\t\t\t\t\t'-r',\n\t\t\t\t\t\t'--full-name',\n\t\t\t\t\t\tref,\n\t\t\t\t\t);\n\n\t\t\t\t\tif (newIndexResult.stdout.trim()) {\n\t\t\t\t\t\t// Write the tree to our temp index\n\t\t\t\t\t\tawait this.git.run(\n\t\t\t\t\t\t\t{ cwd: repoPath, env: env, stdin: newIndexResult.stdout },\n\t\t\t\t\t\t\t'update-index',\n\t\t\t\t\t\t\t'-z',\n\t\t\t\t\t\t\t'--index-info',\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn mixinAsyncDisposable({ path: tempIndex, env: { GIT_INDEX_FILE: tempIndex } }, dispose);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\n\t\t\tvoid dispose();\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync stageFile(repoPath: string, pathOrUri: string | Uri): Promise<void> {\n\t\tawait this.git.run({ cwd: repoPath }, 'add', '-A', '--', toFsPath(pathOrUri));\n\t\tthis.announceIndexChanged(repoPath);\n\t}\n\n\t@debug()\n\tasync stageFiles(\n\t\trepoPath: string,\n\t\tpathsOrUris: (string | Uri)[],\n\t\toptions?: { intentToAdd?: boolean; index?: DisposableTemporaryGitIndex },\n\t): Promise<void> {\n\t\tconst paths = pathsOrUris.map(toFsPath);\n\t\tif (!paths.length) return;\n\n\t\t// Calculate a safe batch size based on average path length\n\t\tconst avgPathLength = countStringLength(paths) / paths.length;\n\t\tconst batchSize = Math.max(1, Math.floor(maxGitCliLength / avgPathLength));\n\n\t\t// Process files in batches (will be a single batch if under the limit)\n\t\tconst batches = chunk(paths, batchSize);\n\t\ttry {\n\t\t\tfor (const batch of batches) {\n\t\t\t\tawait this.git.run(\n\t\t\t\t\t{ cwd: repoPath, env: options?.index?.env },\n\t\t\t\t\t'add',\n\t\t\t\t\toptions?.intentToAdd ? '-N' : '-A',\n\t\t\t\t\t'--',\n\t\t\t\t\t...batch,\n\t\t\t\t);\n\t\t\t}\n\t\t} finally {\n\t\t\t// Announced even when a later batch fails, since the earlier ones already changed the index. A\n\t\t\t// temporary index (used for partial-stage previews / diff building) is not the repository's real\n\t\t\t// index — firing repo-change hooks for it would invalidate status caches for a mutation nothing\n\t\t\t// else can observe.\n\t\t\tif (options?.index == null) {\n\t\t\t\tthis.announceIndexChanged(repoPath);\n\t\t\t}\n\t\t}\n\t}\n\n\t@debug()\n\tasync stageDirectory(repoPath: string, directoryOrUri: string | Uri): Promise<void> {\n\t\tawait this.git.run({ cwd: repoPath }, 'add', '-A', '--', toFsPath(directoryOrUri));\n\t\tthis.announceIndexChanged(repoPath);\n\t}\n\n\t@debug()\n\tasync unstageFile(repoPath: string, pathOrUri: string | Uri): Promise<void> {\n\t\tawait this.git.run({ cwd: repoPath }, 'reset', '-q', '--', toFsPath(pathOrUri));\n\t\tthis.announceIndexChanged(repoPath);\n\t}\n\n\t@debug()\n\tasync unstageFiles(repoPath: string, pathsOrUris: (string | Uri)[]): Promise<void> {\n\t\tconst paths = pathsOrUris.map(toFsPath);\n\t\tif (!paths.length) return;\n\n\t\t// Calculate a safe batch size based on average path length\n\t\tconst avgPathLength = countStringLength(paths) / paths.length;\n\t\tconst batchSize = Math.max(1, Math.floor(maxGitCliLength / avgPathLength));\n\n\t\t// Process files in batches (will be a single batch if under the limit)\n\t\tconst batches = chunk(paths, batchSize);\n\t\ttry {\n\t\t\tfor (const batch of batches) {\n\t\t\t\tawait this.git.run({ cwd: repoPath }, 'reset', '-q', '--', ...batch);\n\t\t\t}\n\t\t} finally {\n\t\t\t// Even when a later batch fails, the earlier ones already changed the index\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync unstageDirectory(repoPath: string, directoryOrUri: string | Uri): Promise<void> {\n\t\tawait this.git.run({ cwd: repoPath }, 'reset', '-q', '--', toFsPath(directoryOrUri));\n\t\tthis.announceIndexChanged(repoPath);\n\t}\n\n\t@debug()\n\tasync removeFile(repoPath: string, pathOrUri: string | Uri, options?: { force?: boolean }): Promise<void> {\n\t\tconst args = ['rm'];\n\t\tif (options?.force) {\n\t\t\targs.push('-f');\n\t\t}\n\t\targs.push('--', toFsPath(pathOrUri));\n\t\tawait this.git.run({ cwd: repoPath }, ...args);\n\t\tthis.announceIndexChanged(repoPath);\n\t}\n\n\t@debug()\n\tasync removeFiles(repoPath: string, pathsOrUris: (string | Uri)[], options?: { force?: boolean }): Promise<void> {\n\t\tconst paths = pathsOrUris.map(toFsPath);\n\t\tif (!paths.length) return;\n\n\t\tconst args: string[] = ['rm'];\n\t\tif (options?.force) {\n\t\t\targs.push('-f');\n\t\t}\n\t\targs.push('--');\n\n\t\t// Calculate a safe batch size based on average path length\n\t\tconst avgPathLength = countStringLength(paths) / paths.length;\n\t\tconst batchSize = Math.max(1, Math.floor(maxGitCliLength / avgPathLength));\n\n\t\t// Process files in batches (will be a single batch if under the limit)\n\t\tconst batches = chunk(paths, batchSize);\n\t\ttry {\n\t\t\tfor (const batch of batches) {\n\t\t\t\tawait this.git.run({ cwd: repoPath }, ...args, ...batch);\n\t\t\t}\n\t\t} finally {\n\t\t\t// Even when a later batch fails, the earlier ones already changed the index\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync stageAll(repoPath: string): Promise<void> {\n\t\tawait this.git.run({ cwd: repoPath }, 'add', '-A');\n\t\tthis.announceIndexChanged(repoPath);\n\t}\n\n\t@debug()\n\tasync unstageAll(repoPath: string): Promise<void> {\n\t\tawait this.git.run({ cwd: repoPath }, 'reset', '-q');\n\t\tthis.announceIndexChanged(repoPath);\n\t}\n\n\t@debug()\n\tasync clean(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tpaths?: (string | Uri)[];\n\t\t\tdirectories?: boolean;\n\t\t\tforce?: boolean;\n\t\t\tignored?: boolean;\n\t\t},\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst args = ['clean'];\n\t\tif (options?.force ?? true) {\n\t\t\targs.push('-f');\n\t\t}\n\t\tif (options?.directories) {\n\t\t\targs.push('-d');\n\t\t}\n\t\tif (options?.ignored) {\n\t\t\targs.push('-x');\n\t\t}\n\n\t\tif (options?.paths == null) {\n\t\t\ttry {\n\t\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw', ...runOptions }, ...args);\n\t\t\t} finally {\n\t\t\t\t// A clean that failed or was cancelled partway may already have removed files\n\t\t\t\tthis.announceIndexChanged(repoPath);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst paths = options.paths.map(toFsPath);\n\t\tif (!paths.length) return;\n\n\t\t// Calculate a safe batch size based on average path length\n\t\tconst avgPathLength = countStringLength(paths) / paths.length;\n\t\tconst batchSize = Math.max(1, Math.floor(maxGitCliLength / avgPathLength));\n\n\t\t// Process paths in batches (will be a single batch if under the limit)\n\t\tconst batches = chunk(paths, batchSize);\n\t\ttry {\n\t\t\tfor (const batch of batches) {\n\t\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw', ...runOptions }, ...args, '--', ...batch);\n\t\t\t}\n\t\t} finally {\n\t\t\t// Even when a later batch fails, the earlier ones already removed files\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t/** What every index or working-tree mutation announces, so cached status is re-read and hosts are told. */\n\tprivate announceIndexChanged(repoPath: string): void {\n\t\t// `diff` and `tracking` too, as a watcher-observed index change clears them: a file's working-vs-index\n\t\t// diff and whether it is tracked both change when it is staged, unstaged or removed\n\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'status', 'diff', 'tracking');\n\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['index']);\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"staging.js","names":["fs"],"sources":["../../../../git-cli/src/providers/staging.ts"],"sourcesContent":["import { promises as fs } from 'fs';\nimport { tmpdir } from 'os';\nimport * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport type { GitOperationRunOptions } from '@gitlens/git/providers/operations.js';\nimport type { DisposableTemporaryGitIndex, GitStagingSubProvider } from '@gitlens/git/providers/staging.js';\nimport { countStringLength } from '@gitlens/utils/array.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { mixinAsyncDisposable } from '@gitlens/utils/disposable.js';\nimport { chunk } from '@gitlens/utils/iterable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { joinPaths } 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 { Git } from '../exec/git.js';\nimport { maxGitCliLength } from '../exec/git.js';\n\nexport class StagingGitSubProvider implements GitStagingSubProvider {\n\tconstructor(\n\t\tprivate readonly context: GitServiceContext,\n\t\tprivate readonly git: Git,\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: CliGitProviderInternal,\n\t) {}\n\n\t@debug()\n\tasync createTemporaryIndex(\n\t\trepoPath: string,\n\t\tfrom: 'empty' | 'current' | 'ref',\n\t\tref?: string,\n\t): Promise<DisposableTemporaryGitIndex> {\n\t\tconst scope = getScopedLogger();\n\n\t\t// Create a temporary index file\n\t\tconst tempDir = await fs.mkdtemp(joinPaths(tmpdir(), 'gl-'));\n\t\tconst tempIndex = joinPaths(tempDir, 'index');\n\n\t\tasync function dispose() {\n\t\t\t// Delete the temporary index file\n\t\t\ttry {\n\t\t\t\tawait fs.rm(tempDir, { recursive: true });\n\t\t\t} catch {\n\t\t\t\t// ignore cleanup errors\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// Tell Git to use our soon to be created index file\n\t\t\tconst env = { GIT_INDEX_FILE: tempIndex };\n\n\t\t\tswitch (from) {\n\t\t\t\tcase 'empty':\n\t\t\t\t\t// Leave the temp index empty\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'current': {\n\t\t\t\t\t// Copy the current index to preserve staged state\n\t\t\t\t\tconst gitDir = await this.provider.config.getGitDir?.(repoPath);\n\t\t\t\t\tif (gitDir == null) throw new Error(l10n.t('Unable to determine git directory for {0}', repoPath));\n\n\t\t\t\t\tconst currentIndex = joinPaths(gitDir.uri.fsPath, 'index');\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait fs.copyFile(currentIndex, tempIndex);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t// A repo that has never staged anything has no index file yet; git reads a missing\n\t\t\t\t\t\t// `GIT_INDEX_FILE` as an empty index, which is what 'current' means there. Any other\n\t\t\t\t\t\t// failure is real — don't silently hand back an index claiming everything is deleted.\n\t\t\t\t\t\tif ((ex as NodeJS.ErrnoException)?.code !== 'ENOENT') throw ex;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'ref': {\n\t\t\t\t\tif (ref == null) throw new Error(l10n.t(\"ref is required when from is 'ref'\"));\n\n\t\t\t\t\t// Create the temp index file from a base ref/sha\n\t\t\t\t\tconst newIndexResult = await this.git.run(\n\t\t\t\t\t\t{ cwd: repoPath, env: env },\n\t\t\t\t\t\t'ls-tree',\n\t\t\t\t\t\t'-z',\n\t\t\t\t\t\t'-r',\n\t\t\t\t\t\t'--full-name',\n\t\t\t\t\t\tref,\n\t\t\t\t\t);\n\n\t\t\t\t\tif (newIndexResult.stdout.trim()) {\n\t\t\t\t\t\t// Write the tree to our temp index\n\t\t\t\t\t\tawait this.git.run(\n\t\t\t\t\t\t\t{ cwd: repoPath, env: env, stdin: newIndexResult.stdout },\n\t\t\t\t\t\t\t'update-index',\n\t\t\t\t\t\t\t'-z',\n\t\t\t\t\t\t\t'--index-info',\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn mixinAsyncDisposable({ path: tempIndex, env: { GIT_INDEX_FILE: tempIndex } }, dispose);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\n\t\t\tvoid dispose();\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync stageFile(repoPath: string, pathOrUri: string | Uri): Promise<void> {\n\t\tconst path = toFsPath(pathOrUri);\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, 'add', '-A', '--', path);\n\t\t} finally {\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync stageFiles(\n\t\trepoPath: string,\n\t\tpathsOrUris: (string | Uri)[],\n\t\toptions?: { intentToAdd?: boolean; index?: DisposableTemporaryGitIndex },\n\t): Promise<void> {\n\t\tconst paths = pathsOrUris.map(toFsPath);\n\t\tif (!paths.length) return;\n\n\t\t// Calculate a safe batch size based on average path length\n\t\tconst avgPathLength = countStringLength(paths) / paths.length;\n\t\tconst batchSize = Math.max(1, Math.floor(maxGitCliLength / avgPathLength));\n\n\t\t// Process files in batches (will be a single batch if under the limit)\n\t\tconst batches = chunk(paths, batchSize);\n\t\ttry {\n\t\t\tfor (const batch of batches) {\n\t\t\t\tawait this.git.run(\n\t\t\t\t\t{ cwd: repoPath, env: options?.index?.env },\n\t\t\t\t\t'add',\n\t\t\t\t\toptions?.intentToAdd ? '-N' : '-A',\n\t\t\t\t\t'--',\n\t\t\t\t\t...batch,\n\t\t\t\t);\n\t\t\t}\n\t\t} finally {\n\t\t\t// Announced even when a later batch fails, since the earlier ones already changed the index. A\n\t\t\t// temporary index (used for partial-stage previews / diff building) is not the repository's real\n\t\t\t// index — firing repo-change hooks for it would invalidate status caches for a mutation nothing\n\t\t\t// else can observe.\n\t\t\tif (options?.index == null) {\n\t\t\t\tthis.announceIndexChanged(repoPath);\n\t\t\t}\n\t\t}\n\t}\n\n\t@debug()\n\tasync stageDirectory(repoPath: string, directoryOrUri: string | Uri): Promise<void> {\n\t\tconst path = toFsPath(directoryOrUri);\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, 'add', '-A', '--', path);\n\t\t} finally {\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync unstageFile(repoPath: string, pathOrUri: string | Uri): Promise<void> {\n\t\tconst path = toFsPath(pathOrUri);\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, 'reset', '-q', '--', path);\n\t\t} finally {\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync unstageFiles(repoPath: string, pathsOrUris: (string | Uri)[]): Promise<void> {\n\t\tconst paths = pathsOrUris.map(toFsPath);\n\t\tif (!paths.length) return;\n\n\t\t// Calculate a safe batch size based on average path length\n\t\tconst avgPathLength = countStringLength(paths) / paths.length;\n\t\tconst batchSize = Math.max(1, Math.floor(maxGitCliLength / avgPathLength));\n\n\t\t// Process files in batches (will be a single batch if under the limit)\n\t\tconst batches = chunk(paths, batchSize);\n\t\ttry {\n\t\t\tfor (const batch of batches) {\n\t\t\t\tawait this.git.run({ cwd: repoPath }, 'reset', '-q', '--', ...batch);\n\t\t\t}\n\t\t} finally {\n\t\t\t// Even when a later batch fails, the earlier ones already changed the index\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync unstageDirectory(repoPath: string, directoryOrUri: string | Uri): Promise<void> {\n\t\tconst path = toFsPath(directoryOrUri);\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, 'reset', '-q', '--', path);\n\t\t} finally {\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync removeFile(repoPath: string, pathOrUri: string | Uri, options?: { force?: boolean }): Promise<void> {\n\t\tconst args = ['rm'];\n\t\tif (options?.force) {\n\t\t\targs.push('-f');\n\t\t}\n\t\targs.push('--', toFsPath(pathOrUri));\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, ...args);\n\t\t} finally {\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync removeFiles(repoPath: string, pathsOrUris: (string | Uri)[], options?: { force?: boolean }): Promise<void> {\n\t\tconst paths = pathsOrUris.map(toFsPath);\n\t\tif (!paths.length) return;\n\n\t\tconst args: string[] = ['rm'];\n\t\tif (options?.force) {\n\t\t\targs.push('-f');\n\t\t}\n\t\targs.push('--');\n\n\t\t// Calculate a safe batch size based on average path length\n\t\tconst avgPathLength = countStringLength(paths) / paths.length;\n\t\tconst batchSize = Math.max(1, Math.floor(maxGitCliLength / avgPathLength));\n\n\t\t// Process files in batches (will be a single batch if under the limit)\n\t\tconst batches = chunk(paths, batchSize);\n\t\ttry {\n\t\t\tfor (const batch of batches) {\n\t\t\t\tawait this.git.run({ cwd: repoPath }, ...args, ...batch);\n\t\t\t}\n\t\t} finally {\n\t\t\t// Even when a later batch fails, the earlier ones already changed the index\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync stageAll(repoPath: string): Promise<void> {\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, 'add', '-A');\n\t\t} finally {\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync unstageAll(repoPath: string): Promise<void> {\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, 'reset', '-q');\n\t\t} finally {\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug()\n\tasync clean(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tpaths?: (string | Uri)[];\n\t\t\tdirectories?: boolean;\n\t\t\tforce?: boolean;\n\t\t\tignored?: boolean;\n\t\t},\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst args = ['clean'];\n\t\tif (options?.force ?? true) {\n\t\t\targs.push('-f');\n\t\t}\n\t\tif (options?.directories) {\n\t\t\targs.push('-d');\n\t\t}\n\t\tif (options?.ignored) {\n\t\t\targs.push('-x');\n\t\t}\n\n\t\tif (options?.paths == null) {\n\t\t\ttry {\n\t\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw', ...runOptions }, ...args);\n\t\t\t} finally {\n\t\t\t\t// A clean that failed or was cancelled partway may already have removed files\n\t\t\t\tthis.announceIndexChanged(repoPath);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst paths = options.paths.map(toFsPath);\n\t\tif (!paths.length) return;\n\n\t\t// Calculate a safe batch size based on average path length\n\t\tconst avgPathLength = countStringLength(paths) / paths.length;\n\t\tconst batchSize = Math.max(1, Math.floor(maxGitCliLength / avgPathLength));\n\n\t\t// Process paths in batches (will be a single batch if under the limit)\n\t\tconst batches = chunk(paths, batchSize);\n\t\ttry {\n\t\t\tfor (const batch of batches) {\n\t\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw', ...runOptions }, ...args, '--', ...batch);\n\t\t\t}\n\t\t} finally {\n\t\t\t// Even when a later batch fails, the earlier ones already removed files\n\t\t\tthis.announceIndexChanged(repoPath);\n\t\t}\n\t}\n\n\t/** What every index or working-tree mutation announces, so cached status is re-read and hosts are told. */\n\tprivate announceIndexChanged(repoPath: string): void {\n\t\t// `diff` and `tracking` too, as a watcher-observed index change clears them: a file's working-vs-index\n\t\t// diff and whether it is tracked both change when it is staged, unstaged or removed\n\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'status', 'diff', 'tracking');\n\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['index']);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AAmBA,IAAa,wBAAb,MAAoE;CAEjD;CACA;CACA;CACA;CAJlB,YACC,SACA,KACA,OACA,UACC;EAJgB,KAAA,UAAA;EACA,KAAA,MAAA;EACA,KAAA,QAAA;EACA,KAAA,WAAA;CACf;CAEH,MACM,qBACL,UACA,MACA,KACuC;EACvC,MAAM,QAAQ,gBAAgB;EAG9B,MAAM,UAAU,MAAMA,SAAG,QAAQ,UAAU,OAAO,GAAG,KAAK,CAAC;EAC3D,MAAM,YAAY,UAAU,SAAS,OAAO;EAE5C,eAAe,UAAU;GAExB,IAAI;IACH,MAAMA,SAAG,GAAG,SAAS,EAAE,WAAW,KAAK,CAAC;GACzC,QAAQ,CAER;EACD;EAEA,IAAI;GAEH,MAAM,MAAM,EAAE,gBAAgB,UAAU;GAExC,QAAQ,MAAR;IACC,KAAK,SAEJ;IACD,KAAK,WAAW;KAEf,MAAM,SAAS,MAAM,KAAK,SAAS,OAAO,YAAY,QAAQ;KAC9D,IAAI,UAAU,MAAM,MAAM,IAAI,MAAM,KAAK,EAAE,6CAA6C,QAAQ,CAAC;KAEjG,MAAM,eAAe,UAAU,OAAO,IAAI,QAAQ,OAAO;KACzD,IAAI;MACH,MAAMA,SAAG,SAAS,cAAc,SAAS;KAC1C,SAAS,IAAI;MAIZ,IAAK,IAA8B,SAAS,UAAU,MAAM;KAC7D;KACA;IACD;IACA,KAAK,OAAO;KACX,IAAI,OAAO,MAAM,MAAM,IAAI,MAAM,KAAK,EAAE,oCAAoC,CAAC;KAG7E,MAAM,iBAAiB,MAAM,KAAK,IAAI,IACrC;MAAE,KAAK;MAAe;KAAI,GAC1B,WACA,MACA,MACA,eACA,GACD;KAEA,IAAI,eAAe,OAAO,KAAK,GAE9B,MAAM,KAAK,IAAI,IACd;MAAE,KAAK;MAAe;MAAK,OAAO,eAAe;KAAO,GACxD,gBACA,MACA,cACD;KAGD;IACD;GACD;GAEA,OAAO,qBAAqB;IAAE,MAAM;IAAW,KAAK,EAAE,gBAAgB,UAAU;GAAE,GAAG,OAAO;EAC7F,SAAS,IAAI;GACZ,OAAO,MAAM,EAAE;GAEf,QAAa;GACb,MAAM;EACP;CACD;CAEA,MACM,UAAU,UAAkB,WAAwC;EACzE,MAAM,OAAO,SAAS,SAAS;EAC/B,IAAI;GACH,MAAM,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,OAAO,MAAM,MAAM,IAAI;EAC9D,UAAU;GACT,KAAK,qBAAqB,QAAQ;EACnC;CACD;CAEA,MACM,WACL,UACA,aACA,SACgB;EAChB,MAAM,QAAQ,YAAY,IAAI,QAAQ;EACtC,IAAI,CAAC,MAAM,QAAQ;EAGnB,MAAM,gBAAgB,kBAAkB,KAAK,IAAI,MAAM;EACvD,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,aAAa,CAAC;EAGzE,MAAM,UAAU,MAAM,OAAO,SAAS;EACtC,IAAI;GACH,KAAK,MAAM,SAAS,SACnB,MAAM,KAAK,IAAI,IACd;IAAE,KAAK;IAAU,KAAK,SAAS,OAAO;GAAI,GAC1C,OACA,SAAS,cAAc,OAAO,MAC9B,MACA,GAAG,KACJ;EAEF,UAAU;GAKT,IAAI,SAAS,SAAS,MACrB,KAAK,qBAAqB,QAAQ;EAEpC;CACD;CAEA,MACM,eAAe,UAAkB,gBAA6C;EACnF,MAAM,OAAO,SAAS,cAAc;EACpC,IAAI;GACH,MAAM,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,OAAO,MAAM,MAAM,IAAI;EAC9D,UAAU;GACT,KAAK,qBAAqB,QAAQ;EACnC;CACD;CAEA,MACM,YAAY,UAAkB,WAAwC;EAC3E,MAAM,OAAO,SAAS,SAAS;EAC/B,IAAI;GACH,MAAM,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,SAAS,MAAM,MAAM,IAAI;EAChE,UAAU;GACT,KAAK,qBAAqB,QAAQ;EACnC;CACD;CAEA,MACM,aAAa,UAAkB,aAA8C;EAClF,MAAM,QAAQ,YAAY,IAAI,QAAQ;EACtC,IAAI,CAAC,MAAM,QAAQ;EAGnB,MAAM,gBAAgB,kBAAkB,KAAK,IAAI,MAAM;EACvD,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,aAAa,CAAC;EAGzE,MAAM,UAAU,MAAM,OAAO,SAAS;EACtC,IAAI;GACH,KAAK,MAAM,SAAS,SACnB,MAAM,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,SAAS,MAAM,MAAM,GAAG,KAAK;EAErE,UAAU;GAET,KAAK,qBAAqB,QAAQ;EACnC;CACD;CAEA,MACM,iBAAiB,UAAkB,gBAA6C;EACrF,MAAM,OAAO,SAAS,cAAc;EACpC,IAAI;GACH,MAAM,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,SAAS,MAAM,MAAM,IAAI;EAChE,UAAU;GACT,KAAK,qBAAqB,QAAQ;EACnC;CACD;CAEA,MACM,WAAW,UAAkB,WAAyB,SAA8C;EACzG,MAAM,OAAO,CAAC,IAAI;EAClB,IAAI,SAAS,OACZ,KAAK,KAAK,IAAI;EAEf,KAAK,KAAK,MAAM,SAAS,SAAS,CAAC;EACnC,IAAI;GACH,MAAM,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,GAAG,IAAI;EAC9C,UAAU;GACT,KAAK,qBAAqB,QAAQ;EACnC;CACD;CAEA,MACM,YAAY,UAAkB,aAA+B,SAA8C;EAChH,MAAM,QAAQ,YAAY,IAAI,QAAQ;EACtC,IAAI,CAAC,MAAM,QAAQ;EAEnB,MAAM,OAAiB,CAAC,IAAI;EAC5B,IAAI,SAAS,OACZ,KAAK,KAAK,IAAI;EAEf,KAAK,KAAK,IAAI;EAGd,MAAM,gBAAgB,kBAAkB,KAAK,IAAI,MAAM;EACvD,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,aAAa,CAAC;EAGzE,MAAM,UAAU,MAAM,OAAO,SAAS;EACtC,IAAI;GACH,KAAK,MAAM,SAAS,SACnB,MAAM,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,GAAG,MAAM,GAAG,KAAK;EAEzD,UAAU;GAET,KAAK,qBAAqB,QAAQ;EACnC;CACD;CAEA,MACM,SAAS,UAAiC;EAC/C,IAAI;GACH,MAAM,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,OAAO,IAAI;EAClD,UAAU;GACT,KAAK,qBAAqB,QAAQ;EACnC;CACD;CAEA,MACM,WAAW,UAAiC;EACjD,IAAI;GACH,MAAM,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,SAAS,IAAI;EACpD,UAAU;GACT,KAAK,qBAAqB,QAAQ;EACnC;CACD;CAEA,MACM,MACL,UACA,SAMA,YACgB;EAChB,MAAM,OAAO,CAAC,OAAO;EACrB,IAAI,SAAS,SAAS,MACrB,KAAK,KAAK,IAAI;EAEf,IAAI,SAAS,aACZ,KAAK,KAAK,IAAI;EAEf,IAAI,SAAS,SACZ,KAAK,KAAK,IAAI;EAGf,IAAI,SAAS,SAAS,MAAM;GAC3B,IAAI;IACH,MAAM,KAAK,IAAI,IAAI;KAAE,KAAK;KAAU,QAAQ;KAAS,GAAG;IAAW,GAAG,GAAG,IAAI;GAC9E,UAAU;IAET,KAAK,qBAAqB,QAAQ;GACnC;GACA;EACD;EAEA,MAAM,QAAQ,QAAQ,MAAM,IAAI,QAAQ;EACxC,IAAI,CAAC,MAAM,QAAQ;EAGnB,MAAM,gBAAgB,kBAAkB,KAAK,IAAI,MAAM;EACvD,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,aAAa,CAAC;EAGzE,MAAM,UAAU,MAAM,OAAO,SAAS;EACtC,IAAI;GACH,KAAK,MAAM,SAAS,SACnB,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAU,QAAQ;IAAS,GAAG;GAAW,GAAG,GAAG,MAAM,MAAM,GAAG,KAAK;EAE/F,UAAU;GAET,KAAK,qBAAqB,QAAQ;EACnC;CACD;;CAGA,qBAA6B,UAAwB;EAGpD,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,UAAU,QAAQ,UAAU;EAC3E,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,OAAO,CAAC;CAChE;AACD;AAvSE,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,wBAAA,IAAA;AAiFN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,aAAA,IAAA;AAUN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,cAAA,IAAA;AAoCN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,kBAAA,IAAA;AAUN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,eAAA,IAAA;AAUN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,gBAAA,IAAA;AAqBN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,oBAAA,IAAA;AAUN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,cAAA,IAAA;AAcN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,eAAA,IAAA;AA2BN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,YAAA,IAAA;AASN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,cAAA,IAAA;AASN,WAAA,CAAA,MAAM,CAAA,GAAA,sBAAA,WAAA,SAAA,IAAA"}
@@ -32,6 +32,7 @@ export declare class StashGitSubProvider implements GitStashSubProvider {
32
32
  private getStashCommitFilesCore;
33
33
  deleteStash(repoPath: string, stashName: string, sha?: string): Promise<void>;
34
34
  private deleteStashCore;
35
+ private verifyStashSha;
35
36
  renameStash(repoPath: string, stashName: string, sha: string, message: string, stashOnRef?: string): Promise<void>;
36
37
  saveStash(repoPath: string, message?: string, pathsOrUris?: (string | Uri)[], options?: {
37
38
  includeUntracked?: boolean;
@@ -40,6 +41,7 @@ export declare class StashGitSubProvider implements GitStashSubProvider {
40
41
  }, runOptions?: GitOperationRunOptions): Promise<void>;
41
42
  private stashPushCore;
42
43
  saveSnapshot(repoPath: string, message?: string): Promise<void>;
44
+ private announceStashChanged;
43
45
  }
44
46
  export declare function convertStashesToStdin(stashOrStashes: GitStash | ReadonlyMap<string, GitStashCommit> | undefined): {
45
47
  readonly stdin: string | undefined;
@@ -142,28 +142,37 @@ var StashGitSubProvider = class {
142
142
  } : void 0, void 0, void 0, f.mode)) ?? [];
143
143
  }
144
144
  async deleteStash(repoPath, stashName, sha) {
145
- await this.deleteStashCore(repoPath, stashName, sha);
146
- this.context.hooks?.repository?.onChanged?.(repoPath, ["stash"]);
147
- this.context.hooks?.cache?.onReset?.(repoPath, "stashes");
145
+ await this.deleteStashCore(repoPath, stashName, sha, { announce: true });
148
146
  }
149
- async deleteStashCore(repoPath, stashName, sha) {
147
+ async deleteStashCore(repoPath, stashName, sha, options) {
150
148
  if (!stashName) return void 0;
149
+ if (!options.verified) await this.verifyStashSha(repoPath, stashName, sha);
151
150
  let result;
152
- if (sha) {
153
- result = await this.git.run({
154
- cwd: repoPath,
155
- errors: "ignore"
156
- }, "show", "--format=%H", "--no-patch", stashName);
157
- if (result.stdout.trim() !== sha) throw new Error(l10n.t("Unable to delete stash; mismatch with stash number"));
151
+ try {
152
+ result = await this.git.run({ cwd: repoPath }, "stash", "drop", stashName);
153
+ } finally {
154
+ if (options.announce) this.announceStashChanged(repoPath);
158
155
  }
159
- result = await this.git.run({ cwd: repoPath }, "stash", "drop", stashName);
160
156
  return result.stdout;
161
157
  }
158
+ async verifyStashSha(repoPath, stashName, sha) {
159
+ if (!sha) return;
160
+ if ((await this.git.run({
161
+ cwd: repoPath,
162
+ errors: "ignore"
163
+ }, "show", "--format=%H", "--no-patch", stashName)).stdout.trim() !== sha) throw new Error(l10n.t("Unable to delete stash; mismatch with stash number"));
164
+ }
162
165
  async renameStash(repoPath, stashName, sha, message, stashOnRef) {
163
- await this.deleteStashCore(repoPath, stashName, sha);
164
- await this.git.run({ cwd: repoPath }, "stash", "store", "-m", stashOnRef ? `On ${stashOnRef}: ${message}` : message, sha);
165
- this.context.hooks?.repository?.onChanged?.(repoPath, ["stash"]);
166
- this.context.hooks?.cache?.onReset?.(repoPath, "stashes");
166
+ if (stashName) await this.verifyStashSha(repoPath, stashName, sha);
167
+ try {
168
+ await this.deleteStashCore(repoPath, stashName, sha, {
169
+ announce: false,
170
+ verified: true
171
+ });
172
+ await this.git.run({ cwd: repoPath }, "stash", "store", "-m", stashOnRef ? `On ${stashOnRef}: ${message}` : message, sha);
173
+ } finally {
174
+ this.announceStashChanged(repoPath);
175
+ }
167
176
  }
168
177
  async saveStash(repoPath, message, pathsOrUris, options, runOptions) {
169
178
  const paths = pathsOrUris?.map(toFsPath);
@@ -236,9 +245,15 @@ var StashGitSubProvider = class {
236
245
  if (id == null) return;
237
246
  const args = [];
238
247
  if (message) args.push("-m", message);
239
- await this.git.run({ cwd: repoPath }, "stash", "store", ...args, id);
240
- this.context.hooks?.repository?.onChanged?.(repoPath, ["stash"]);
248
+ try {
249
+ await this.git.run({ cwd: repoPath }, "stash", "store", ...args, id);
250
+ } finally {
251
+ this.announceStashChanged(repoPath);
252
+ }
253
+ }
254
+ announceStashChanged(repoPath) {
241
255
  this.context.hooks?.cache?.onReset?.(repoPath, "stashes");
256
+ this.context.hooks?.repository?.onChanged?.(repoPath, ["stash"]);
242
257
  }
243
258
  };
244
259
  __decorate([gate(), debug()], StashGitSubProvider.prototype, "applyStash", null);
@@ -246,7 +261,7 @@ __decorate([debug()], StashGitSubProvider.prototype, "createStash", null);
246
261
  __decorate([debug()], StashGitSubProvider.prototype, "getStash", null);
247
262
  __decorate([debug()], StashGitSubProvider.prototype, "getStashCommitFiles", null);
248
263
  __decorate([debug()], StashGitSubProvider.prototype, "deleteStash", null);
249
- __decorate([gate()], StashGitSubProvider.prototype, "deleteStashCore", null);
264
+ __decorate([gate((rp, name, sha) => `${rp}\0${name}\0${sha ?? ""}`)], StashGitSubProvider.prototype, "deleteStashCore", null);
250
265
  __decorate([debug()], StashGitSubProvider.prototype, "renameStash", null);
251
266
  __decorate([debug({ args: (repoPath, message, paths) => ({
252
267
  repoPath,