@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.
- package/CHANGELOG.md +78 -1
- package/dist/git/cache.d.ts +84 -29
- package/dist/git/cache.js +188 -54
- package/dist/git/cache.js.map +1 -1
- package/dist/git/features.d.ts +1 -1
- package/dist/git/features.js +5 -0
- package/dist/git/features.js.map +1 -1
- package/dist/git/models/branch.d.ts +20 -2
- package/dist/git/models/branch.js +28 -6
- package/dist/git/models/branch.js.map +1 -1
- package/dist/git/models/reference.d.ts +3 -0
- package/dist/git/models/status.js +2 -2
- package/dist/git/models/worktree.d.ts +4 -1
- package/dist/git/models/worktree.js +4 -2
- package/dist/git/models/worktree.js.map +1 -1
- package/dist/git/parsers/diffParser.js +1 -1
- package/dist/git/providers/branches.d.ts +73 -8
- package/dist/git/providers/operations.d.ts +3 -2
- package/dist/git/providers/pausedOperations.d.ts +6 -0
- package/dist/git/providers/provider.d.ts +45 -2
- package/dist/git/providers/revision.d.ts +17 -3
- package/dist/git/providers/status.d.ts +8 -2
- package/dist/git/remotes/azure-devops.js +61 -53
- package/dist/git/remotes/azure-devops.js.map +1 -1
- package/dist/git/run.types.d.ts +12 -0
- package/dist/git/service.d.ts +8 -5
- package/dist/git/service.js +16 -8
- package/dist/git/service.js.map +1 -1
- package/dist/git/utils/branch.utils.d.ts +12 -2
- package/dist/git/utils/branch.utils.js +49 -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/watching/changeEvent.d.ts +13 -2
- package/dist/git/watching/changeEvent.js +17 -3
- package/dist/git/watching/changeEvent.js.map +1 -1
- package/dist/git/watching/gitDirPoller.d.ts +111 -0
- package/dist/git/watching/gitDirPoller.js +266 -0
- package/dist/git/watching/gitDirPoller.js.map +1 -0
- package/dist/git/watching/provider.d.ts +16 -0
- package/dist/git/watching/watchGroup.d.ts +40 -4
- package/dist/git/watching/watchGroup.js +143 -17
- package/dist/git/watching/watchGroup.js.map +1 -1
- package/dist/git/watching/watchService.d.ts +70 -1
- package/dist/git/watching/watchService.js +158 -13
- package/dist/git/watching/watchService.js.map +1 -1
- package/dist/git/watching/watchSession.d.ts +44 -0
- package/dist/git/watching/watchSession.js +91 -6
- package/dist/git/watching/watchSession.js.map +1 -1
- package/dist/git/watching/watcherPatterns.d.ts +21 -0
- package/dist/git/watching/watcherPatterns.js +67 -1
- package/dist/git/watching/watcherPatterns.js.map +1 -1
- package/dist/git/watching/worktreeSummary.d.ts +34 -7
- package/dist/git/watching/worktreeSummary.js +39 -12
- package/dist/git/watching/worktreeSummary.js.map +1 -1
- package/dist/git-cli/cliGitProvider.d.ts +40 -2
- package/dist/git-cli/cliGitProvider.js +182 -18
- package/dist/git-cli/cliGitProvider.js.map +1 -1
- package/dist/git-cli/exec/commandClassifier.d.ts +15 -0
- package/dist/git-cli/exec/commandClassifier.js +48 -2
- package/dist/git-cli/exec/commandClassifier.js.map +1 -1
- package/dist/git-cli/exec/git.d.ts +20 -3
- package/dist/git-cli/exec/git.js +63 -19
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/exec/gitQueue.d.ts +2 -0
- package/dist/git-cli/exec/gitQueue.js +2 -1
- package/dist/git-cli/exec/gitQueue.js.map +1 -1
- package/dist/git-cli/exec/indexLock.d.ts +39 -0
- package/dist/git-cli/exec/indexLock.js +160 -0
- package/dist/git-cli/exec/indexLock.js.map +1 -0
- 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/parsers/worktreeParser.js +42 -2
- package/dist/git-cli/parsers/worktreeParser.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.d.ts +109 -10
- package/dist/git-cli/providers/branches.js +630 -134
- 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.d.ts +9 -5
- package/dist/git-cli/providers/config.js +58 -25
- package/dist/git-cli/providers/config.js.map +1 -1
- 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.d.ts +17 -0
- package/dist/git-cli/providers/operations.js +172 -111
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/pausedOperations.d.ts +8 -0
- package/dist/git-cli/providers/pausedOperations.js +59 -39
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/refs.js +11 -8
- package/dist/git-cli/providers/refs.js.map +1 -1
- package/dist/git-cli/providers/remotes.js +19 -10
- package/dist/git-cli/providers/remotes.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 +39 -14
- package/dist/git-cli/providers/staging.js.map +1 -1
- package/dist/git-cli/providers/stash.d.ts +2 -0
- package/dist/git-cli/providers/stash.js +33 -18
- package/dist/git-cli/providers/stash.js.map +1 -1
- package/dist/git-cli/providers/status.d.ts +3 -1
- package/dist/git-cli/providers/status.js +40 -22
- package/dist/git-cli/providers/status.js.map +1 -1
- package/dist/git-cli/providers/tags.js +6 -4
- package/dist/git-cli/providers/tags.js.map +1 -1
- package/dist/git-cli/providers/worktrees.d.ts +1 -0
- package/dist/git-cli/providers/worktrees.js +60 -31
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/git-cli/service.d.ts +6 -0
- package/dist/git-cli/service.js +5 -2
- package/dist/git-cli/service.js.map +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.d.ts +3 -1
- package/dist/plus/git-github/providers/github/status.js +2 -2
- package/dist/plus/git-github/providers/github/status.js.map +1 -1
- package/dist/plus/integrations/collectionMetadata.d.ts +13 -2
- package/dist/plus/integrations/collectionMetadata.js +14 -2
- package/dist/plus/integrations/collectionMetadata.js.map +1 -1
- package/dist/plus/integrations/index.d.ts +2 -2
- package/dist/plus/integrations/index.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +1 -0
- package/dist/plus/integrations/integrationService.js +1 -1
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/manager.d.ts +1 -0
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +41 -5
- package/dist/plus/integrations/models/gitHostIntegration.js +106 -29
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/issueReads.d.ts +17 -4
- package/dist/plus/integrations/providers/apiClients.d.ts +2 -0
- package/dist/plus/integrations/providers/apiClients.js +7 -1
- package/dist/plus/integrations/providers/apiClients.js.map +1 -1
- package/dist/plus/integrations/providers/azure/azure.d.ts +5 -4
- package/dist/plus/integrations/providers/azure/azure.js +36 -76
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
- package/dist/plus/integrations/providers/azure/azure.utils.js +20 -17
- package/dist/plus/integrations/providers/azure/azure.utils.js.map +1 -1
- package/dist/plus/integrations/providers/azure/models.d.ts +2 -2
- package/dist/plus/integrations/providers/azure/models.js +4 -4
- package/dist/plus/integrations/providers/azure/models.js.map +1 -1
- package/dist/plus/integrations/providers/azure/workItemStateCategories.d.ts +21 -12
- package/dist/plus/integrations/providers/azure/workItemStateCategories.js +74 -17
- package/dist/plus/integrations/providers/azure/workItemStateCategories.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.d.ts +44 -0
- package/dist/plus/integrations/providers/azureDevOps.js +108 -17
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +45 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.js +121 -6
- package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
- package/dist/plus/integrations/providers/jira-server.js +18 -14
- package/dist/plus/integrations/providers/jira-server.js.map +1 -1
- package/dist/plus/integrations/providers/jira.js +18 -14
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/models.d.ts +1 -2
- package/dist/plus/integrations/providers/models.js +9 -2
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/providersApi.d.ts +7 -17
- package/dist/plus/integrations/providers/providersApi.js +85 -78
- package/dist/plus/integrations/providers/providersApi.js.map +1 -1
- package/dist/plus/integrations/providers/utils/jiraIssueDrains.d.ts +22 -0
- package/dist/plus/integrations/providers/utils/jiraIssueDrains.js +69 -9
- package/dist/plus/integrations/providers/utils/jiraIssueDrains.js.map +1 -1
- package/dist/plus/integrations/providers/utils/providerPaging.js +8 -2
- package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
- package/dist/plus/integrations/reads/filters.d.ts +3 -3
- package/dist/plus/integrations/reads/filters.js.map +1 -1
- package/dist/plus/integrations/reads/issueBatch.d.ts +2 -1
- package/dist/plus/integrations/reads/issueBatch.js +1 -1
- package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +23 -14
- package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
- package/dist/plus/integrations/reads/issues.d.ts +2 -1
- package/dist/plus/integrations/reads/issues.js +18 -3
- package/dist/plus/integrations/reads/issues.js.map +1 -1
- package/dist/plus/integrations/reads/pullRequestBatch.js +1 -1
- package/dist/plus/integrations/reads/resolveRepository.js +12 -3
- package/dist/plus/integrations/reads/resolveRepository.js.map +1 -1
- package/dist/plus/integrations/reads/warnings.d.ts +11 -4
- package/dist/plus/integrations/reads/warnings.js +15 -5
- package/dist/plus/integrations/reads/warnings.js.map +1 -1
- package/dist/plus/integrations/results.d.ts +36 -2
- package/dist/plus/integrations/results.js +33 -13
- package/dist/plus/integrations/results.js.map +1 -1
- package/dist/utils/promiseCache.d.ts +10 -0
- package/dist/utils/promiseCache.js +17 -2
- package/dist/utils/promiseCache.js.map +1 -1
- package/docs/integrations.md +52 -20
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stash.js","names":[],"sources":["../../../../git-cli/src/providers/stash.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { StashApplyError, StashPushError } from '@gitlens/git/errors.js';\nimport type { GitStashCommit } from '@gitlens/git/models/commit.js';\nimport { GitCommit, GitCommitIdentity } from '@gitlens/git/models/commit.js';\nimport { GitFileChange } from '@gitlens/git/models/fileChange.js';\nimport type { GitFileStatus } from '@gitlens/git/models/fileStatus.js';\nimport { GitFileWorkingTreeStatus } from '@gitlens/git/models/fileStatus.js';\nimport type { GitStash } from '@gitlens/git/models/stash.js';\nimport type { GitUser } from '@gitlens/git/models/user.js';\nimport type { GitOperationRunOptions } from '@gitlens/git/providers/operations.js';\nimport type { GitStashSubProvider, StashApplyResult } from '@gitlens/git/providers/stash.js';\nimport { countStringLength } from '@gitlens/utils/array.js';\nimport { isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { skip } from '@gitlens/utils/iterable.js';\nimport { normalizePath, splitPath } from '@gitlens/utils/path.js';\nimport { getSettledValue } from '@gitlens/utils/promise.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fileUri, joinUriPath, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport { gitFeaturesByVersion } from '../exec/features.js';\nimport type { Git } from '../exec/git.js';\nimport { getGitCommandError, GitError, GitErrors, maxGitCliLength } from '../exec/git.js';\nimport type { ParsedStash, ParsedStashWithFiles } from '../parsers/logParser.js';\nimport { getStashFilesOnlyLogParser, getStashLogParser } from '../parsers/logParser.js';\nimport { createCommitFileset } from './commitFilesetUtils.js';\n\nexport class StashGitSubProvider implements GitStashSubProvider {\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@gate()\n\t@debug()\n\tasync applyStash(\n\t\trepoPath: string,\n\t\tstashNameOrSha: string,\n\t\toptions?: { deleteAfter?: boolean; index?: boolean },\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<StashApplyResult> {\n\t\tif (!stashNameOrSha) return { conflicted: false };\n\n\t\tconst args = ['stash', options?.deleteAfter ? 'pop' : 'apply'];\n\t\tif (options?.index) {\n\t\t\targs.push('--index');\n\t\t}\n\t\targs.push(stashNameOrSha);\n\t\treturn this.applyStashCore(repoPath, args, options?.deleteAfter ? 'stash-pop' : 'stash-apply', runOptions);\n\t}\n\n\tprivate async applyStashCore(\n\t\trepoPath: string,\n\t\targs: string[],\n\t\tconflictCommand: 'stash-apply' | 'stash-pop',\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<StashApplyResult> {\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, ...runOptions }, ...args);\n\t\t\treturn { conflicted: false };\n\t\t} catch (ex) {\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tif (ex instanceof Error) {\n\t\t\t\tconst msg: string = ex.message ?? '';\n\t\t\t\tif (\n\t\t\t\t\t(msg.includes('Auto-merging') && msg.includes('CONFLICT')) ||\n\t\t\t\t\t(ex instanceof GitError &&\n\t\t\t\t\t\t((ex.stdout?.includes('Auto-merging') && ex.stdout.includes('CONFLICT')) ||\n\t\t\t\t\t\t\tex.stdout?.includes('needs merge')))\n\t\t\t\t) {\n\t\t\t\t\tthis.context.hooks?.operations?.onConflicted?.(conflictCommand);\n\t\t\t\t\treturn { conflicted: true };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'stash-apply',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew StashApplyError(\n\t\t\t\t\t\t{ reason: reason ?? 'other', gitCommand: { repoPath: repoPath, args: args } },\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// A conflicted, failed or cancelled apply may already have changed the stash list or working tree\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes', 'status');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash']);\n\t\t}\n\t}\n\n\t@debug()\n\tasync createStash(repoPath: string, message?: string): Promise<string | undefined> {\n\t\tconst args = ['stash', 'create'];\n\t\tif (message) {\n\t\t\targs.push(message);\n\t\t}\n\n\t\tconst result = await this.git.run({ cwd: repoPath }, ...args);\n\t\treturn result.stdout.trim() || undefined;\n\t}\n\n\t@debug()\n\tasync getStash(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tincludeFiles?: boolean;\n\t\t\treachableFrom?: string;\n\t\t\tsimilarityThreshold?: number | null;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStash | undefined> {\n\t\tif (repoPath == null) return undefined;\n\n\t\t// Resolve options against config up front so the cache key reflects the actual values used\n\t\t// to produce the cached payload — undefined inputs aren't conflated across config changes.\n\t\tconst cfg = this.context.config;\n\t\tconst includeFiles = options?.includeFiles ?? cfg?.commits.includeFileDetails?.(repoPath) ?? true;\n\t\tconst similarityThreshold = includeFiles\n\t\t\t? (options?.similarityThreshold ?? cfg?.commits.similarityThreshold ?? null)\n\t\t\t: null;\n\t\tconst reachableFrom = options?.reachableFrom;\n\n\t\t// Cache only the unfiltered stash list; reachability projection runs below by testing each\n\t\t// distinct stash parent against `reachableFrom` directly, so re-projecting is cheap\n\t\tconst cacheKey = `f${includeFiles ? 1 : 0}|s${similarityThreshold ?? ''}`;\n\n\t\tconst stash = await this.cache.getStash(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\tasync (commonPath, _cacheable, signal) => {\n\t\t\t\t// Prefer the aggregate signal from the cache; fall back to the caller's cancellation.\n\t\t\t\tsignal ??= cancellation;\n\t\t\t\tconst parser = getStashLogParser(includeFiles);\n\t\t\t\tconst args = [...parser.arguments];\n\n\t\t\t\tif (includeFiles) {\n\t\t\t\t\targs.push(`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`);\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.git.run({ cwd: repoPath, cancellation: signal }, 'stash', 'list', ...args);\n\n\t\t\t\tconst currentUser = await this.provider.config.getCurrentUser(repoPath);\n\n\t\t\t\tconst stashes = new Map<string, GitStashCommit>();\n\t\t\t\tfor (const s of parser.parse(result.stdout)) {\n\t\t\t\t\tstashes.set(s.sha, createStash(s, commonPath, currentUser));\n\t\t\t\t}\n\n\t\t\t\treturn { repoPath: commonPath, stashes: stashes };\n\t\t\t},\n\t\t\t{ cancellation: cancellation },\n\t\t);\n\n\t\tif (stash == null || !reachableFrom || !stash.stashes.size) return stash;\n\n\t\t// Copy because the cached `stash.stashes` map is shared and must not be mutated.\n\t\tconst stashes = new Map(stash.stashes);\n\n\t\tconst reachableStashes = new Set<string>();\n\n\t\t// Metadata pass: a stash belongs on `reachableFrom` iff git's auto-prepended\n\t\t// `On <branch>: …` (or `WIP on <branch>: …`) prefix in the stash commit subject names\n\t\t// this branch. `stashOnRef` is parsed from %s in createStash, so this covers autostashes\n\t\t// and custom-reflog stashes too.\n\t\tfor (const [sha, s] of stash.stashes) {\n\t\t\tif (s.stashOnRef === reachableFrom) {\n\t\t\t\treachableStashes.add(sha);\n\t\t\t}\n\t\t}\n\n\t\t// Transitive pass for the rare detached-HEAD-on-stash chain (stash B created while HEAD\n\t\t// pointed at stash A). Such stashes have no `stashOnRef`, but if their parent is a stash\n\t\t// already marked reachable they should follow.\n\t\tlet changed;\n\t\tdo {\n\t\t\tchanged = false;\n\t\t\tfor (const [sha, s] of stash.stashes) {\n\t\t\t\tif (!reachableStashes.has(sha) && s.parents.some(p => reachableStashes.has(p))) {\n\t\t\t\t\treachableStashes.add(sha);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t} while (changed);\n\n\t\tfor (const [sha] of stash.stashes) {\n\t\t\tif (!reachableStashes.has(sha)) {\n\t\t\t\tstashes.delete(sha);\n\t\t\t}\n\t\t}\n\n\t\treturn { ...stash, stashes: stashes };\n\t}\n\n\t@debug()\n\tasync getStashCommitFiles(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { similarityThreshold?: number | null },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitFileChange[]> {\n\t\tconst [stashFilesResult, stashUntrackedFilesResult] = await Promise.allSettled([\n\t\t\t// Don't include untracked files here, because we won't be able to tell them apart from added (and we need the untracked status)\n\t\t\tthis.getStashCommitFilesCore(repoPath, ref, { untracked: false, ...options }, cancellation),\n\t\t\t// Check for any untracked files -- since git doesn't return them via `git stash list` :(\n\t\t\t// See https://stackoverflow.com/questions/12681529/\n\t\t\tthis.getStashCommitFilesCore(repoPath, ref, { untracked: 'only', ...options }, cancellation),\n\t\t]);\n\n\t\tlet files = getSettledValue(stashFilesResult);\n\t\tconst untrackedFiles = getSettledValue(stashUntrackedFilesResult);\n\n\t\tif (files?.length && untrackedFiles?.length) {\n\t\t\tfiles.push(...untrackedFiles);\n\t\t} else {\n\t\t\tfiles = files ?? untrackedFiles;\n\t\t}\n\n\t\treturn files ?? [];\n\t}\n\n\tprivate async getStashCommitFilesCore(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { similarityThreshold?: number | null; untracked?: boolean | 'only' },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitFileChange[] | undefined> {\n\t\tconst args = [];\n\t\tif (options?.untracked) {\n\t\t\targs.push(options?.untracked === 'only' ? '--only-untracked' : '--include-untracked');\n\t\t}\n\n\t\tconst similarityThreshold = options?.similarityThreshold ?? this.context.config?.commits.similarityThreshold;\n\t\tif (similarityThreshold != null) {\n\t\t\targs.push(`-M${similarityThreshold}%`);\n\t\t}\n\n\t\tconst parser = getStashFilesOnlyLogParser();\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation },\n\t\t\t'stash',\n\t\t\t'show',\n\t\t\t...args,\n\t\t\t...parser.arguments,\n\t\t\tref,\n\t\t);\n\n\t\tconst repoUri = fileUri(normalizePath(repoPath));\n\t\tfor (const s of parser.parse(result.stdout)) {\n\t\t\treturn (\n\t\t\t\ts.files?.map(\n\t\t\t\t\tf =>\n\t\t\t\t\t\tnew GitFileChange(\n\t\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\t\tf.path,\n\t\t\t\t\t\t\t(options?.untracked === 'only'\n\t\t\t\t\t\t\t\t? GitFileWorkingTreeStatus.Untracked\n\t\t\t\t\t\t\t\t: f.status) as GitFileStatus,\n\t\t\t\t\t\t\tjoinUriPath(repoUri, normalizePath(f.path)),\n\t\t\t\t\t\t\tf.originalPath,\n\t\t\t\t\t\t\tf.originalPath != null ? joinUriPath(repoUri, normalizePath(f.originalPath)) : undefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tf.additions || f.deletions\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tadditions: f.additions ?? 0,\n\t\t\t\t\t\t\t\t\t\tdeletions: f.deletions ?? 0,\n\t\t\t\t\t\t\t\t\t\tchanges: 0,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tf.mode,\n\t\t\t\t\t\t),\n\t\t\t\t) ?? []\n\t\t\t);\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t@debug()\n\tasync deleteStash(repoPath: string, stashName: string, sha?: string): Promise<void> {\n\t\tawait this.deleteStashCore(repoPath, stashName, sha);\n\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash']);\n\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes');\n\t}\n\n\t@gate()\n\tprivate async deleteStashCore(repoPath: string, stashName: string, sha?: string): Promise<string | undefined> {\n\t\tif (!stashName) return undefined;\n\n\t\tlet result;\n\t\tif (sha) {\n\t\t\tresult = await this.git.run(\n\t\t\t\t{ cwd: repoPath, errors: 'ignore' },\n\t\t\t\t'show',\n\t\t\t\t'--format=%H',\n\t\t\t\t'--no-patch',\n\t\t\t\tstashName,\n\t\t\t);\n\t\t\tif (result.stdout.trim() !== sha) {\n\t\t\t\tthrow new Error(l10n.t('Unable to delete stash; mismatch with stash number'));\n\t\t\t}\n\t\t}\n\n\t\tresult = await this.git.run({ cwd: repoPath }, 'stash', 'drop', stashName);\n\t\treturn result.stdout;\n\t}\n\n\t@debug()\n\tasync renameStash(\n\t\trepoPath: string,\n\t\tstashName: string,\n\t\tsha: string,\n\t\tmessage: string,\n\t\tstashOnRef?: string,\n\t): Promise<void> {\n\t\tawait this.deleteStashCore(repoPath, stashName, sha);\n\t\tawait this.git.run(\n\t\t\t{ cwd: repoPath },\n\t\t\t'stash',\n\t\t\t'store',\n\t\t\t'-m',\n\t\t\tstashOnRef ? `On ${stashOnRef}: ${message}` : message,\n\t\t\tsha,\n\t\t);\n\n\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash']);\n\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes');\n\t}\n\n\t@debug({ args: (repoPath, message, paths) => ({ repoPath: repoPath, message: message, paths: paths?.length }) })\n\tasync saveStash(\n\t\trepoPath: string,\n\t\tmessage?: string,\n\t\tpathsOrUris?: (string | Uri)[],\n\t\toptions?: { includeUntracked?: boolean; keepIndex?: boolean; onlyStaged?: boolean },\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst paths = pathsOrUris?.map(toFsPath);\n\t\tif (!paths?.length) {\n\t\t\tawait this.stashPushCore(repoPath, message, options, runOptions);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.git.ensureSupports('git:stash:push:pathspecs', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Stashing individual files requires a newer version of Git (>= {0}) than is currently installed ({1}). Please retry by stashing everything or install a more recent version of Git and try again.',\n\t\t\t\trequiredVersion,\n\t\t\t\tinstalledVersion,\n\t\t\t),\n\t\t);\n\n\t\tconst pathspecs = paths.map(p => `./${splitPath(p, repoPath)[0]}`);\n\n\t\tlet stdin = await this.git.supports('git:stash:push:stdin');\n\t\tif (stdin && options?.onlyStaged && paths.length) {\n\t\t\t// Since Git doesn't support --staged with --pathspec-from-file try to pass them in directly\n\t\t\tstdin = false;\n\t\t}\n\n\t\t// If we don't support stdin, then error out if we are over the maximum allowed git cli length\n\t\tif (!stdin && countStringLength(pathspecs) > maxGitCliLength) {\n\t\t\tawait this.git.ensureSupports('git:stash:push:stdin', (requiredVersion, installedVersion) =>\n\t\t\t\tl10n.t(\n\t\t\t\t\t'Stashing so many files ({0}) at once requires a newer version of Git (>= {1}) than is currently installed ({2}). Please retry by stashing fewer files or install a more recent version of Git and try again.',\n\t\t\t\t\tpathspecs.length,\n\t\t\t\t\trequiredVersion,\n\t\t\t\t\tinstalledVersion,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tawait this.stashPushCore(\n\t\t\trepoPath,\n\t\t\tmessage,\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tpathspecs: pathspecs,\n\t\t\t\tstdin: stdin,\n\t\t\t},\n\t\t\trunOptions,\n\t\t);\n\t}\n\n\tprivate async stashPushCore(\n\t\trepoPath: string,\n\t\tmessage?: string,\n\t\toptions?: {\n\t\t\tincludeUntracked?: boolean;\n\t\t\tkeepIndex?: boolean;\n\t\t\tonlyStaged?: boolean;\n\t\t\tpathspecs?: string[];\n\t\t\tstdin?: boolean;\n\t\t},\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst params = ['stash', 'push'];\n\n\t\tif ((options?.includeUntracked || options?.pathspecs?.length) && !options?.onlyStaged) {\n\t\t\tparams.push('--include-untracked');\n\t\t}\n\n\t\t// `git stash push --keep-index --include-untracked -- <pathspec>` hits a bug in git when the\n\t\t// pathspec names an untracked file: the restoring checkout can't match an untracked path in the\n\t\t// index tree, so it fails and the staged changes are lost.\n\t\t//\n\t\t// $ mkdir stash-test && cd stash-test && git init\n\t\t// $ echo a > a.txt\n\t\t// $ git add a.txt\n\t\t// $ git commit -m init\n\t\t// $ echo b > b.txt\n\t\t// $ git stash push --keep-index --include-untracked -- b.txt\n\t\t// Saved working directory and index state WIP on main: 8a280fe init\n\t\t// error: pathspec ':(prefix:0)b.txt' did not match any file(s) known to git\n\t\t//\n\t\t// Only suppress --keep-index for that case — when the selection actually includes untracked\n\t\t// files (`includeUntracked`) AND we're stashing by pathspec. Keying off `includeUntracked` (the\n\t\t// caller's intent) rather than the `--include-untracked` flag is deliberate: we add\n\t\t// `--include-untracked` to every pathspec push above as a safety net, but a tracked-only\n\t\t// selection can — and must — still keep the index intact.\n\t\tif (options?.keepIndex && !(options?.includeUntracked && options?.pathspecs?.length)) {\n\t\t\tparams.push('--keep-index');\n\t\t}\n\n\t\tif (options?.onlyStaged) {\n\t\t\tif (await this.git.supports('git:stash:push:staged')) {\n\t\t\t\tparams.push('--staged');\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Git version {0} or higher is required for --staged',\n\t\t\t\t\t\tString(gitFeaturesByVersion.get('git:stash:push:staged')),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (message) {\n\t\t\tparams.push('-m', message);\n\t\t}\n\n\t\tlet stdin;\n\t\tif (options?.pathspecs?.length) {\n\t\t\tif (options.stdin) {\n\t\t\t\tstdin = options.pathspecs.join('\\0');\n\t\t\t\tparams.push('--pathspec-from-file=-', '--pathspec-file-nul', '--');\n\t\t\t} else {\n\t\t\t\tparams.push('--', ...options.pathspecs);\n\t\t\t}\n\t\t} else {\n\t\t\tparams.push('--');\n\t\t}\n\n\t\tlet nothingToSave = false;\n\t\ttry {\n\t\t\tconst result = await this.git.run({ cwd: repoPath, ...runOptions, stdin: stdin }, ...params);\n\t\t\tif (GitErrors.stashNothingToSave.test(result.stdout)) {\n\t\t\t\tnothingToSave = true;\n\t\t\t\tthrow new StashPushError({\n\t\t\t\t\treason: 'nothingToSave',\n\t\t\t\t\tgitCommand: { repoPath: repoPath, args: params },\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof StashPushError || isCancellationError(ex)) throw ex;\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'stash-push',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew StashPushError(\n\t\t\t\t\t\t{ reason: reason ?? 'other', gitCommand: { repoPath: repoPath, args: params } },\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// A failed or cancelled push may already have stashed, and reset the working tree; one with nothing to\n\t\t\t// save changed nothing\n\t\t\tif (!nothingToSave) {\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes', 'status');\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash']);\n\t\t\t}\n\t\t}\n\t}\n\n\t@debug()\n\tasync saveSnapshot(repoPath: string, message?: string): Promise<void> {\n\t\tconst result = await this.git.run({ cwd: repoPath }, 'stash', 'create');\n\t\tconst id = result.stdout.trim() || undefined;\n\t\tif (id == null) return;\n\n\t\tconst args = [];\n\t\tif (message) {\n\t\t\targs.push('-m', message);\n\t\t}\n\t\tawait this.git.run({ cwd: repoPath }, 'stash', 'store', ...args, id);\n\n\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash']);\n\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes');\n\t}\n}\n\nexport function convertStashesToStdin(stashOrStashes: GitStash | ReadonlyMap<string, GitStashCommit> | undefined): {\n\treadonly stdin: string | undefined;\n\treadonly stashes: Map<string, GitStashCommit>;\n\treadonly remappedIds: Map<string, string>;\n} {\n\tconst remappedIds = new Map<string, string>();\n\tif (stashOrStashes == null) return { stdin: undefined, stashes: new Map(), remappedIds: remappedIds };\n\n\tlet stdin: string | undefined;\n\tconst original = 'stashes' in stashOrStashes ? stashOrStashes.stashes : stashOrStashes;\n\tconst stashes = new Map<string, GitStashCommit>(original);\n\n\tif (original.size) {\n\t\tstdin = '';\n\t\tfor (const stash of original.values()) {\n\t\t\tstdin += `${stash.sha.substring(0, 9)}\\n`;\n\t\t\t// Include the stash's 2nd (index files) and 3rd (untracked files) parents (if they aren't already in the map)\n\t\t\tfor (const p of skip(stash.parents, 1)) {\n\t\t\t\tremappedIds.set(p, stash.sha);\n\n\t\t\t\tif (!stashes.has(p)) {\n\t\t\t\t\tstashes.set(p, stash);\n\t\t\t\t\tstdin += `${p.substring(0, 9)}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { stdin: stdin || undefined, stashes: stashes, remappedIds: remappedIds };\n}\n\nconst stashSummaryRegex =\n\t// oxlint-disable-next-line no-control-regex\n\t/(?:(?:(?<wip>WIP) on|On) (?<onref>[^/](?!.*\\/\\.)(?!.*\\.\\.)(?!.*\\/\\/)(?!.*@\\{)[^\\x00-\\x1F\\x7F ~^:?*[\\\\]+[^./]):\\s*)?(?<summary>.*)$/s;\n\nfunction createStash(\n\ts: ParsedStash | ParsedStashWithFiles,\n\trepoPath: string,\n\tcurrentUser: GitUser | undefined,\n): GitStashCommit {\n\t// `onRef` comes from the commit subject (%s), which git always prefixes with `On <branch>: …`\n\t// or `WIP on <branch>: …`. This holds even when the reflog message was customized\n\t// (autostash, `git stash store -m \"…\"`), so it's a reliable source\n\tlet onRef: string | undefined;\n\tconst subjectMatch = stashSummaryRegex.exec((s.commitSubject ?? '').trim());\n\tif (subjectMatch?.groups?.onref) {\n\t\tonRef = subjectMatch.groups.onref;\n\t}\n\n\t// The user-visible display message is derived from the reflog subject (%gs) so that short\n\t// custom messages like \"wip\", \"q\", or \"show args\" stay as the user wrote them instead of\n\t// being replaced by the verbose git-auto subject\n\tlet message = s.summary.trim();\n\tconst reflogMatch = stashSummaryRegex.exec(message);\n\tif (reflogMatch?.groups != null) {\n\t\tconst summary = reflogMatch.groups.summary.trim();\n\t\tif (summary.length === 0) {\n\t\t\tmessage = 'WIP';\n\t\t} else if (reflogMatch.groups.wip) {\n\t\t\tmessage = `WIP: ${summary}`;\n\t\t} else {\n\t\t\tmessage = summary;\n\t\t}\n\t}\n\n\tconst index = message.indexOf('\\n');\n\n\treturn new GitCommit(\n\t\trepoPath,\n\t\ts.sha,\n\t\tnew GitCommitIdentity(\n\t\t\tcurrentUser?.name ?? '',\n\t\t\tcurrentUser?.email,\n\t\t\tnew Date(Number(s.authorDate) * 1000),\n\t\t\tundefined,\n\t\t\ttrue,\n\t\t),\n\t\tnew GitCommitIdentity(\n\t\t\tcurrentUser?.name ?? '',\n\t\t\tcurrentUser?.email,\n\t\t\tnew Date(Number(s.committedDate) * 1000),\n\t\t\tundefined,\n\t\t\ttrue,\n\t\t),\n\t\tindex !== -1 ? message.substring(0, index) : message,\n\t\ts.parents.split(' ') ?? [],\n\t\tmessage,\n\t\tcreateCommitFileset(s, repoPath, undefined),\n\t\ts.stats,\n\t\tundefined,\n\t\tundefined,\n\t\ts.stashName,\n\t\tonRef,\n\t) as GitStashCommit;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stash.js","names":[],"sources":["../../../../git-cli/src/providers/stash.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { StashApplyError, StashPushError } from '@gitlens/git/errors.js';\nimport type { GitStashCommit } from '@gitlens/git/models/commit.js';\nimport { GitCommit, GitCommitIdentity } from '@gitlens/git/models/commit.js';\nimport { GitFileChange } from '@gitlens/git/models/fileChange.js';\nimport type { GitFileStatus } from '@gitlens/git/models/fileStatus.js';\nimport { GitFileWorkingTreeStatus } from '@gitlens/git/models/fileStatus.js';\nimport type { GitStash } from '@gitlens/git/models/stash.js';\nimport type { GitUser } from '@gitlens/git/models/user.js';\nimport type { GitOperationRunOptions } from '@gitlens/git/providers/operations.js';\nimport type { GitStashSubProvider, StashApplyResult } from '@gitlens/git/providers/stash.js';\nimport { countStringLength } from '@gitlens/utils/array.js';\nimport { isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { skip } from '@gitlens/utils/iterable.js';\nimport { normalizePath, splitPath } from '@gitlens/utils/path.js';\nimport { getSettledValue } from '@gitlens/utils/promise.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fileUri, joinUriPath, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport { gitFeaturesByVersion } from '../exec/features.js';\nimport type { Git } from '../exec/git.js';\nimport { getGitCommandError, GitError, GitErrors, maxGitCliLength } from '../exec/git.js';\nimport type { ParsedStash, ParsedStashWithFiles } from '../parsers/logParser.js';\nimport { getStashFilesOnlyLogParser, getStashLogParser } from '../parsers/logParser.js';\nimport { createCommitFileset } from './commitFilesetUtils.js';\n\nexport class StashGitSubProvider implements GitStashSubProvider {\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@gate()\n\t@debug()\n\tasync applyStash(\n\t\trepoPath: string,\n\t\tstashNameOrSha: string,\n\t\toptions?: { deleteAfter?: boolean; index?: boolean },\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<StashApplyResult> {\n\t\tif (!stashNameOrSha) return { conflicted: false };\n\n\t\tconst args = ['stash', options?.deleteAfter ? 'pop' : 'apply'];\n\t\tif (options?.index) {\n\t\t\targs.push('--index');\n\t\t}\n\t\targs.push(stashNameOrSha);\n\t\treturn this.applyStashCore(repoPath, args, options?.deleteAfter ? 'stash-pop' : 'stash-apply', runOptions);\n\t}\n\n\tprivate async applyStashCore(\n\t\trepoPath: string,\n\t\targs: string[],\n\t\tconflictCommand: 'stash-apply' | 'stash-pop',\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<StashApplyResult> {\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, ...runOptions }, ...args);\n\t\t\treturn { conflicted: false };\n\t\t} catch (ex) {\n\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\tif (ex instanceof Error) {\n\t\t\t\tconst msg: string = ex.message ?? '';\n\t\t\t\tif (\n\t\t\t\t\t(msg.includes('Auto-merging') && msg.includes('CONFLICT')) ||\n\t\t\t\t\t(ex instanceof GitError &&\n\t\t\t\t\t\t((ex.stdout?.includes('Auto-merging') && ex.stdout.includes('CONFLICT')) ||\n\t\t\t\t\t\t\tex.stdout?.includes('needs merge')))\n\t\t\t\t) {\n\t\t\t\t\tthis.context.hooks?.operations?.onConflicted?.(conflictCommand);\n\t\t\t\t\treturn { conflicted: true };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'stash-apply',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew StashApplyError(\n\t\t\t\t\t\t{ reason: reason ?? 'other', gitCommand: { repoPath: repoPath, args: args } },\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// A conflicted, failed or cancelled apply may already have changed the stash list or working tree\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes', 'status');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash']);\n\t\t}\n\t}\n\n\t@debug()\n\tasync createStash(repoPath: string, message?: string): Promise<string | undefined> {\n\t\tconst args = ['stash', 'create'];\n\t\tif (message) {\n\t\t\targs.push(message);\n\t\t}\n\n\t\tconst result = await this.git.run({ cwd: repoPath }, ...args);\n\t\treturn result.stdout.trim() || undefined;\n\t}\n\n\t@debug()\n\tasync getStash(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tincludeFiles?: boolean;\n\t\t\treachableFrom?: string;\n\t\t\tsimilarityThreshold?: number | null;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStash | undefined> {\n\t\tif (repoPath == null) return undefined;\n\n\t\t// Resolve options against config up front so the cache key reflects the actual values used\n\t\t// to produce the cached payload — undefined inputs aren't conflated across config changes.\n\t\tconst cfg = this.context.config;\n\t\tconst includeFiles = options?.includeFiles ?? cfg?.commits.includeFileDetails?.(repoPath) ?? true;\n\t\tconst similarityThreshold = includeFiles\n\t\t\t? (options?.similarityThreshold ?? cfg?.commits.similarityThreshold ?? null)\n\t\t\t: null;\n\t\tconst reachableFrom = options?.reachableFrom;\n\n\t\t// Cache only the unfiltered stash list; reachability projection runs below by testing each\n\t\t// distinct stash parent against `reachableFrom` directly, so re-projecting is cheap\n\t\tconst cacheKey = `f${includeFiles ? 1 : 0}|s${similarityThreshold ?? ''}`;\n\n\t\tconst stash = await this.cache.getStash(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\tasync (commonPath, _cacheable, signal) => {\n\t\t\t\t// Prefer the aggregate signal from the cache; fall back to the caller's cancellation.\n\t\t\t\tsignal ??= cancellation;\n\t\t\t\tconst parser = getStashLogParser(includeFiles);\n\t\t\t\tconst args = [...parser.arguments];\n\n\t\t\t\tif (includeFiles) {\n\t\t\t\t\targs.push(`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`);\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.git.run({ cwd: repoPath, cancellation: signal }, 'stash', 'list', ...args);\n\n\t\t\t\tconst currentUser = await this.provider.config.getCurrentUser(repoPath);\n\n\t\t\t\tconst stashes = new Map<string, GitStashCommit>();\n\t\t\t\tfor (const s of parser.parse(result.stdout)) {\n\t\t\t\t\tstashes.set(s.sha, createStash(s, commonPath, currentUser));\n\t\t\t\t}\n\n\t\t\t\treturn { repoPath: commonPath, stashes: stashes };\n\t\t\t},\n\t\t\t{ cancellation: cancellation },\n\t\t);\n\n\t\tif (stash == null || !reachableFrom || !stash.stashes.size) return stash;\n\n\t\t// Copy because the cached `stash.stashes` map is shared and must not be mutated.\n\t\tconst stashes = new Map(stash.stashes);\n\n\t\tconst reachableStashes = new Set<string>();\n\n\t\t// Metadata pass: a stash belongs on `reachableFrom` iff git's auto-prepended\n\t\t// `On <branch>: …` (or `WIP on <branch>: …`) prefix in the stash commit subject names\n\t\t// this branch. `stashOnRef` is parsed from %s in createStash, so this covers autostashes\n\t\t// and custom-reflog stashes too.\n\t\tfor (const [sha, s] of stash.stashes) {\n\t\t\tif (s.stashOnRef === reachableFrom) {\n\t\t\t\treachableStashes.add(sha);\n\t\t\t}\n\t\t}\n\n\t\t// Transitive pass for the rare detached-HEAD-on-stash chain (stash B created while HEAD\n\t\t// pointed at stash A). Such stashes have no `stashOnRef`, but if their parent is a stash\n\t\t// already marked reachable they should follow.\n\t\tlet changed;\n\t\tdo {\n\t\t\tchanged = false;\n\t\t\tfor (const [sha, s] of stash.stashes) {\n\t\t\t\tif (!reachableStashes.has(sha) && s.parents.some(p => reachableStashes.has(p))) {\n\t\t\t\t\treachableStashes.add(sha);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t} while (changed);\n\n\t\tfor (const [sha] of stash.stashes) {\n\t\t\tif (!reachableStashes.has(sha)) {\n\t\t\t\tstashes.delete(sha);\n\t\t\t}\n\t\t}\n\n\t\treturn { ...stash, stashes: stashes };\n\t}\n\n\t@debug()\n\tasync getStashCommitFiles(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { similarityThreshold?: number | null },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitFileChange[]> {\n\t\tconst [stashFilesResult, stashUntrackedFilesResult] = await Promise.allSettled([\n\t\t\t// Don't include untracked files here, because we won't be able to tell them apart from added (and we need the untracked status)\n\t\t\tthis.getStashCommitFilesCore(repoPath, ref, { untracked: false, ...options }, cancellation),\n\t\t\t// Check for any untracked files -- since git doesn't return them via `git stash list` :(\n\t\t\t// See https://stackoverflow.com/questions/12681529/\n\t\t\tthis.getStashCommitFilesCore(repoPath, ref, { untracked: 'only', ...options }, cancellation),\n\t\t]);\n\n\t\tlet files = getSettledValue(stashFilesResult);\n\t\tconst untrackedFiles = getSettledValue(stashUntrackedFilesResult);\n\n\t\tif (files?.length && untrackedFiles?.length) {\n\t\t\tfiles.push(...untrackedFiles);\n\t\t} else {\n\t\t\tfiles = files ?? untrackedFiles;\n\t\t}\n\n\t\treturn files ?? [];\n\t}\n\n\tprivate async getStashCommitFilesCore(\n\t\trepoPath: string,\n\t\tref: string,\n\t\toptions?: { similarityThreshold?: number | null; untracked?: boolean | 'only' },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitFileChange[] | undefined> {\n\t\tconst args = [];\n\t\tif (options?.untracked) {\n\t\t\targs.push(options?.untracked === 'only' ? '--only-untracked' : '--include-untracked');\n\t\t}\n\n\t\tconst similarityThreshold = options?.similarityThreshold ?? this.context.config?.commits.similarityThreshold;\n\t\tif (similarityThreshold != null) {\n\t\t\targs.push(`-M${similarityThreshold}%`);\n\t\t}\n\n\t\tconst parser = getStashFilesOnlyLogParser();\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, cancellation: cancellation },\n\t\t\t'stash',\n\t\t\t'show',\n\t\t\t...args,\n\t\t\t...parser.arguments,\n\t\t\tref,\n\t\t);\n\n\t\tconst repoUri = fileUri(normalizePath(repoPath));\n\t\tfor (const s of parser.parse(result.stdout)) {\n\t\t\treturn (\n\t\t\t\ts.files?.map(\n\t\t\t\t\tf =>\n\t\t\t\t\t\tnew GitFileChange(\n\t\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\t\tf.path,\n\t\t\t\t\t\t\t(options?.untracked === 'only'\n\t\t\t\t\t\t\t\t? GitFileWorkingTreeStatus.Untracked\n\t\t\t\t\t\t\t\t: f.status) as GitFileStatus,\n\t\t\t\t\t\t\tjoinUriPath(repoUri, normalizePath(f.path)),\n\t\t\t\t\t\t\tf.originalPath,\n\t\t\t\t\t\t\tf.originalPath != null ? joinUriPath(repoUri, normalizePath(f.originalPath)) : undefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tf.additions || f.deletions\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tadditions: f.additions ?? 0,\n\t\t\t\t\t\t\t\t\t\tdeletions: f.deletions ?? 0,\n\t\t\t\t\t\t\t\t\t\tchanges: 0,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tf.mode,\n\t\t\t\t\t\t),\n\t\t\t\t) ?? []\n\t\t\t);\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t@debug()\n\tasync deleteStash(repoPath: string, stashName: string, sha?: string): Promise<void> {\n\t\tawait this.deleteStashCore(repoPath, stashName, sha, { announce: true });\n\t}\n\n\t// Keyed without `options`, so a delete and a rename of the same stash share one drop: a second drop would take\n\t// the stash that moved up into its place\n\t@gate((rp, name, sha) => `${rp}\\0${name}\\0${sha ?? ''}`)\n\tprivate async deleteStashCore(\n\t\trepoPath: string,\n\t\tstashName: string,\n\t\tsha: string | undefined,\n\t\toptions: { announce: boolean; verified?: boolean },\n\t): Promise<string | undefined> {\n\t\tif (!stashName) return undefined;\n\n\t\tif (!options.verified) {\n\t\t\tawait this.verifyStashSha(repoPath, stashName, sha);\n\t\t}\n\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await this.git.run({ cwd: repoPath }, 'stash', 'drop', stashName);\n\t\t} finally {\n\t\t\tif (options.announce) {\n\t\t\t\tthis.announceStashChanged(repoPath);\n\t\t\t}\n\t\t}\n\t\treturn result.stdout;\n\t}\n\n\tprivate async verifyStashSha(repoPath: string, stashName: string, sha: string | undefined): Promise<void> {\n\t\tif (!sha) return;\n\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, errors: 'ignore' },\n\t\t\t'show',\n\t\t\t'--format=%H',\n\t\t\t'--no-patch',\n\t\t\tstashName,\n\t\t);\n\t\tif (result.stdout.trim() !== sha) {\n\t\t\tthrow new Error(l10n.t('Unable to delete stash; mismatch with stash number'));\n\t\t}\n\t}\n\n\t@debug()\n\tasync renameStash(\n\t\trepoPath: string,\n\t\tstashName: string,\n\t\tsha: string,\n\t\tmessage: string,\n\t\tstashOnRef?: string,\n\t): Promise<void> {\n\t\tif (stashName) {\n\t\t\tawait this.verifyStashSha(repoPath, stashName, sha);\n\t\t}\n\n\t\t// The drop and the store announce once, after both ran, even if the store fails\n\t\ttry {\n\t\t\tawait this.deleteStashCore(repoPath, stashName, sha, { announce: false, verified: true });\n\t\t\tawait this.git.run(\n\t\t\t\t{ cwd: repoPath },\n\t\t\t\t'stash',\n\t\t\t\t'store',\n\t\t\t\t'-m',\n\t\t\t\tstashOnRef ? `On ${stashOnRef}: ${message}` : message,\n\t\t\t\tsha,\n\t\t\t);\n\t\t} finally {\n\t\t\tthis.announceStashChanged(repoPath);\n\t\t}\n\t}\n\n\t@debug({ args: (repoPath, message, paths) => ({ repoPath: repoPath, message: message, paths: paths?.length }) })\n\tasync saveStash(\n\t\trepoPath: string,\n\t\tmessage?: string,\n\t\tpathsOrUris?: (string | Uri)[],\n\t\toptions?: { includeUntracked?: boolean; keepIndex?: boolean; onlyStaged?: boolean },\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst paths = pathsOrUris?.map(toFsPath);\n\t\tif (!paths?.length) {\n\t\t\tawait this.stashPushCore(repoPath, message, options, runOptions);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.git.ensureSupports('git:stash:push:pathspecs', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Stashing individual files requires a newer version of Git (>= {0}) than is currently installed ({1}). Please retry by stashing everything or install a more recent version of Git and try again.',\n\t\t\t\trequiredVersion,\n\t\t\t\tinstalledVersion,\n\t\t\t),\n\t\t);\n\n\t\tconst pathspecs = paths.map(p => `./${splitPath(p, repoPath)[0]}`);\n\n\t\tlet stdin = await this.git.supports('git:stash:push:stdin');\n\t\tif (stdin && options?.onlyStaged && paths.length) {\n\t\t\t// Since Git doesn't support --staged with --pathspec-from-file try to pass them in directly\n\t\t\tstdin = false;\n\t\t}\n\n\t\t// If we don't support stdin, then error out if we are over the maximum allowed git cli length\n\t\tif (!stdin && countStringLength(pathspecs) > maxGitCliLength) {\n\t\t\tawait this.git.ensureSupports('git:stash:push:stdin', (requiredVersion, installedVersion) =>\n\t\t\t\tl10n.t(\n\t\t\t\t\t'Stashing so many files ({0}) at once requires a newer version of Git (>= {1}) than is currently installed ({2}). Please retry by stashing fewer files or install a more recent version of Git and try again.',\n\t\t\t\t\tpathspecs.length,\n\t\t\t\t\trequiredVersion,\n\t\t\t\t\tinstalledVersion,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tawait this.stashPushCore(\n\t\t\trepoPath,\n\t\t\tmessage,\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tpathspecs: pathspecs,\n\t\t\t\tstdin: stdin,\n\t\t\t},\n\t\t\trunOptions,\n\t\t);\n\t}\n\n\tprivate async stashPushCore(\n\t\trepoPath: string,\n\t\tmessage?: string,\n\t\toptions?: {\n\t\t\tincludeUntracked?: boolean;\n\t\t\tkeepIndex?: boolean;\n\t\t\tonlyStaged?: boolean;\n\t\t\tpathspecs?: string[];\n\t\t\tstdin?: boolean;\n\t\t},\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst params = ['stash', 'push'];\n\n\t\tif ((options?.includeUntracked || options?.pathspecs?.length) && !options?.onlyStaged) {\n\t\t\tparams.push('--include-untracked');\n\t\t}\n\n\t\t// `git stash push --keep-index --include-untracked -- <pathspec>` hits a bug in git when the\n\t\t// pathspec names an untracked file: the restoring checkout can't match an untracked path in the\n\t\t// index tree, so it fails and the staged changes are lost.\n\t\t//\n\t\t// $ mkdir stash-test && cd stash-test && git init\n\t\t// $ echo a > a.txt\n\t\t// $ git add a.txt\n\t\t// $ git commit -m init\n\t\t// $ echo b > b.txt\n\t\t// $ git stash push --keep-index --include-untracked -- b.txt\n\t\t// Saved working directory and index state WIP on main: 8a280fe init\n\t\t// error: pathspec ':(prefix:0)b.txt' did not match any file(s) known to git\n\t\t//\n\t\t// Only suppress --keep-index for that case — when the selection actually includes untracked\n\t\t// files (`includeUntracked`) AND we're stashing by pathspec. Keying off `includeUntracked` (the\n\t\t// caller's intent) rather than the `--include-untracked` flag is deliberate: we add\n\t\t// `--include-untracked` to every pathspec push above as a safety net, but a tracked-only\n\t\t// selection can — and must — still keep the index intact.\n\t\tif (options?.keepIndex && !(options?.includeUntracked && options?.pathspecs?.length)) {\n\t\t\tparams.push('--keep-index');\n\t\t}\n\n\t\tif (options?.onlyStaged) {\n\t\t\tif (await this.git.supports('git:stash:push:staged')) {\n\t\t\t\tparams.push('--staged');\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Git version {0} or higher is required for --staged',\n\t\t\t\t\t\tString(gitFeaturesByVersion.get('git:stash:push:staged')),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (message) {\n\t\t\tparams.push('-m', message);\n\t\t}\n\n\t\tlet stdin;\n\t\tif (options?.pathspecs?.length) {\n\t\t\tif (options.stdin) {\n\t\t\t\tstdin = options.pathspecs.join('\\0');\n\t\t\t\tparams.push('--pathspec-from-file=-', '--pathspec-file-nul', '--');\n\t\t\t} else {\n\t\t\t\tparams.push('--', ...options.pathspecs);\n\t\t\t}\n\t\t} else {\n\t\t\tparams.push('--');\n\t\t}\n\n\t\tlet nothingToSave = false;\n\t\ttry {\n\t\t\tconst result = await this.git.run({ cwd: repoPath, ...runOptions, stdin: stdin }, ...params);\n\t\t\tif (GitErrors.stashNothingToSave.test(result.stdout)) {\n\t\t\t\tnothingToSave = true;\n\t\t\t\tthrow new StashPushError({\n\t\t\t\t\treason: 'nothingToSave',\n\t\t\t\t\tgitCommand: { repoPath: repoPath, args: params },\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof StashPushError || isCancellationError(ex)) throw ex;\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'stash-push',\n\t\t\t\tex,\n\t\t\t\treason =>\n\t\t\t\t\tnew StashPushError(\n\t\t\t\t\t\t{ reason: reason ?? 'other', gitCommand: { repoPath: repoPath, args: params } },\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// A failed or cancelled push may already have stashed, and reset the working tree; one with nothing to\n\t\t\t// save changed nothing\n\t\t\tif (!nothingToSave) {\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes', 'status');\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash']);\n\t\t\t}\n\t\t}\n\t}\n\n\t@debug()\n\tasync saveSnapshot(repoPath: string, message?: string): Promise<void> {\n\t\tconst result = await this.git.run({ cwd: repoPath }, 'stash', 'create');\n\t\tconst id = result.stdout.trim() || undefined;\n\t\tif (id == null) return;\n\n\t\tconst args = [];\n\t\tif (message) {\n\t\t\targs.push('-m', message);\n\t\t}\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, 'stash', 'store', ...args, id);\n\t\t} finally {\n\t\t\tthis.announceStashChanged(repoPath);\n\t\t}\n\t}\n\n\tprivate announceStashChanged(repoPath: string): void {\n\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'stashes');\n\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['stash']);\n\t}\n}\n\nexport function convertStashesToStdin(stashOrStashes: GitStash | ReadonlyMap<string, GitStashCommit> | undefined): {\n\treadonly stdin: string | undefined;\n\treadonly stashes: Map<string, GitStashCommit>;\n\treadonly remappedIds: Map<string, string>;\n} {\n\tconst remappedIds = new Map<string, string>();\n\tif (stashOrStashes == null) return { stdin: undefined, stashes: new Map(), remappedIds: remappedIds };\n\n\tlet stdin: string | undefined;\n\tconst original = 'stashes' in stashOrStashes ? stashOrStashes.stashes : stashOrStashes;\n\tconst stashes = new Map<string, GitStashCommit>(original);\n\n\tif (original.size) {\n\t\tstdin = '';\n\t\tfor (const stash of original.values()) {\n\t\t\tstdin += `${stash.sha.substring(0, 9)}\\n`;\n\t\t\t// Include the stash's 2nd (index files) and 3rd (untracked files) parents (if they aren't already in the map)\n\t\t\tfor (const p of skip(stash.parents, 1)) {\n\t\t\t\tremappedIds.set(p, stash.sha);\n\n\t\t\t\tif (!stashes.has(p)) {\n\t\t\t\t\tstashes.set(p, stash);\n\t\t\t\t\tstdin += `${p.substring(0, 9)}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { stdin: stdin || undefined, stashes: stashes, remappedIds: remappedIds };\n}\n\nconst stashSummaryRegex =\n\t// oxlint-disable-next-line no-control-regex\n\t/(?:(?:(?<wip>WIP) on|On) (?<onref>[^/](?!.*\\/\\.)(?!.*\\.\\.)(?!.*\\/\\/)(?!.*@\\{)[^\\x00-\\x1F\\x7F ~^:?*[\\\\]+[^./]):\\s*)?(?<summary>.*)$/s;\n\nfunction createStash(\n\ts: ParsedStash | ParsedStashWithFiles,\n\trepoPath: string,\n\tcurrentUser: GitUser | undefined,\n): GitStashCommit {\n\t// `onRef` comes from the commit subject (%s), which git always prefixes with `On <branch>: …`\n\t// or `WIP on <branch>: …`. This holds even when the reflog message was customized\n\t// (autostash, `git stash store -m \"…\"`), so it's a reliable source\n\tlet onRef: string | undefined;\n\tconst subjectMatch = stashSummaryRegex.exec((s.commitSubject ?? '').trim());\n\tif (subjectMatch?.groups?.onref) {\n\t\tonRef = subjectMatch.groups.onref;\n\t}\n\n\t// The user-visible display message is derived from the reflog subject (%gs) so that short\n\t// custom messages like \"wip\", \"q\", or \"show args\" stay as the user wrote them instead of\n\t// being replaced by the verbose git-auto subject\n\tlet message = s.summary.trim();\n\tconst reflogMatch = stashSummaryRegex.exec(message);\n\tif (reflogMatch?.groups != null) {\n\t\tconst summary = reflogMatch.groups.summary.trim();\n\t\tif (summary.length === 0) {\n\t\t\tmessage = 'WIP';\n\t\t} else if (reflogMatch.groups.wip) {\n\t\t\tmessage = `WIP: ${summary}`;\n\t\t} else {\n\t\t\tmessage = summary;\n\t\t}\n\t}\n\n\tconst index = message.indexOf('\\n');\n\n\treturn new GitCommit(\n\t\trepoPath,\n\t\ts.sha,\n\t\tnew GitCommitIdentity(\n\t\t\tcurrentUser?.name ?? '',\n\t\t\tcurrentUser?.email,\n\t\t\tnew Date(Number(s.authorDate) * 1000),\n\t\t\tundefined,\n\t\t\ttrue,\n\t\t),\n\t\tnew GitCommitIdentity(\n\t\t\tcurrentUser?.name ?? '',\n\t\t\tcurrentUser?.email,\n\t\t\tnew Date(Number(s.committedDate) * 1000),\n\t\t\tundefined,\n\t\t\ttrue,\n\t\t),\n\t\tindex !== -1 ? message.substring(0, index) : message,\n\t\ts.parents.split(' ') ?? [],\n\t\tmessage,\n\t\tcreateCommitFileset(s, repoPath, undefined),\n\t\ts.stats,\n\t\tundefined,\n\t\tundefined,\n\t\ts.stashName,\n\t\tonRef,\n\t) as GitStashCommit;\n}\n"],"mappings":"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"}
|
|
@@ -67,7 +67,9 @@ export declare class StatusGitSubProvider implements GitStatusSubProvider {
|
|
|
67
67
|
hasConflictingFiles(repoPath: string, cancellation?: AbortSignal): Promise<boolean>;
|
|
68
68
|
getConflictingFiles(repoPath: string, cancellation?: AbortSignal): Promise<GitConflictFile[]>;
|
|
69
69
|
private hasUntrackedFiles;
|
|
70
|
-
getUntrackedFiles(repoPath: string,
|
|
70
|
+
getUntrackedFiles(repoPath: string, options?: {
|
|
71
|
+
paths?: readonly string[];
|
|
72
|
+
}, cancellation?: AbortSignal): Promise<GitFile[]>;
|
|
71
73
|
}
|
|
72
74
|
//#endregion
|
|
73
75
|
//# sourceMappingURL=status.d.ts.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { chunkByStringLength } from "../../utils/iterable.js";
|
|
1
2
|
import { raceWithTimeout } from "../../utils/cancellation.js";
|
|
2
3
|
import { iterateByDelimiter } from "../../utils/string.js";
|
|
3
4
|
import { getScopedLogger } from "../../utils/logger.scoped.js";
|
|
@@ -8,12 +9,12 @@ import { toFsPath } from "../../utils/uri.js";
|
|
|
8
9
|
import { normalizePath, splitPath, stripFolderGlob } from "../../utils/path.js";
|
|
9
10
|
import { PromiseMap } from "../../utils/promiseCache.js";
|
|
10
11
|
import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
|
|
11
|
-
import { GitErrors, defaultExceptionHandler, gitConfigsStatus } from "../exec/git.js";
|
|
12
|
+
import { GitErrors, defaultExceptionHandler, gitConfigsStatus, maxGitCliLength } from "../exec/git.js";
|
|
12
13
|
import { GitFileWorkingTreeStatus } from "../../git/models/fileStatus.js";
|
|
13
|
-
import _usingCtx from "../../_virtual/@oxc-project+runtime/helpers/esm/usingCtx.js";
|
|
14
|
-
import { parseGitConflictFiles } from "../parsers/indexParser.js";
|
|
15
14
|
import { GitStatus } from "../../git/models/status.js";
|
|
15
|
+
import _usingCtx from "../../_virtual/@oxc-project+runtime/helpers/esm/usingCtx.js";
|
|
16
16
|
import { parseGitStatus } from "../parsers/statusParser.js";
|
|
17
|
+
import { parseGitConflictFiles } from "../parsers/indexParser.js";
|
|
17
18
|
//#region ../git-cli/src/providers/status.ts
|
|
18
19
|
/** Backstop when `advanced.git.timeout` is disabled (0). Independent of the command timeout so disabling it can't
|
|
19
20
|
* also disable deadlock recovery — mirrors `@gate`'s always-on 5-min force-clear. */
|
|
@@ -289,29 +290,46 @@ var StatusGitSubProvider = class {
|
|
|
289
290
|
_usingCtx3.d();
|
|
290
291
|
}
|
|
291
292
|
}
|
|
292
|
-
getUntrackedFiles(repoPath, cancellation) {
|
|
293
|
+
getUntrackedFiles(repoPath, options, cancellation) {
|
|
293
294
|
const scope = getScopedLogger();
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
295
|
+
const paths = options?.paths;
|
|
296
|
+
if (paths != null && !paths.length) return Promise.resolve([]);
|
|
297
|
+
const pathspecs = paths?.map((p) => `:(literal)${p}`);
|
|
298
|
+
const read = pathspecs != null ? `getUntrackedFiles\0${pathspecs.join("\0")}` : "getUntrackedFiles";
|
|
299
|
+
return this.dedupeByStatusGeneration(repoPath, read, async (correlationKey, signal) => {
|
|
300
|
+
const prefix = [
|
|
301
|
+
"ls-files",
|
|
302
|
+
"-z",
|
|
303
|
+
"--others",
|
|
304
|
+
"--exclude-standard"
|
|
305
|
+
];
|
|
306
|
+
let batches = [[]];
|
|
307
|
+
if (pathspecs != null) {
|
|
308
|
+
const perArgOverhead = 3;
|
|
309
|
+
const prefixLength = [...prefix, "--"].reduce((sum, arg) => sum + arg.length + perArgOverhead, 0);
|
|
310
|
+
batches = chunkByStringLength(pathspecs, maxGitCliLength - prefixLength, perArgOverhead);
|
|
304
311
|
}
|
|
312
|
+
const seen = /* @__PURE__ */ new Set();
|
|
305
313
|
const files = [];
|
|
306
|
-
for (const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
});
|
|
314
|
+
for (const batch of batches) {
|
|
315
|
+
const result = await this.git.run({
|
|
316
|
+
cwd: repoPath,
|
|
317
|
+
cancellation: signal,
|
|
318
|
+
errors: "throw",
|
|
319
|
+
correlationKey
|
|
320
|
+
}, ...prefix, ...pathspecs != null ? ["--", ...batch] : []);
|
|
321
|
+
if (!result.stdout) continue;
|
|
322
|
+
for (const line of iterateByDelimiter(result.stdout, "\0")) {
|
|
323
|
+
if (!line.length || seen.has(line)) continue;
|
|
324
|
+
seen.add(line);
|
|
325
|
+
files.push({
|
|
326
|
+
path: line,
|
|
327
|
+
repoPath,
|
|
328
|
+
status: GitFileWorkingTreeStatus.Untracked
|
|
329
|
+
});
|
|
330
|
+
}
|
|
313
331
|
}
|
|
314
|
-
scope?.addExitInfo(`${String(files.length)} untracked file(s)`);
|
|
332
|
+
scope?.addExitInfo(files.length ? `${String(files.length)} untracked file(s)` : "no untracked files");
|
|
315
333
|
return files;
|
|
316
334
|
}, cancellation);
|
|
317
335
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","names":[],"sources":["../../../../git-cli/src/providers/status.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport type { GitFile } from '@gitlens/git/models/file.js';\nimport { GitFileWorkingTreeStatus } from '@gitlens/git/models/fileStatus.js';\nimport type { GitConflictFile } from '@gitlens/git/models/staging.js';\nimport { GitStatus } from '@gitlens/git/models/status.js';\nimport type { GitStatusFile } from '@gitlens/git/models/statusFile.js';\nimport type { GitStatusSubProvider, GitWorkingChangesState } from '@gitlens/git/providers/status.js';\nimport type { GitCommandPriority, GitErrorHandling } from '@gitlens/git/run.types.js';\nimport { raceWithTimeout } from '@gitlens/utils/cancellation.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { createDisposable } from '@gitlens/utils/disposable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { normalizePath, splitPath, stripFolderGlob } from '@gitlens/utils/path.js';\nimport { getSettledValue } from '@gitlens/utils/promise.js';\nimport { PromiseMap } from '@gitlens/utils/promiseCache.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 { GitResult } from '../exec/exec.types.js';\nimport type { Git } from '../exec/git.js';\nimport { defaultExceptionHandler, gitConfigsStatus, GitErrors } from '../exec/git.js';\nimport { parseGitConflictFiles } from '../parsers/indexParser.js';\nimport { parseGitStatus } from '../parsers/statusParser.js';\n\n/** Backstop when `advanced.git.timeout` is disabled (0). Independent of the command timeout so disabling it can't\n * also disable deadlock recovery — mirrors `@gate`'s always-on 5-min force-clear. */\nconst disabledTimeoutBackstopMs = 1000 * 60 * 5;\n\n/**\n * Deadlock-backstop duration for a status read (see `dedupeByStatusGeneration`), exported for testing.\n * Always returns a value so a wedged read recovers even with `advanced.git.timeout` disabled (which bounds git\n * *commands*, not deadlock recovery). With a timeout set, `gitTimeout * 2` sits above the per-command timeout so\n * `git.run` reads reject at their own timeout first; the backstop's real job is bounding the timeout-less\n * `git.stream` reads (`hasUntrackedFiles`/`hasConflictingFiles`).\n */\nexport function computeDeadlockBackstopMs(gitTimeout: number | undefined): number {\n\tconst timeout = gitTimeout ?? 60000;\n\treturn timeout > 0 ? timeout * 2 : disabledTimeoutBackstopMs;\n}\n\n/**\n * A non-default `untracked`/`branch` gets its own key, so a full-status caller never joins a narrower run; the\n * default stays `'getStatus'`, which `getStatusForPathCore`'s rename path joins.\n */\nfunction getStatusReadKey(options?: { untracked?: 'no' | 'normal' | 'all'; branch?: false }): string {\n\tif (options?.untracked == null && options?.branch !== false) return 'getStatus';\n\n\tconst parts: string[] = [];\n\tif (options?.untracked != null) {\n\t\tparts.push(`untracked=${options.untracked}`);\n\t}\n\tif (options?.branch === false) {\n\t\tparts.push('branch=false');\n\t}\n\treturn `getStatus:${parts.join(':')}`;\n}\n\nexport class StatusGitSubProvider implements GitStatusSubProvider {\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/** In-flight reads, keyed by `<read>\\0<repoPath>\\0<generation>`. `PromiseMap` (not a bare Map) so joiners\n\t * get per-caller cancellation: the shared run aborts only when ALL current callers do. */\n\tprivate readonly _pendingReads = new PromiseMap<string, unknown>();\n\n\t/**\n\t * Single-flight for point-in-time reads of mutable working-tree state — replaces `@gate`, which dedups on\n\t * repoPath with no notion of *when* a run started and so joins a pre-change read to a post-change caller\n\t * (see {@link Cache.getStatusGeneration}). Same-generation callers share one run (via a `PromiseMap`, so a\n\t * joiner cancelling can't reject the others); a caller in a newer generation gets a different key and a\n\t * fresh run; a `force` read advances the clock first, so it fences every later reader too, not just itself.\n\t * The exec-layer command dedup (`Git.pendingCommands`) is fenced automatically: each run carries this entry's\n\t * aggregate signal, whose id is part of the exec cache key, so a newer-generation run never joins an older\n\t * one's process; the generation-derived `correlationKey` is a readable second guard on that key. A `raceWithTimeout` backstop (scaled to `advanced.git.timeout`, see\n\t * {@link computeDeadlockBackstopMs}) replaces `@gate`'s 5-min force-clear so a never-settling read (a hung\n\t * `git.stream`, which has no per-command timeout) can't wedge same-generation callers — including blocking\n\t * awaiters like the commit flow — indefinitely.\n\t */\n\tprivate dedupeByStatusGeneration<T>(\n\t\trepoPath: string,\n\t\tread: string,\n\t\trun: (correlationKey: string, signal: AbortSignal | undefined) => Promise<T>,\n\t\tcancellation?: AbortSignal,\n\t\tforce?: boolean,\n\t): Promise<T> {\n\t\t// A `force` (user refresh) read is the user asserting the working tree may have changed without the watcher\n\t\t// observing it — the same class of event as a watcher tick, so it ADVANCES the clock rather than carving out\n\t\t// a private key for itself. A one-shot nonce would fence only this caller: the pre-assertion run stays\n\t\t// joinable, so the very next ordinary reader still picks up pre-change content — and, stamped with a newer\n\t\t// `Wip.revision` (assigned at producer start, not read start), applies it right back over the refreshed\n\t\t// result. Advancing is also CHEAPER than a nonce: concurrent readers join the one fresh read instead of each\n\t\t// spawning a private one.\n\t\tif (force) {\n\t\t\tthis.cache.incrementStatusGeneration(repoPath);\n\t\t}\n\t\tconst generation = this.cache.getStatusGeneration(repoPath);\n\t\t// `\\0` separators: `read`/`repoPath` are free-form (paths can contain `:`), so a printable delimiter could\n\t\t// collide (`getStatusForPath:/a:x` vs `getStatusForPath:/a` + `:x`).\n\t\tconst key = `${read}\\0${repoPath}\\0${generation}`;\n\t\tconst correlationKey = `status:${generation}`;\n\t\tconst backstopMs = computeDeadlockBackstopMs(this.git.options.gitTimeout);\n\n\t\treturn this._pendingReads.getOrCreate(\n\t\t\tkey,\n\t\t\t(cacheable, signal) => {\n\t\t\t\t// Point-in-time read: never memoize a settled value. `invalidate()` at the start makes the entry\n\t\t\t\t// self-evict on settle, so a later caller in this same generation re-reads (a newer generation\n\t\t\t\t// already gets a different key). `signal` is the aggregate — the run aborts only if every caller\n\t\t\t\t// cancels, so one caller's abort can't reject the others. The backstop rejects a wedged read so\n\t\t\t\t// waiters unblock and the entry self-evicts; it ALSO aborts the underlying git op (via `backstop`\n\t\t\t\t// linked into the run's signal) so a wedged read releases its GitQueue slot/process rather than\n\t\t\t\t// running orphaned — best-effort, since a truly-stuck process may ignore the abort.\n\t\t\t\tcacheable.invalidate();\n\t\t\t\tconst backstop = new AbortController();\n\t\t\t\tconst runSignal = signal != null ? AbortSignal.any([signal, backstop.signal]) : backstop.signal;\n\t\t\t\treturn raceWithTimeout(run(correlationKey, runSignal), backstopMs, backstop);\n\t\t\t},\n\t\t\tcancellation,\n\t\t) as Promise<T>;\n\t}\n\n\t@debug()\n\tgetStatus(\n\t\trepoPath: string | undefined,\n\t\toptions?: {\n\t\t\tpriority?: GitCommandPriority;\n\t\t\tforce?: boolean;\n\t\t\tuntracked?: 'no' | 'normal' | 'all';\n\t\t\tbranch?: false;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatus | undefined> {\n\t\tif (repoPath == null) return Promise.resolve(undefined);\n\n\t\t// `-u` already means `-uall`, so an explicit `'all'` shares the default run\n\t\tconst opts = options?.untracked === 'all' ? { ...options, untracked: undefined } : options;\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\tgetStatusReadKey(opts),\n\t\t\t(correlationKey, signal) =>\n\t\t\t\tthis.getStatusCore(repoPath, { ...opts, correlationKey: correlationKey }, signal),\n\t\t\tcancellation,\n\t\t\topts?.force,\n\t\t);\n\t}\n\n\tprivate async getStatusCore(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tpriority?: GitCommandPriority;\n\t\t\tcorrelationKey?: string;\n\t\t\tuntracked?: 'no' | 'normal' | 'all';\n\t\t\tbranch?: false;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatus | undefined> {\n\t\tconst porcelainVersion = (await this.git.supports('git:status:porcelain-v2')) ? 2 : 1;\n\n\t\tconst result = await this.statusCore(\n\t\t\trepoPath,\n\t\t\tporcelainVersion,\n\t\t\t{\n\t\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t\t\tpriority: options?.priority,\n\t\t\t\tcorrelationKey: options?.correlationKey,\n\t\t\t\tuntracked: options?.untracked,\n\t\t\t\tbranch: options?.branch,\n\t\t\t\terrors: 'throw',\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t\tconst status = parseGitStatus(result.stdout, repoPath, porcelainVersion);\n\n\t\tif (options?.branch === false) {\n\t\t\t// Without `--branch` a clean tree prints nothing at all, which the parser reads as no status\n\t\t\tif (status == null && result.completion.status === 'exited' && result.exitCode === 0) {\n\t\t\t\treturn new GitStatus(normalizePath(repoPath), '', '', []);\n\t\t\t}\n\t\t\t// No branch name either, which `GitStatus` reads as detached, so there is no paused rebase to look up\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status?.detached) {\n\t\t\tconst pausedOpStatus = await this.provider.pausedOps?.getPausedOperationStatus?.(\n\t\t\t\trepoPath,\n\t\t\t\tundefined,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (pausedOpStatus?.type === 'rebase') {\n\t\t\t\treturn new GitStatus(\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpausedOpStatus.incoming.name,\n\t\t\t\t\tstatus.sha,\n\t\t\t\t\tstatus.files,\n\t\t\t\t\tstatus.upstream,\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn status;\n\t}\n\n\t@debug()\n\tasync getStatusForFile(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\toptions?: { renames?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatusFile | undefined> {\n\t\tconst files = await this.getStatusForPathCore(\n\t\t\trepoPath,\n\t\t\ttoFsPath(pathOrUri),\n\t\t\t{ ...options, exact: true },\n\t\t\tcancellation,\n\t\t);\n\t\treturn files?.[0];\n\t}\n\n\t@debug()\n\tasync getStatusForPath(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\toptions?: { renames?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatusFile[] | undefined> {\n\t\treturn this.getStatusForPathCore(repoPath, toFsPath(pathOrUri), { ...options, exact: false }, cancellation);\n\t}\n\n\tprivate async getStatusForPathCore(\n\t\trepoPath: string,\n\t\tpathOrUri: string,\n\t\toptions: { exact: boolean; renames?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatusFile[] | undefined> {\n\t\tconst relativePath = stripFolderGlob(splitPath(pathOrUri, repoPath)[0]);\n\n\t\t// Rename-aware queries can't scope by pathspec (that disables Git's rename detection), so they run the\n\t\t// SAME full `git status` as `getStatus`. Delegate to it — sharing one process/dedup entry — and filter,\n\t\t// rather than spawning a second identical `git status`.\n\t\tif (options.renames !== false) {\n\t\t\t// The rename path keeps the default handling the scoped read gets\n\t\t\tconst status = await this.getStatus(repoPath, undefined, cancellation).catch((ex: unknown) => {\n\t\t\t\tdefaultExceptionHandler(ex as Error, repoPath);\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t\tif (status == null) return undefined;\n\n\t\t\tif (options.exact) {\n\t\t\t\tconst file = status.files.find(f => f.path === relativePath);\n\t\t\t\treturn file ? [file] : undefined;\n\t\t\t}\n\t\t\treturn status.files.filter(f => f.path.startsWith(relativePath));\n\t\t}\n\n\t\t// Non-rename query: pathspec-scoped `git status` (a distinct command), deduped on its own key. `exact`\n\t\t// is NOT in the key — the pathspec-scoped command is identical for exact/non-exact, so both share one run.\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t// Free-form `relativePath` (may contain `:`) goes LAST so the prefix can't be shifted into it.\n\t\t\t`getStatusForPath:${relativePath}`,\n\t\t\t(correlationKey, signal) => this.getStatusForPathScoped(repoPath, relativePath, correlationKey, signal),\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprivate async getStatusForPathScoped(\n\t\trepoPath: string,\n\t\trelativePath: string,\n\t\tcorrelationKey: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatusFile[] | undefined> {\n\t\tconst porcelainVersion = (await this.git.supports('git:status:porcelain-v2')) ? 2 : 1;\n\t\tconst result = await this.statusCore(\n\t\t\trepoPath,\n\t\t\tporcelainVersion,\n\t\t\t{ similarityThreshold: this.context.config?.commits.similarityThreshold, correlationKey: correlationKey },\n\t\t\tcancellation,\n\t\t\trelativePath,\n\t\t);\n\n\t\tconst status = parseGitStatus(result.stdout, repoPath, porcelainVersion);\n\t\treturn status?.files;\n\t}\n\n\tprivate async statusCore(\n\t\trepoPath: string,\n\t\tporcelainVersion: number = 1,\n\t\toptions?: {\n\t\t\tsimilarityThreshold?: number | null;\n\t\t\tpriority?: GitCommandPriority;\n\t\t\tcorrelationKey?: string;\n\t\t\tuntracked?: 'no' | 'normal' | 'all';\n\t\t\tbranch?: false;\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t\t...pathspecs: string[]\n\t): Promise<GitResult> {\n\t\tconst params = ['status', porcelainVersion >= 2 ? `--porcelain=v${porcelainVersion}` : '--porcelain'];\n\t\tif (options?.branch !== false) {\n\t\t\tparams.push('--branch');\n\t\t}\n\t\tparams.push(options?.untracked != null ? `-u${options.untracked}` : '-u');\n\t\tif (await this.git.supports('git:status:find-renames')) {\n\t\t\tparams.push(\n\t\t\t\t`--find-renames${options?.similarityThreshold == null ? '' : `=${options.similarityThreshold}%`}`,\n\t\t\t);\n\t\t}\n\n\t\treturn this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\tconfigs: gitConfigsStatus,\n\t\t\t\tenv: { GIT_OPTIONAL_LOCKS: '0' },\n\t\t\t\tcorrelationKey: options?.correlationKey,\n\t\t\t\t...(options?.errors != null ? { errors: options.errors } : undefined),\n\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t},\n\t\t\t...params,\n\t\t\t'--',\n\t\t\t...pathspecs,\n\t\t);\n\t}\n\n\t@debug()\n\thasWorkingChanges(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tstaged?: boolean;\n\t\t\tunstaged?: boolean;\n\t\t\tuntracked?: boolean;\n\t\t\tpriority?: GitCommandPriority;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst staged = options?.staged ?? true;\n\t\tconst unstaged = options?.unstaged ?? true;\n\t\tconst untracked = options?.untracked ?? true;\n\t\t// `priority` is in the key even though it doesn't change the answer: a joiner INHERITS the in-flight run's\n\t\t// scheduling. `GitQueue` refuses to start background work while anything is waiting at normal/interactive,\n\t\t// so letting a foreground caller (the overview's dirty pill, the Worktrees view) join a `background` probe\n\t\t// would strand it for the whole graph load. Splitting the two lanes costs at most one extra spawn; joining\n\t\t// costs unbounded foreground latency.\n\t\tconst priority = options?.priority ?? 'default';\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t`hasWorkingChanges:${staged}:${unstaged}:${untracked}:${priority}`,\n\t\t\tasync (correlationKey, signal) => {\n\t\t\t\tif (staged || unstaged) {\n\t\t\t\t\tconst diffQuiet = (revision: string | undefined) =>\n\t\t\t\t\t\tthis.git.run(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\t\t\tcancellation: signal,\n\t\t\t\t\t\t\t\terrors: 'throw',\n\t\t\t\t\t\t\t\texpectedExitCodes: [1],\n\t\t\t\t\t\t\t\tcorrelationKey: correlationKey,\n\t\t\t\t\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'diff',\n\t\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t\trevision,\n\t\t\t\t\t\t\t'--',\n\t\t\t\t\t\t);\n\n\t\t\t\t\tlet result;\n\t\t\t\t\tif (staged && unstaged) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresult = await diffQuiet('HEAD');\n\t\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t\t// Before the first commit HEAD names nothing; everything staged or modified is a change\n\t\t\t\t\t\t\t// against the empty tree. `diff HEAD --` names only HEAD, so its \"bad revision\" is that case\n\t\t\t\t\t\t\t// without re-validating HEAD (a corrupt HEAD then reads as dirty, the safe answer)\n\t\t\t\t\t\t\tif (GitErrors.badRevision.exec(String(ex))?.[1]?.toUpperCase() !== 'HEAD') throw ex;\n\n\t\t\t\t\t\t\tresult = await diffQuiet(await this.provider.revision.getEmptyTreeSha(repoPath));\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = await diffQuiet(staged ? '--staged' : undefined);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.exitCode === 1) {\n\t\t\t\t\t\tif (staged && unstaged) {\n\t\t\t\t\t\t\tscope?.addExitInfo('has staged and unstaged changes');\n\t\t\t\t\t\t} else if (staged) {\n\t\t\t\t\t\t\tscope?.addExitInfo('has staged changes');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tscope?.addExitInfo('has unstaged changes');\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check for untracked files. NOTE: this runs through `git.stream`, which spawns directly\n\t\t\t\t// and never enters the queue — so `priority` above doesn't reach it. Only clean worktrees\n\t\t\t\t// get this far (a dirty one already returned above), and callers fanning out across many\n\t\t\t\t// worktrees are expected to bound their own concurrency.\n\t\t\t\tif (untracked) {\n\t\t\t\t\tconst hasUntracked = await this.hasUntrackedFiles(repoPath, signal);\n\t\t\t\t\tif (hasUntracked) {\n\t\t\t\t\t\tscope?.addExitInfo('has untracked files');\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tscope?.addExitInfo('no working changes');\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@debug()\n\tgetWorkingChangesState(repoPath: string, cancellation?: AbortSignal): Promise<GitWorkingChangesState> {\n\t\tconst scope = getScopedLogger();\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t'getWorkingChangesState',\n\t\t\tasync (correlationKey, signal) => {\n\t\t\t\tconst [stagedResult, unstagedResult, untrackedResult] = await Promise.allSettled([\n\t\t\t\t\t// Check for staged changes\n\t\t\t\t\tthis.git.run(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\t\tcancellation: signal,\n\t\t\t\t\t\t\terrors: 'throw',\n\t\t\t\t\t\t\texpectedExitCodes: [1],\n\t\t\t\t\t\t\tcorrelationKey: correlationKey,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t'diff',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t'--staged',\n\t\t\t\t\t),\n\t\t\t\t\t// Check for unstaged changes\n\t\t\t\t\tthis.git.run(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\t\tcancellation: signal,\n\t\t\t\t\t\t\terrors: 'throw',\n\t\t\t\t\t\t\texpectedExitCodes: [1],\n\t\t\t\t\t\t\tcorrelationKey: correlationKey,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t'diff',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t),\n\t\t\t\t\t// Check for untracked files\n\t\t\t\t\tthis.hasUntrackedFiles(repoPath, signal),\n\t\t\t\t]);\n\n\t\t\t\tfor (const settled of [stagedResult, unstagedResult, untrackedResult]) {\n\t\t\t\t\tif (settled.status === 'rejected') throw settled.reason;\n\t\t\t\t}\n\n\t\t\t\tconst result = {\n\t\t\t\t\tstaged: getSettledValue(stagedResult)?.exitCode === 1,\n\t\t\t\t\tunstaged: getSettledValue(unstagedResult)?.exitCode === 1,\n\t\t\t\t\tuntracked: getSettledValue(untrackedResult) === true,\n\t\t\t\t};\n\n\t\t\t\tscope?.addExitInfo(\n\t\t\t\t\tresult.staged || result.unstaged || result.untracked\n\t\t\t\t\t\t? `has ${result.staged ? 'staged' : ''}${result.unstaged ? (result.staged ? ', unstaged' : 'unstaged ') : ''}${\n\t\t\t\t\t\t\t\tresult.untracked ? (result.staged || result.unstaged ? ', untracked' : 'untracked') : ''\n\t\t\t\t\t\t\t} changes`\n\t\t\t\t\t\t: 'no working changes',\n\t\t\t\t);\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\thasConflictingFiles(repoPath: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\t// Route through `dedupeByStatusGeneration` (like every other point-in-time read here) for the join-fence\n\t\t// and the `raceWithTimeout` backstop — a bare `git.stream` has no per-command timeout and could wedge.\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t'hasConflictingFiles',\n\t\t\tasync (_correlationKey, signal) => {\n\t\t\t\tconst stream = this.git.stream({ cwd: repoPath, cancellation: signal }, 'ls-files', '--unmerged');\n\t\t\t\tusing _streamDisposer = createDisposable(() => void stream.return?.(undefined));\n\n\t\t\t\t// Early exit on first chunk - breaking causes SIGPIPE, killing git process\n\t\t\t\tfor await (const _chunk of stream) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@debug()\n\tgetConflictingFiles(repoPath: string, cancellation?: AbortSignal): Promise<GitConflictFile[]> {\n\t\tconst scope = getScopedLogger();\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t'getConflictingFiles',\n\t\t\tasync (correlationKey, signal) => {\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: signal, errors: 'throw', correlationKey: correlationKey },\n\t\t\t\t\t'ls-files',\n\t\t\t\t\t'-z',\n\t\t\t\t\t'--unmerged',\n\t\t\t\t);\n\n\t\t\t\tif (!result.stdout) {\n\t\t\t\t\tscope?.addExitInfo('no conflicting files');\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst files = parseGitConflictFiles(result.stdout, repoPath);\n\t\t\t\tscope?.addExitInfo(`${String(files.length)} conflicting file(s)`);\n\t\t\t\treturn files;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprivate async hasUntrackedFiles(repoPath: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\tconst stream = this.git.stream(\n\t\t\t{ cwd: repoPath, cancellation: cancellation },\n\t\t\t'ls-files',\n\t\t\t// '-z', // Unneeded since we are only looking for presence\n\t\t\t'--others',\n\t\t\t'--exclude-standard',\n\t\t);\n\t\tusing _streamDisposer = createDisposable(() => void stream.return?.(undefined));\n\n\t\t// Early exit on first chunk - breaking causes SIGPIPE, killing git process\n\t\tfor await (const _chunk of stream) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t@debug()\n\tgetUntrackedFiles(repoPath: string, cancellation?: AbortSignal): Promise<GitFile[]> {\n\t\tconst scope = getScopedLogger();\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t'getUntrackedFiles',\n\t\t\tasync (correlationKey, signal) => {\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: signal, errors: 'throw', correlationKey: correlationKey },\n\t\t\t\t\t'ls-files',\n\t\t\t\t\t'-z',\n\t\t\t\t\t'--others',\n\t\t\t\t\t'--exclude-standard',\n\t\t\t\t);\n\n\t\t\t\tif (!result.stdout) {\n\t\t\t\t\tscope?.addExitInfo('no untracked files');\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst files: GitFile[] = [];\n\n\t\t\t\tfor (const line of iterateByDelimiter(result.stdout, '\\0')) {\n\t\t\t\t\tif (!line.length) continue;\n\n\t\t\t\t\tfiles.push({ path: line, repoPath: repoPath, status: GitFileWorkingTreeStatus.Untracked });\n\t\t\t\t}\n\n\t\t\t\tscope?.addExitInfo(`${String(files.length)} untracked file(s)`);\n\t\t\t\treturn files;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"status.js","names":[],"sources":["../../../../git-cli/src/providers/status.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport type { GitFile } from '@gitlens/git/models/file.js';\nimport { GitFileWorkingTreeStatus } from '@gitlens/git/models/fileStatus.js';\nimport type { GitConflictFile } from '@gitlens/git/models/staging.js';\nimport { GitStatus } from '@gitlens/git/models/status.js';\nimport type { GitStatusFile } from '@gitlens/git/models/statusFile.js';\nimport type { GitStatusSubProvider, GitWorkingChangesState } from '@gitlens/git/providers/status.js';\nimport type { GitCommandPriority, GitErrorHandling } from '@gitlens/git/run.types.js';\nimport { raceWithTimeout } from '@gitlens/utils/cancellation.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { createDisposable } from '@gitlens/utils/disposable.js';\nimport { chunkByStringLength } from '@gitlens/utils/iterable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { normalizePath, splitPath, stripFolderGlob } from '@gitlens/utils/path.js';\nimport { getSettledValue } from '@gitlens/utils/promise.js';\nimport { PromiseMap } from '@gitlens/utils/promiseCache.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 { GitResult } from '../exec/exec.types.js';\nimport type { Git } from '../exec/git.js';\nimport { defaultExceptionHandler, gitConfigsStatus, GitErrors, maxGitCliLength } from '../exec/git.js';\nimport { parseGitConflictFiles } from '../parsers/indexParser.js';\nimport { parseGitStatus } from '../parsers/statusParser.js';\n\n/** Backstop when `advanced.git.timeout` is disabled (0). Independent of the command timeout so disabling it can't\n * also disable deadlock recovery — mirrors `@gate`'s always-on 5-min force-clear. */\nconst disabledTimeoutBackstopMs = 1000 * 60 * 5;\n\n/**\n * Deadlock-backstop duration for a status read (see `dedupeByStatusGeneration`), exported for testing.\n * Always returns a value so a wedged read recovers even with `advanced.git.timeout` disabled (which bounds git\n * *commands*, not deadlock recovery). With a timeout set, `gitTimeout * 2` sits above the per-command timeout so\n * `git.run` reads reject at their own timeout first; the backstop's real job is bounding the timeout-less\n * `git.stream` reads (`hasUntrackedFiles`/`hasConflictingFiles`).\n */\nexport function computeDeadlockBackstopMs(gitTimeout: number | undefined): number {\n\tconst timeout = gitTimeout ?? 60000;\n\treturn timeout > 0 ? timeout * 2 : disabledTimeoutBackstopMs;\n}\n\n/**\n * A non-default `untracked`/`branch` gets its own key, so a full-status caller never joins a narrower run; the\n * default stays `'getStatus'`, which `getStatusForPathCore`'s rename path joins.\n */\nfunction getStatusReadKey(options?: { untracked?: 'no' | 'normal' | 'all'; branch?: false }): string {\n\tif (options?.untracked == null && options?.branch !== false) return 'getStatus';\n\n\tconst parts: string[] = [];\n\tif (options?.untracked != null) {\n\t\tparts.push(`untracked=${options.untracked}`);\n\t}\n\tif (options?.branch === false) {\n\t\tparts.push('branch=false');\n\t}\n\treturn `getStatus:${parts.join(':')}`;\n}\n\nexport class StatusGitSubProvider implements GitStatusSubProvider {\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/** In-flight reads, keyed by `<read>\\0<repoPath>\\0<generation>`. `PromiseMap` (not a bare Map) so joiners\n\t * get per-caller cancellation: the shared run aborts only when ALL current callers do. */\n\tprivate readonly _pendingReads = new PromiseMap<string, unknown>();\n\n\t/**\n\t * Single-flight for point-in-time reads of mutable working-tree state — replaces `@gate`, which dedups on\n\t * repoPath with no notion of *when* a run started and so joins a pre-change read to a post-change caller\n\t * (see {@link Cache.getStatusGeneration}). Same-generation callers share one run (via a `PromiseMap`, so a\n\t * joiner cancelling can't reject the others); a caller in a newer generation gets a different key and a\n\t * fresh run; a `force` read advances the clock first, so it fences every later reader too, not just itself.\n\t * The exec-layer command dedup (`Git.pendingCommands`) is fenced automatically: each run carries this entry's\n\t * aggregate signal, whose id is part of the exec cache key, so a newer-generation run never joins an older\n\t * one's process; the generation-derived `correlationKey` is a readable second guard on that key. A `raceWithTimeout` backstop (scaled to `advanced.git.timeout`, see\n\t * {@link computeDeadlockBackstopMs}) replaces `@gate`'s 5-min force-clear so a never-settling read (a hung\n\t * `git.stream`, which has no per-command timeout) can't wedge same-generation callers — including blocking\n\t * awaiters like the commit flow — indefinitely.\n\t */\n\tprivate dedupeByStatusGeneration<T>(\n\t\trepoPath: string,\n\t\tread: string,\n\t\trun: (correlationKey: string, signal: AbortSignal | undefined) => Promise<T>,\n\t\tcancellation?: AbortSignal,\n\t\tforce?: boolean,\n\t): Promise<T> {\n\t\t// A `force` (user refresh) read is the user asserting the working tree may have changed without the watcher\n\t\t// observing it — the same class of event as a watcher tick, so it ADVANCES the clock rather than carving out\n\t\t// a private key for itself. A one-shot nonce would fence only this caller: the pre-assertion run stays\n\t\t// joinable, so the very next ordinary reader still picks up pre-change content — and, stamped with a newer\n\t\t// `Wip.revision` (assigned at producer start, not read start), applies it right back over the refreshed\n\t\t// result. Advancing is also CHEAPER than a nonce: concurrent readers join the one fresh read instead of each\n\t\t// spawning a private one.\n\t\tif (force) {\n\t\t\tthis.cache.incrementStatusGeneration(repoPath);\n\t\t}\n\t\tconst generation = this.cache.getStatusGeneration(repoPath);\n\t\t// `\\0` separators: `read`/`repoPath` are free-form (paths can contain `:`), so a printable delimiter could\n\t\t// collide (`getStatusForPath:/a:x` vs `getStatusForPath:/a` + `:x`).\n\t\tconst key = `${read}\\0${repoPath}\\0${generation}`;\n\t\tconst correlationKey = `status:${generation}`;\n\t\tconst backstopMs = computeDeadlockBackstopMs(this.git.options.gitTimeout);\n\n\t\treturn this._pendingReads.getOrCreate(\n\t\t\tkey,\n\t\t\t(cacheable, signal) => {\n\t\t\t\t// Point-in-time read: never memoize a settled value. `invalidate()` at the start makes the entry\n\t\t\t\t// self-evict on settle, so a later caller in this same generation re-reads (a newer generation\n\t\t\t\t// already gets a different key). `signal` is the aggregate — the run aborts only if every caller\n\t\t\t\t// cancels, so one caller's abort can't reject the others. The backstop rejects a wedged read so\n\t\t\t\t// waiters unblock and the entry self-evicts; it ALSO aborts the underlying git op (via `backstop`\n\t\t\t\t// linked into the run's signal) so a wedged read releases its GitQueue slot/process rather than\n\t\t\t\t// running orphaned — best-effort, since a truly-stuck process may ignore the abort.\n\t\t\t\tcacheable.invalidate();\n\t\t\t\tconst backstop = new AbortController();\n\t\t\t\tconst runSignal = signal != null ? AbortSignal.any([signal, backstop.signal]) : backstop.signal;\n\t\t\t\treturn raceWithTimeout(run(correlationKey, runSignal), backstopMs, backstop);\n\t\t\t},\n\t\t\tcancellation,\n\t\t) as Promise<T>;\n\t}\n\n\t@debug()\n\tgetStatus(\n\t\trepoPath: string | undefined,\n\t\toptions?: {\n\t\t\tpriority?: GitCommandPriority;\n\t\t\tforce?: boolean;\n\t\t\tuntracked?: 'no' | 'normal' | 'all';\n\t\t\tbranch?: false;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatus | undefined> {\n\t\tif (repoPath == null) return Promise.resolve(undefined);\n\n\t\t// `-u` already means `-uall`, so an explicit `'all'` shares the default run\n\t\tconst opts = options?.untracked === 'all' ? { ...options, untracked: undefined } : options;\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\tgetStatusReadKey(opts),\n\t\t\t(correlationKey, signal) =>\n\t\t\t\tthis.getStatusCore(repoPath, { ...opts, correlationKey: correlationKey }, signal),\n\t\t\tcancellation,\n\t\t\topts?.force,\n\t\t);\n\t}\n\n\tprivate async getStatusCore(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tpriority?: GitCommandPriority;\n\t\t\tcorrelationKey?: string;\n\t\t\tuntracked?: 'no' | 'normal' | 'all';\n\t\t\tbranch?: false;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatus | undefined> {\n\t\tconst porcelainVersion = (await this.git.supports('git:status:porcelain-v2')) ? 2 : 1;\n\n\t\tconst result = await this.statusCore(\n\t\t\trepoPath,\n\t\t\tporcelainVersion,\n\t\t\t{\n\t\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t\t\tpriority: options?.priority,\n\t\t\t\tcorrelationKey: options?.correlationKey,\n\t\t\t\tuntracked: options?.untracked,\n\t\t\t\tbranch: options?.branch,\n\t\t\t\terrors: 'throw',\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t\tconst status = parseGitStatus(result.stdout, repoPath, porcelainVersion);\n\n\t\tif (options?.branch === false) {\n\t\t\t// Without `--branch` a clean tree prints nothing at all, which the parser reads as no status\n\t\t\tif (status == null && result.completion.status === 'exited' && result.exitCode === 0) {\n\t\t\t\treturn new GitStatus(normalizePath(repoPath), '', '', []);\n\t\t\t}\n\t\t\t// No branch name either, which `GitStatus` reads as detached, so there is no paused rebase to look up\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status?.detached) {\n\t\t\tconst pausedOpStatus = await this.provider.pausedOps?.getPausedOperationStatus?.(\n\t\t\t\trepoPath,\n\t\t\t\tundefined,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (pausedOpStatus?.type === 'rebase') {\n\t\t\t\treturn new GitStatus(\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpausedOpStatus.incoming.name,\n\t\t\t\t\tstatus.sha,\n\t\t\t\t\tstatus.files,\n\t\t\t\t\tstatus.upstream,\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn status;\n\t}\n\n\t@debug()\n\tasync getStatusForFile(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\toptions?: { renames?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatusFile | undefined> {\n\t\tconst files = await this.getStatusForPathCore(\n\t\t\trepoPath,\n\t\t\ttoFsPath(pathOrUri),\n\t\t\t{ ...options, exact: true },\n\t\t\tcancellation,\n\t\t);\n\t\treturn files?.[0];\n\t}\n\n\t@debug()\n\tasync getStatusForPath(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\toptions?: { renames?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatusFile[] | undefined> {\n\t\treturn this.getStatusForPathCore(repoPath, toFsPath(pathOrUri), { ...options, exact: false }, cancellation);\n\t}\n\n\tprivate async getStatusForPathCore(\n\t\trepoPath: string,\n\t\tpathOrUri: string,\n\t\toptions: { exact: boolean; renames?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatusFile[] | undefined> {\n\t\tconst relativePath = stripFolderGlob(splitPath(pathOrUri, repoPath)[0]);\n\n\t\t// Rename-aware queries can't scope by pathspec (that disables Git's rename detection), so they run the\n\t\t// SAME full `git status` as `getStatus`. Delegate to it — sharing one process/dedup entry — and filter,\n\t\t// rather than spawning a second identical `git status`.\n\t\tif (options.renames !== false) {\n\t\t\t// The rename path keeps the default handling the scoped read gets\n\t\t\tconst status = await this.getStatus(repoPath, undefined, cancellation).catch((ex: unknown) => {\n\t\t\t\tdefaultExceptionHandler(ex as Error, repoPath);\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t\tif (status == null) return undefined;\n\n\t\t\tif (options.exact) {\n\t\t\t\tconst file = status.files.find(f => f.path === relativePath);\n\t\t\t\treturn file ? [file] : undefined;\n\t\t\t}\n\t\t\treturn status.files.filter(f => f.path.startsWith(relativePath));\n\t\t}\n\n\t\t// Non-rename query: pathspec-scoped `git status` (a distinct command), deduped on its own key. `exact`\n\t\t// is NOT in the key — the pathspec-scoped command is identical for exact/non-exact, so both share one run.\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t// Free-form `relativePath` (may contain `:`) goes LAST so the prefix can't be shifted into it.\n\t\t\t`getStatusForPath:${relativePath}`,\n\t\t\t(correlationKey, signal) => this.getStatusForPathScoped(repoPath, relativePath, correlationKey, signal),\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprivate async getStatusForPathScoped(\n\t\trepoPath: string,\n\t\trelativePath: string,\n\t\tcorrelationKey: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitStatusFile[] | undefined> {\n\t\tconst porcelainVersion = (await this.git.supports('git:status:porcelain-v2')) ? 2 : 1;\n\t\tconst result = await this.statusCore(\n\t\t\trepoPath,\n\t\t\tporcelainVersion,\n\t\t\t{ similarityThreshold: this.context.config?.commits.similarityThreshold, correlationKey: correlationKey },\n\t\t\tcancellation,\n\t\t\trelativePath,\n\t\t);\n\n\t\tconst status = parseGitStatus(result.stdout, repoPath, porcelainVersion);\n\t\treturn status?.files;\n\t}\n\n\tprivate async statusCore(\n\t\trepoPath: string,\n\t\tporcelainVersion: number = 1,\n\t\toptions?: {\n\t\t\tsimilarityThreshold?: number | null;\n\t\t\tpriority?: GitCommandPriority;\n\t\t\tcorrelationKey?: string;\n\t\t\tuntracked?: 'no' | 'normal' | 'all';\n\t\t\tbranch?: false;\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t\t...pathspecs: string[]\n\t): Promise<GitResult> {\n\t\tconst params = ['status', porcelainVersion >= 2 ? `--porcelain=v${porcelainVersion}` : '--porcelain'];\n\t\tif (options?.branch !== false) {\n\t\t\tparams.push('--branch');\n\t\t}\n\t\tparams.push(options?.untracked != null ? `-u${options.untracked}` : '-u');\n\t\tif (await this.git.supports('git:status:find-renames')) {\n\t\t\tparams.push(\n\t\t\t\t`--find-renames${options?.similarityThreshold == null ? '' : `=${options.similarityThreshold}%`}`,\n\t\t\t);\n\t\t}\n\n\t\treturn this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\tconfigs: gitConfigsStatus,\n\t\t\t\tenv: { GIT_OPTIONAL_LOCKS: '0' },\n\t\t\t\tcorrelationKey: options?.correlationKey,\n\t\t\t\t...(options?.errors != null ? { errors: options.errors } : undefined),\n\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t},\n\t\t\t...params,\n\t\t\t'--',\n\t\t\t...pathspecs,\n\t\t);\n\t}\n\n\t@debug()\n\thasWorkingChanges(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tstaged?: boolean;\n\t\t\tunstaged?: boolean;\n\t\t\tuntracked?: boolean;\n\t\t\tpriority?: GitCommandPriority;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst staged = options?.staged ?? true;\n\t\tconst unstaged = options?.unstaged ?? true;\n\t\tconst untracked = options?.untracked ?? true;\n\t\t// `priority` is in the key even though it doesn't change the answer: a joiner INHERITS the in-flight run's\n\t\t// scheduling. `GitQueue` refuses to start background work while anything is waiting at normal/interactive,\n\t\t// so letting a foreground caller (the overview's dirty pill, the Worktrees view) join a `background` probe\n\t\t// would strand it for the whole graph load. Splitting the two lanes costs at most one extra spawn; joining\n\t\t// costs unbounded foreground latency.\n\t\tconst priority = options?.priority ?? 'default';\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t`hasWorkingChanges:${staged}:${unstaged}:${untracked}:${priority}`,\n\t\t\tasync (correlationKey, signal) => {\n\t\t\t\tif (staged || unstaged) {\n\t\t\t\t\tconst diffQuiet = (revision: string | undefined) =>\n\t\t\t\t\t\tthis.git.run(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\t\t\tcancellation: signal,\n\t\t\t\t\t\t\t\terrors: 'throw',\n\t\t\t\t\t\t\t\texpectedExitCodes: [1],\n\t\t\t\t\t\t\t\tcorrelationKey: correlationKey,\n\t\t\t\t\t\t\t\t...(options?.priority != null ? { priority: options.priority } : undefined),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'diff',\n\t\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t\trevision,\n\t\t\t\t\t\t\t'--',\n\t\t\t\t\t\t);\n\n\t\t\t\t\tlet result;\n\t\t\t\t\tif (staged && unstaged) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresult = await diffQuiet('HEAD');\n\t\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t\t// Before the first commit HEAD names nothing; everything staged or modified is a change\n\t\t\t\t\t\t\t// against the empty tree. `diff HEAD --` names only HEAD, so its \"bad revision\" is that case\n\t\t\t\t\t\t\t// without re-validating HEAD (a corrupt HEAD then reads as dirty, the safe answer)\n\t\t\t\t\t\t\tif (GitErrors.badRevision.exec(String(ex))?.[1]?.toUpperCase() !== 'HEAD') throw ex;\n\n\t\t\t\t\t\t\tresult = await diffQuiet(await this.provider.revision.getEmptyTreeSha(repoPath));\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = await diffQuiet(staged ? '--staged' : undefined);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.exitCode === 1) {\n\t\t\t\t\t\tif (staged && unstaged) {\n\t\t\t\t\t\t\tscope?.addExitInfo('has staged and unstaged changes');\n\t\t\t\t\t\t} else if (staged) {\n\t\t\t\t\t\t\tscope?.addExitInfo('has staged changes');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tscope?.addExitInfo('has unstaged changes');\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check for untracked files. NOTE: this runs through `git.stream`, which spawns directly\n\t\t\t\t// and never enters the queue — so `priority` above doesn't reach it. Only clean worktrees\n\t\t\t\t// get this far (a dirty one already returned above), and callers fanning out across many\n\t\t\t\t// worktrees are expected to bound their own concurrency.\n\t\t\t\tif (untracked) {\n\t\t\t\t\tconst hasUntracked = await this.hasUntrackedFiles(repoPath, signal);\n\t\t\t\t\tif (hasUntracked) {\n\t\t\t\t\t\tscope?.addExitInfo('has untracked files');\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tscope?.addExitInfo('no working changes');\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@debug()\n\tgetWorkingChangesState(repoPath: string, cancellation?: AbortSignal): Promise<GitWorkingChangesState> {\n\t\tconst scope = getScopedLogger();\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t'getWorkingChangesState',\n\t\t\tasync (correlationKey, signal) => {\n\t\t\t\tconst [stagedResult, unstagedResult, untrackedResult] = await Promise.allSettled([\n\t\t\t\t\t// Check for staged changes\n\t\t\t\t\tthis.git.run(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\t\tcancellation: signal,\n\t\t\t\t\t\t\terrors: 'throw',\n\t\t\t\t\t\t\texpectedExitCodes: [1],\n\t\t\t\t\t\t\tcorrelationKey: correlationKey,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t'diff',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t\t'--staged',\n\t\t\t\t\t),\n\t\t\t\t\t// Check for unstaged changes\n\t\t\t\t\tthis.git.run(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\t\t\tcancellation: signal,\n\t\t\t\t\t\t\terrors: 'throw',\n\t\t\t\t\t\t\texpectedExitCodes: [1],\n\t\t\t\t\t\t\tcorrelationKey: correlationKey,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t'diff',\n\t\t\t\t\t\t'--quiet',\n\t\t\t\t\t),\n\t\t\t\t\t// Check for untracked files\n\t\t\t\t\tthis.hasUntrackedFiles(repoPath, signal),\n\t\t\t\t]);\n\n\t\t\t\tfor (const settled of [stagedResult, unstagedResult, untrackedResult]) {\n\t\t\t\t\tif (settled.status === 'rejected') throw settled.reason;\n\t\t\t\t}\n\n\t\t\t\tconst result = {\n\t\t\t\t\tstaged: getSettledValue(stagedResult)?.exitCode === 1,\n\t\t\t\t\tunstaged: getSettledValue(unstagedResult)?.exitCode === 1,\n\t\t\t\t\tuntracked: getSettledValue(untrackedResult) === true,\n\t\t\t\t};\n\n\t\t\t\tscope?.addExitInfo(\n\t\t\t\t\tresult.staged || result.unstaged || result.untracked\n\t\t\t\t\t\t? `has ${result.staged ? 'staged' : ''}${result.unstaged ? (result.staged ? ', unstaged' : 'unstaged ') : ''}${\n\t\t\t\t\t\t\t\tresult.untracked ? (result.staged || result.unstaged ? ', untracked' : 'untracked') : ''\n\t\t\t\t\t\t\t} changes`\n\t\t\t\t\t\t: 'no working changes',\n\t\t\t\t);\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\thasConflictingFiles(repoPath: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\t// Route through `dedupeByStatusGeneration` (like every other point-in-time read here) for the join-fence\n\t\t// and the `raceWithTimeout` backstop — a bare `git.stream` has no per-command timeout and could wedge.\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t'hasConflictingFiles',\n\t\t\tasync (_correlationKey, signal) => {\n\t\t\t\tconst stream = this.git.stream({ cwd: repoPath, cancellation: signal }, 'ls-files', '--unmerged');\n\t\t\t\tusing _streamDisposer = createDisposable(() => void stream.return?.(undefined));\n\n\t\t\t\t// Early exit on first chunk - breaking causes SIGPIPE, killing git process\n\t\t\t\tfor await (const _chunk of stream) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@debug()\n\tgetConflictingFiles(repoPath: string, cancellation?: AbortSignal): Promise<GitConflictFile[]> {\n\t\tconst scope = getScopedLogger();\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\t'getConflictingFiles',\n\t\t\tasync (correlationKey, signal) => {\n\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t{ cwd: repoPath, cancellation: signal, errors: 'throw', correlationKey: correlationKey },\n\t\t\t\t\t'ls-files',\n\t\t\t\t\t'-z',\n\t\t\t\t\t'--unmerged',\n\t\t\t\t);\n\n\t\t\t\tif (!result.stdout) {\n\t\t\t\t\tscope?.addExitInfo('no conflicting files');\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst files = parseGitConflictFiles(result.stdout, repoPath);\n\t\t\t\tscope?.addExitInfo(`${String(files.length)} conflicting file(s)`);\n\t\t\t\treturn files;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprivate async hasUntrackedFiles(repoPath: string, cancellation?: AbortSignal): Promise<boolean> {\n\t\tconst stream = this.git.stream(\n\t\t\t{ cwd: repoPath, cancellation: cancellation },\n\t\t\t'ls-files',\n\t\t\t// '-z', // Unneeded since we are only looking for presence\n\t\t\t'--others',\n\t\t\t'--exclude-standard',\n\t\t);\n\t\tusing _streamDisposer = createDisposable(() => void stream.return?.(undefined));\n\n\t\t// Early exit on first chunk - breaking causes SIGPIPE, killing git process\n\t\tfor await (const _chunk of stream) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t@debug()\n\tgetUntrackedFiles(\n\t\trepoPath: string,\n\t\toptions?: { paths?: readonly string[] },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitFile[]> {\n\t\tconst scope = getScopedLogger();\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 Promise.resolve([]);\n\n\t\t// Literal pathspecs so a folder named like a glob (`[id]/`) doesn't match its siblings\n\t\tconst pathspecs = paths?.map(p => `:(literal)${p}`);\n\n\t\t// Path-scoped reads join only an identical path set; `\\0` can't appear in a path\n\t\tconst read = pathspecs != null ? `getUntrackedFiles\\0${pathspecs.join('\\0')}` : 'getUntrackedFiles';\n\n\t\treturn this.dedupeByStatusGeneration(\n\t\t\trepoPath,\n\t\t\tread,\n\t\t\tasync (correlationKey, signal) => {\n\t\t\t\tconst prefix = ['ls-files', '-z', '--others', '--exclude-standard'];\n\n\t\t\t\t// Batch the pathspecs to stay under the command-line length limit (a single batch when unscoped).\n\t\t\t\t// Reserve the prefix and a per-arg overhead (separator + possible quoting), so neither a run of\n\t\t\t\t// long paths nor many short ones can push a batch past the OS limit.\n\t\t\t\tlet batches: Iterable<readonly string[]> = [[]];\n\t\t\t\tif (pathspecs != null) {\n\t\t\t\t\tconst perArgOverhead = 3;\n\t\t\t\t\tconst prefixLength = [...prefix, '--'].reduce((sum, arg) => sum + arg.length + perArgOverhead, 0);\n\t\t\t\t\tbatches = chunkByStringLength(pathspecs, maxGitCliLength - prefixLength, perArgOverhead);\n\t\t\t\t}\n\n\t\t\t\tconst seen = new Set<string>();\n\t\t\t\tconst files: GitFile[] = [];\n\n\t\t\t\tfor (const batch of batches) {\n\t\t\t\t\tconst result = await this.git.run(\n\t\t\t\t\t\t{ cwd: repoPath, cancellation: signal, errors: 'throw', correlationKey: correlationKey },\n\t\t\t\t\t\t...prefix,\n\t\t\t\t\t\t...(pathspecs != null ? ['--', ...batch] : []),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!result.stdout) continue;\n\n\t\t\t\t\tfor (const line of iterateByDelimiter(result.stdout, '\\0')) {\n\t\t\t\t\t\tif (!line.length || seen.has(line)) continue;\n\n\t\t\t\t\t\tseen.add(line);\n\t\t\t\t\t\tfiles.push({ path: line, repoPath: repoPath, status: GitFileWorkingTreeStatus.Untracked });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tscope?.addExitInfo(files.length ? `${String(files.length)} untracked file(s)` : 'no untracked files');\n\t\t\t\treturn files;\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -92,8 +92,6 @@ var TagsGitSubProvider = class {
|
|
|
92
92
|
if (message != null && message.length > 0) args.push("-m", message);
|
|
93
93
|
try {
|
|
94
94
|
await this.git.run({ cwd: repoPath }, ...args);
|
|
95
|
-
this.context.hooks?.cache?.onReset?.(repoPath, "tags");
|
|
96
|
-
this.context.hooks?.repository?.onChanged?.(repoPath, ["tags"]);
|
|
97
95
|
} catch (ex) {
|
|
98
96
|
throw getGitCommandError("tag", ex, (reason) => new TagError({
|
|
99
97
|
reason,
|
|
@@ -104,6 +102,9 @@ var TagsGitSubProvider = class {
|
|
|
104
102
|
args
|
|
105
103
|
}
|
|
106
104
|
}, ex));
|
|
105
|
+
} finally {
|
|
106
|
+
this.context.hooks?.cache?.onReset?.(repoPath, "tags");
|
|
107
|
+
this.context.hooks?.repository?.onChanged?.(repoPath, ["tags"]);
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
async deleteTag(repoPath, name) {
|
|
@@ -114,8 +115,6 @@ var TagsGitSubProvider = class {
|
|
|
114
115
|
];
|
|
115
116
|
try {
|
|
116
117
|
await this.git.run({ cwd: repoPath }, ...args);
|
|
117
|
-
this.context.hooks?.cache?.onReset?.(repoPath, "tags");
|
|
118
|
-
this.context.hooks?.repository?.onChanged?.(repoPath, ["tags"]);
|
|
119
118
|
} catch (ex) {
|
|
120
119
|
throw getGitCommandError("tag", ex, (reason) => new TagError({
|
|
121
120
|
reason,
|
|
@@ -126,6 +125,9 @@ var TagsGitSubProvider = class {
|
|
|
126
125
|
args
|
|
127
126
|
}
|
|
128
127
|
}, ex));
|
|
128
|
+
} finally {
|
|
129
|
+
this.context.hooks?.cache?.onReset?.(repoPath, "tags");
|
|
130
|
+
this.context.hooks?.repository?.onChanged?.(repoPath, ["tags"]);
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
async pushTag(repoPath, name, remote, options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.js","names":[],"sources":["../../../../git-cli/src/providers/tags.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { TagError } from '@gitlens/git/errors.js';\nimport { GitTag } from '@gitlens/git/models/tag.js';\nimport type { GitTagsSubProvider } from '@gitlens/git/providers/tags.js';\nimport type { TagSortOptions } from '@gitlens/git/utils/sorting.js';\nimport { sortTags } from '@gitlens/git/utils/sorting.js';\nimport { ensureArray, filterMap } from '@gitlens/utils/array.js';\nimport { isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport type { PagedResult, PagingOptions } from '@gitlens/utils/paging.js';\nimport { emptyPagedResult } from '@gitlens/utils/paging.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult } from '../exec/exec.types.js';\nimport type { Git, GitError } from '../exec/git.js';\nimport { getGitCommandError, gitConfigsBranch } from '../exec/git.js';\n\nexport class TagsGitSubProvider implements GitTagsSubProvider {\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 getTag(repoPath: string, name: string, cancellation?: AbortSignal): Promise<GitTag | undefined> {\n\t\tconst {\n\t\t\tvalues: [tag],\n\t\t} = await this.getTags(repoPath, { filter: t => t.name === name }, cancellation);\n\t\treturn tag;\n\t}\n\n\t@debug({ args: repoPath => ({ repoPath: repoPath }) })\n\tasync getTags(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tfilter?: (t: GitTag) => boolean;\n\t\t\tpaging?: PagingOptions;\n\t\t\tsort?: boolean | TagSortOptions;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PagedResult<GitTag>> {\n\t\tif (!repoPath) return emptyPagedResult;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tlet tagsResult = await this.cache.getTags(\n\t\t\trepoPath,\n\t\t\tasync (commonPath, _cacheable, signal) => {\n\t\t\t\t// Prefer the aggregate signal from the cache; fall back to the caller's cancellation.\n\t\t\t\tsignal ??= cancellation;\n\t\t\t\ttry {\n\t\t\t\t\tconst records = await this.provider.refs.getRefs(commonPath, signal);\n\t\t\t\t\tif (!records.length) return emptyPagedResult;\n\n\t\t\t\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\t\t\t\tconst tags: GitTag[] = [];\n\n\t\t\t\t\tfor (const record of records) {\n\t\t\t\t\t\tconst fullName = record.name;\n\t\t\t\t\t\tif (!fullName.startsWith('refs/tags/')) continue;\n\n\t\t\t\t\t\t// Annotated tags: peeledObjectname is the commit SHA; objectname is the tag-object SHA.\n\t\t\t\t\t\t// Lightweight tags: peeledObjectname is empty; objectname is already the commit SHA.\n\t\t\t\t\t\tconst annotated = Boolean(record.peeledObjectname);\n\t\t\t\t\t\tconst sha = record.peeledObjectname || record.objectname;\n\n\t\t\t\t\t\ttags.push(\n\t\t\t\t\t\t\tnew GitTag(\n\t\t\t\t\t\t\t\tcommonPath,\n\t\t\t\t\t\t\t\tfullName,\n\t\t\t\t\t\t\t\tsha,\n\t\t\t\t\t\t\t\trecord.subject,\n\t\t\t\t\t\t\t\trecord.creatorDate ? new Date(record.creatorDate) : undefined,\n\t\t\t\t\t\t\t\trecord.authorDate ? new Date(record.authorDate) : undefined,\n\t\t\t\t\t\t\t\tannotated,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tsw?.stop({ suffix: ` parsed ${String(tags.length)} tags` });\n\n\t\t\t\t\treturn { values: tags };\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tscope?.error(ex);\n\t\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\t\treturn emptyPagedResult;\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\n\t\tif (options?.filter != null) {\n\t\t\ttagsResult = {\n\t\t\t\t...tagsResult,\n\t\t\t\tvalues: tagsResult.values.filter(options.filter),\n\t\t\t};\n\t\t}\n\n\t\tif (options?.sort) {\n\t\t\tsortTags(tagsResult.values, typeof options.sort === 'boolean' ? undefined : options.sort);\n\t\t}\n\n\t\treturn tagsResult;\n\t}\n\n\t@debug()\n\tasync getTagsWithCommit(\n\t\trepoPath: string,\n\t\tsha: string,\n\t\toptions?: { commitDate?: Date; mode?: 'contains' | 'pointsAt' },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string[]> {\n\t\tconst result = await this.tagsContainingCore(repoPath, sha, options, cancellation);\n\t\tif (!result.stdout) return [];\n\n\t\treturn filterMap(result.stdout.split('\\n'), b => b.trim() || undefined);\n\t}\n\n\tprivate async tagsContainingCore(\n\t\trepoPath: string,\n\t\tsha: string,\n\t\toptions?: { mode?: 'contains' | 'pointsAt' },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitResult> {\n\t\tconst params: string[] = ['tag', '--format=%(refname:short)'];\n\t\tparams.push(options?.mode === 'pointsAt' ? `--points-at=${sha}` : `--contains=${sha}`);\n\n\t\treturn this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\tconfigs: gitConfigsBranch,\n\t\t\t\terrors: 'ignore',\n\t\t\t},\n\t\t\t...params,\n\t\t);\n\t}\n\n\t@debug()\n\tasync createTag(repoPath: string, name: string, sha: string, message?: string): Promise<void> {\n\t\tconst args = ['tag', name, sha];\n\t\tif (message != null && message.length > 0) {\n\t\t\targs.push('-m', message);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, ...args);\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'tags');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['tags']);\n\t\t} catch (ex) {\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'tag',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew TagError(\n\t\t\t\t\t\t{ reason: reason, action: 'create', tag: name, gitCommand: { repoPath: repoPath, args: args } },\n\t\t\t\t\t\tex as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\t@debug()\n\tasync deleteTag(repoPath: string, name: string): Promise<void> {\n\t\tconst args = ['tag', '-d', name];\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, ...args);\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'tags');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['tags']);\n\t\t} catch (ex) {\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'tag',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew TagError(\n\t\t\t\t\t\t{ reason: reason, action: 'delete', tag: name, gitCommand: { repoPath: repoPath, args: args } },\n\t\t\t\t\t\tex as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\t@debug()\n\tasync pushTag(\n\t\trepoPath: string,\n\t\tname: string | string[],\n\t\tremote: string,\n\t\toptions?: { force?: boolean },\n\t): Promise<void> {\n\t\tconst names = ensureArray(name);\n\t\tconst args = ['push'];\n\t\tif (options?.force) {\n\t\t\targs.push('--force');\n\t\t}\n\n\t\targs.push(remote, ...names.map(n => `refs/tags/${n}`));\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, ...args);\n\t\t} catch (ex) {\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'tag',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew TagError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\taction: 'push',\n\t\t\t\t\t\t\ttag: names.join(', '),\n\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tex as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tags.js","names":[],"sources":["../../../../git-cli/src/providers/tags.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { TagError } from '@gitlens/git/errors.js';\nimport { GitTag } from '@gitlens/git/models/tag.js';\nimport type { GitTagsSubProvider } from '@gitlens/git/providers/tags.js';\nimport type { TagSortOptions } from '@gitlens/git/utils/sorting.js';\nimport { sortTags } from '@gitlens/git/utils/sorting.js';\nimport { ensureArray, filterMap } from '@gitlens/utils/array.js';\nimport { isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport type { PagedResult, PagingOptions } from '@gitlens/utils/paging.js';\nimport { emptyPagedResult } from '@gitlens/utils/paging.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult } from '../exec/exec.types.js';\nimport type { Git, GitError } from '../exec/git.js';\nimport { getGitCommandError, gitConfigsBranch } from '../exec/git.js';\n\nexport class TagsGitSubProvider implements GitTagsSubProvider {\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 getTag(repoPath: string, name: string, cancellation?: AbortSignal): Promise<GitTag | undefined> {\n\t\tconst {\n\t\t\tvalues: [tag],\n\t\t} = await this.getTags(repoPath, { filter: t => t.name === name }, cancellation);\n\t\treturn tag;\n\t}\n\n\t@debug({ args: repoPath => ({ repoPath: repoPath }) })\n\tasync getTags(\n\t\trepoPath: string,\n\t\toptions?: {\n\t\t\tfilter?: (t: GitTag) => boolean;\n\t\t\tpaging?: PagingOptions;\n\t\t\tsort?: boolean | TagSortOptions;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PagedResult<GitTag>> {\n\t\tif (!repoPath) return emptyPagedResult;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tlet tagsResult = await this.cache.getTags(\n\t\t\trepoPath,\n\t\t\tasync (commonPath, _cacheable, signal) => {\n\t\t\t\t// Prefer the aggregate signal from the cache; fall back to the caller's cancellation.\n\t\t\t\tsignal ??= cancellation;\n\t\t\t\ttry {\n\t\t\t\t\tconst records = await this.provider.refs.getRefs(commonPath, signal);\n\t\t\t\t\tif (!records.length) return emptyPagedResult;\n\n\t\t\t\t\tusing sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });\n\n\t\t\t\t\tconst tags: GitTag[] = [];\n\n\t\t\t\t\tfor (const record of records) {\n\t\t\t\t\t\tconst fullName = record.name;\n\t\t\t\t\t\tif (!fullName.startsWith('refs/tags/')) continue;\n\n\t\t\t\t\t\t// Annotated tags: peeledObjectname is the commit SHA; objectname is the tag-object SHA.\n\t\t\t\t\t\t// Lightweight tags: peeledObjectname is empty; objectname is already the commit SHA.\n\t\t\t\t\t\tconst annotated = Boolean(record.peeledObjectname);\n\t\t\t\t\t\tconst sha = record.peeledObjectname || record.objectname;\n\n\t\t\t\t\t\ttags.push(\n\t\t\t\t\t\t\tnew GitTag(\n\t\t\t\t\t\t\t\tcommonPath,\n\t\t\t\t\t\t\t\tfullName,\n\t\t\t\t\t\t\t\tsha,\n\t\t\t\t\t\t\t\trecord.subject,\n\t\t\t\t\t\t\t\trecord.creatorDate ? new Date(record.creatorDate) : undefined,\n\t\t\t\t\t\t\t\trecord.authorDate ? new Date(record.authorDate) : undefined,\n\t\t\t\t\t\t\t\tannotated,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tsw?.stop({ suffix: ` parsed ${String(tags.length)} tags` });\n\n\t\t\t\t\treturn { values: tags };\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tscope?.error(ex);\n\t\t\t\t\tif (isCancellationError(ex)) throw ex;\n\n\t\t\t\t\treturn emptyPagedResult;\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\n\t\tif (options?.filter != null) {\n\t\t\ttagsResult = {\n\t\t\t\t...tagsResult,\n\t\t\t\tvalues: tagsResult.values.filter(options.filter),\n\t\t\t};\n\t\t}\n\n\t\tif (options?.sort) {\n\t\t\tsortTags(tagsResult.values, typeof options.sort === 'boolean' ? undefined : options.sort);\n\t\t}\n\n\t\treturn tagsResult;\n\t}\n\n\t@debug()\n\tasync getTagsWithCommit(\n\t\trepoPath: string,\n\t\tsha: string,\n\t\toptions?: { commitDate?: Date; mode?: 'contains' | 'pointsAt' },\n\t\tcancellation?: AbortSignal,\n\t): Promise<string[]> {\n\t\tconst result = await this.tagsContainingCore(repoPath, sha, options, cancellation);\n\t\tif (!result.stdout) return [];\n\n\t\treturn filterMap(result.stdout.split('\\n'), b => b.trim() || undefined);\n\t}\n\n\tprivate async tagsContainingCore(\n\t\trepoPath: string,\n\t\tsha: string,\n\t\toptions?: { mode?: 'contains' | 'pointsAt' },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitResult> {\n\t\tconst params: string[] = ['tag', '--format=%(refname:short)'];\n\t\tparams.push(options?.mode === 'pointsAt' ? `--points-at=${sha}` : `--contains=${sha}`);\n\n\t\treturn this.git.run(\n\t\t\t{\n\t\t\t\tcwd: repoPath,\n\t\t\t\tcancellation: cancellation,\n\t\t\t\tconfigs: gitConfigsBranch,\n\t\t\t\terrors: 'ignore',\n\t\t\t},\n\t\t\t...params,\n\t\t);\n\t}\n\n\t@debug()\n\tasync createTag(repoPath: string, name: string, sha: string, message?: string): Promise<void> {\n\t\tconst args = ['tag', name, sha];\n\t\tif (message != null && message.length > 0) {\n\t\t\targs.push('-m', message);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, ...args);\n\t\t} catch (ex) {\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'tag',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew TagError(\n\t\t\t\t\t\t{ reason: reason, action: 'create', tag: name, gitCommand: { repoPath: repoPath, args: args } },\n\t\t\t\t\t\tex as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t} finally {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'tags');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['tags']);\n\t\t}\n\t}\n\n\t@debug()\n\tasync deleteTag(repoPath: string, name: string): Promise<void> {\n\t\tconst args = ['tag', '-d', name];\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, ...args);\n\t\t} catch (ex) {\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'tag',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew TagError(\n\t\t\t\t\t\t{ reason: reason, action: 'delete', tag: name, gitCommand: { repoPath: repoPath, args: args } },\n\t\t\t\t\t\tex as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t} finally {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'tags');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['tags']);\n\t\t}\n\t}\n\n\t@debug()\n\tasync pushTag(\n\t\trepoPath: string,\n\t\tname: string | string[],\n\t\tremote: string,\n\t\toptions?: { force?: boolean },\n\t): Promise<void> {\n\t\tconst names = ensureArray(name);\n\t\tconst args = ['push'];\n\t\tif (options?.force) {\n\t\t\targs.push('--force');\n\t\t}\n\n\t\targs.push(remote, ...names.map(n => `refs/tags/${n}`));\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath }, ...args);\n\t\t} catch (ex) {\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'tag',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew TagError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\taction: 'push',\n\t\t\t\t\t\t\ttag: names.join(', '),\n\t\t\t\t\t\t\tgitCommand: { repoPath: repoPath, args: args },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tex as GitError,\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -33,6 +33,7 @@ export declare class WorktreesGitSubProvider implements GitWorktreesSubProvider
|
|
|
33
33
|
}, runOptions?: GitOperationRunOptions): Promise<GitWorktree | undefined>;
|
|
34
34
|
getWorktree(repoPath: string, predicate: (w: GitWorktree) => boolean, cancellation?: AbortSignal): Promise<GitWorktree | undefined>;
|
|
35
35
|
getWorktrees(repoPath: string, cancellation?: AbortSignal): Promise<GitWorktree[]>;
|
|
36
|
+
private withLockReason;
|
|
36
37
|
getWorktreesDefaultUri(repoPath: string): Uri | undefined;
|
|
37
38
|
/**
|
|
38
39
|
* Deletes a worktree (`git worktree remove`). Pass `force: 'locked'` to also override a locked worktree.
|