@gitkraken/core-gitlens 0.16.3 → 0.16.4
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 +25 -1
- package/dist/git/cache.d.ts +64 -5
- package/dist/git/cache.js +75 -5
- package/dist/git/cache.js.map +1 -1
- package/dist/git/models/branch.d.ts +0 -6
- package/dist/git/models/branch.js.map +1 -1
- package/dist/git/providers/branches.d.ts +65 -1
- package/dist/git/providers/refs.d.ts +3 -2
- package/dist/git/providers/shared/remotes.js +5 -5
- package/dist/git/providers/shared/remotes.js.map +1 -1
- package/dist/git-cli/providers/branches.d.ts +135 -39
- package/dist/git-cli/providers/branches.js +846 -264
- package/dist/git-cli/providers/branches.js.map +1 -1
- package/dist/git-cli/providers/commits.js +37 -20
- package/dist/git-cli/providers/commits.js.map +1 -1
- package/dist/git-cli/providers/config.js +16 -10
- package/dist/git-cli/providers/config.js.map +1 -1
- package/dist/git-cli/providers/contributors.js +3 -3
- package/dist/git-cli/providers/contributors.js.map +1 -1
- package/dist/git-cli/providers/diff.js +15 -12
- package/dist/git-cli/providers/diff.js.map +1 -1
- package/dist/git-cli/providers/graph.js +17 -14
- package/dist/git-cli/providers/graph.js.map +1 -1
- package/dist/git-cli/providers/maintenance.js +3 -3
- package/dist/git-cli/providers/maintenance.js.map +1 -1
- package/dist/git-cli/providers/patch.js +4 -1
- package/dist/git-cli/providers/patch.js.map +1 -1
- package/dist/git-cli/providers/pausedOperations.js +2 -2
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/refs.js +16 -13
- package/dist/git-cli/providers/refs.js.map +1 -1
- package/dist/git-cli/providers/remotes.js +4 -1
- package/dist/git-cli/providers/remotes.js.map +1 -1
- package/dist/git-cli/providers/revision.js +14 -11
- package/dist/git-cli/providers/revision.js.map +1 -1
- package/dist/git-cli/providers/stash.js +2 -2
- package/dist/git-cli/providers/stash.js.map +1 -1
- package/dist/git-cli/providers/status.js +7 -7
- package/dist/git-cli/providers/status.js.map +1 -1
- package/dist/git-cli/providers/tags.js +6 -3
- package/dist/git-cli/providers/tags.js.map +1 -1
- package/dist/git-cli/providers/worktrees.js +3 -3
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/plus/git-github/providers/github/branches.d.ts +9 -1
- package/dist/plus/git-github/providers/github/branches.js +54 -8
- package/dist/plus/git-github/providers/github/branches.js.map +1 -1
- package/dist/plus/integrations/providers/issueSorts.d.ts +1 -0
- package/dist/plus/integrations/reads/drains.d.ts +1 -0
- package/dist/utils/decorators/log.d.ts +3 -1
- package/dist/utils/decorators/log.js +61 -45
- package/dist/utils/decorators/log.js.map +1 -1
- package/dist/utils/logger.d.ts +15 -1
- package/dist/utils/logger.js +30 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/logger.scoped.d.ts +12 -1
- package/dist/utils/logger.scoped.js +38 -4
- package/dist/utils/logger.scoped.js.map +1 -1
- package/package.json +1 -1
|
@@ -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} 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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"}
|
|
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({ quiet: true })\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({ quiet: true, 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({ quiet: true })\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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"}
|
|
@@ -290,9 +290,9 @@ var WorktreesGitSubProvider = class {
|
|
|
290
290
|
}
|
|
291
291
|
};
|
|
292
292
|
__decorate([debug()], WorktreesGitSubProvider.prototype, "createWorktree", null);
|
|
293
|
-
__decorate([debug()], WorktreesGitSubProvider.prototype, "getWorktree", null);
|
|
294
|
-
__decorate([debug()], WorktreesGitSubProvider.prototype, "getWorktrees", null);
|
|
295
|
-
__decorate([debug()], WorktreesGitSubProvider.prototype, "getWorktreesDefaultUri", null);
|
|
293
|
+
__decorate([debug({ quiet: true })], WorktreesGitSubProvider.prototype, "getWorktree", null);
|
|
294
|
+
__decorate([debug({ quiet: true })], WorktreesGitSubProvider.prototype, "getWorktrees", null);
|
|
295
|
+
__decorate([debug({ quiet: true })], WorktreesGitSubProvider.prototype, "getWorktreesDefaultUri", null);
|
|
296
296
|
__decorate([debug()], WorktreesGitSubProvider.prototype, "deleteWorktree", null);
|
|
297
297
|
__decorate([debug()], WorktreesGitSubProvider.prototype, "pruneWorktrees", null);
|
|
298
298
|
__decorate([debug()], WorktreesGitSubProvider.prototype, "lockWorktree", null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktrees.js","names":["basename","fs"],"sources":["../../../../git-cli/src/providers/worktrees.ts"],"sourcesContent":["import { exec } from 'child_process';\nimport { promises as fs } from 'fs';\nimport { join, resolve } from 'path';\nimport * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { WorktreeCreateError, WorktreeDeleteError } from '@gitlens/git/errors.js';\nimport type { WorkspaceFolderResolver } from '@gitlens/git/models/worktree.js';\nimport { GitWorktree } from '@gitlens/git/models/worktree.js';\nimport type { GitOperationRunOptions } from '@gitlens/git/providers/operations.js';\nimport type { GitWorktreesSubProvider } from '@gitlens/git/providers/worktrees.js';\nimport { isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { isWindows } from '@gitlens/utils/env/node/platform.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { basename, normalizePath } from '@gitlens/utils/path.js';\nimport { getSettledValue } from '@gitlens/utils/promise.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fileUri, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport { mayWriteTracking } from '../exec/commandClassifier.js';\nimport type { Git, GitError } from '../exec/git.js';\nimport { getGitCommandError, GitErrors, isRunHookFailure } from '../exec/git.js';\nimport { parseGitWorktrees } from '../parsers/worktreeParser.js';\n\n/** Extracts the lock reason from Git's `cannot remove a locked working tree` output, when it provides one */\nfunction getLockReason(ex: GitError): string | undefined {\n\treturn GitErrors.worktreeLockedReason.exec(ex.stderr || ex.stdout || ex.message || '')?.[1].trim() || undefined;\n}\n\n/**\n * The branch `git worktree add` says it created, from the `Preparing worktree (new branch '<name>')` line it writes to\n * stderr (git 2.17+, in English since every run sets `LC_ALL=C`)\n */\nfunction getNewWorktreeBranch(stderr: string | undefined): string | undefined {\n\treturn stderr ? /^Preparing worktree \\(new branch '(.+)'\\)$/m.exec(stderr)?.[1] : undefined;\n}\n\nexport class WorktreesGitSubProvider implements GitWorktreesSubProvider {\n\tconstructor(\n\t\tprivate readonly context: GitServiceContext,\n\t\tprivate readonly git: Git,\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: CliGitProviderInternal,\n\t) {}\n\n\t/**\n\t * Creates a worktree (`git worktree add`). `runOptions` are spread into the underlying `git.run` call, so a\n\t * large checkout can run without the default command timeout (`{ timeout: 0 }`) and still be cancelled.\n\t */\n\t@debug()\n\tasync createWorktree(\n\t\trepoPath: string,\n\t\tpath: string,\n\t\toptions?: {\n\t\t\tcommitish?: string;\n\t\t\tcreateBranch?: string;\n\t\t\tdetach?: boolean;\n\t\t\tforce?: boolean;\n\t\t\tnoTracking?: boolean;\n\t\t},\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst args = ['worktree', 'add'];\n\t\tif (options?.force) {\n\t\t\targs.push('--force');\n\t\t}\n\t\tif (options?.createBranch) {\n\t\t\targs.push('-b', options.createBranch);\n\t\t}\n\t\tif (options?.createBranch && options.noTracking) {\n\t\t\targs.push('--no-track');\n\t\t}\n\t\tif (options?.detach) {\n\t\t\targs.push('--detach');\n\t\t}\n\t\targs.push(path);\n\t\tif (options?.commitish) {\n\t\t\targs.push(options.commitish);\n\t\t}\n\n\t\t// Without `-b`, git may still create a branch: from a remote branch of the commitish's name, or named after the\n\t\t// path when no commitish is given\n\t\tlet createdBranch = options?.createBranch;\n\t\t// A cancelled or timed-out run, or a host-rejected retry, leaves no output to name the branch git may have created\n\t\tlet mayHaveCreatedBranch = false;\n\t\ttry {\n\t\t\tconst result = await this.git.run({ cwd: repoPath, ...runOptions }, ...args);\n\t\t\tcreatedBranch ??= getNewWorktreeBranch(result.stderr);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\t// `?.`: a host's index-lock retry hook may reject with anything, `undefined` included\n\t\t\tcreatedBranch ??= getNewWorktreeBranch((ex as GitError | undefined)?.stderr);\n\n\t\t\t// A cancelled or timed-out checkout, or a host-rejected index-lock retry, is not git refusing the worktree\n\t\t\tif (isCancellationError(ex) || isRunHookFailure(ex)) {\n\t\t\t\tmayHaveCreatedBranch = createdBranch == null && !options?.detach;\n\t\t\t\tthrow ex;\n\t\t\t}\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'worktree-create',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew WorktreeCreateError(\n\t\t\t\t\t\t{ reason: reason, 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\t// A failed or cancelled add may already have created the branch (and its tracking in `.git/config`) or\n\t\t\t// the worktree directory.\n\t\t\t//\n\t\t\t// The tracking isn't announced as a `config` change, only evicted: git may also write repository-wide\n\t\t\t// keys (`extensions.relativeWorktrees` under `worktree.useRelativePaths`), so the write can't claim its\n\t\t\t// config change is confined to the new branch, and an unconfined one would refresh every worktree on each\n\t\t\t// add. The watcher's report of the file says what changed in it instead.\n\t\t\tif (createdBranch) {\n\t\t\t\t// Evict the cached base only — see `checkout -b` for why the persisted keys are left alone.\n\t\t\t\tthis.cache.deleteBaseBranchName(repoPath, createdBranch);\n\t\t\t\t// A branch git created on its own may track a remote branch, whatever the commitish looks like\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(\n\t\t\t\t\trepoPath,\n\t\t\t\t\t...(!options?.createBranch || mayWriteTracking(options.commitish, options.noTracking)\n\t\t\t\t\t\t? (['branches', 'config', 'worktrees'] as const)\n\t\t\t\t\t\t: (['branches', 'worktrees'] as const)),\n\t\t\t\t);\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(\n\t\t\t\t\trepoPath,\n\t\t\t\t\t['worktrees', 'heads'],\n\t\t\t\t\t[`refs/heads/${createdBranch}`],\n\t\t\t\t);\n\t\t\t} else if (mayHaveCreatedBranch) {\n\t\t\t\t// Git creates the branch before checking it out, so a run cut short may have left one it never named\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'config', 'worktrees');\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees', 'heads']);\n\t\t\t} else {\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync createWorktreeWithResult(\n\t\trepoPath: string,\n\t\tpath: string,\n\t\toptions?: {\n\t\t\tcommitish?: string;\n\t\t\tcreateBranch?: string;\n\t\t\tdetach?: boolean;\n\t\t\tforce?: boolean;\n\t\t\tnoTracking?: boolean;\n\t\t},\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<GitWorktree | undefined> {\n\t\tawait this.createWorktree(repoPath, path, options, runOptions);\n\t\tconst normalized = normalizePath(path);\n\t\treturn this.getWorktree(repoPath, w => normalizePath(w.path) === normalized, runOptions?.cancellation);\n\t}\n\n\t@debug()\n\tasync getWorktree(\n\t\trepoPath: string,\n\t\tpredicate: (w: GitWorktree) => boolean,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitWorktree | undefined> {\n\t\treturn (await this.getWorktrees(repoPath, cancellation)).find(predicate);\n\t}\n\n\t@debug()\n\tasync getWorktrees(repoPath: string, cancellation?: AbortSignal): Promise<GitWorktree[]> {\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Displaying worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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\treturn this.cache.getWorktrees(\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\tconst [dataResult, branchesResult] = await Promise.allSettled([\n\t\t\t\t\tthis.git.run({ cwd: commonPath, cancellation: signal }, 'worktree', 'list', '--porcelain'),\n\t\t\t\t\tthis.provider.branches.getBranches(commonPath, undefined, signal),\n\t\t\t\t]);\n\n\t\t\t\tif (dataResult.status === 'rejected') {\n\t\t\t\t\t// Don't cache a bogus empty result for a transient command failure — retry on next access.\n\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t}\n\n\t\t\t\tconst getWorkspaceFolder: WorkspaceFolderResolver | undefined = this.context.workspace\n\t\t\t\t\t? uri => {\n\t\t\t\t\t\t\tconst folder = this.context.workspace!.getFolder(uri.fsPath);\n\t\t\t\t\t\t\tif (folder == null) return undefined;\n\t\t\t\t\t\t\treturn { uri: fileUri(folder.path), name: basename(folder.path) };\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\n\t\t\t\tconst worktrees = parseGitWorktrees(\n\t\t\t\t\tgetSettledValue(dataResult)?.stdout,\n\t\t\t\t\tcommonPath,\n\t\t\t\t\tgetSettledValue(branchesResult)?.values ?? [],\n\t\t\t\t\tgetWorkspaceFolder,\n\t\t\t\t);\n\n\t\t\t\t// Older git prints a bare `locked` even when a reason exists; recover it from the admin dir\n\t\t\t\tif (await this.git.supports('git:worktree:list:lock-reason')) return worktrees;\n\n\t\t\t\treturn Promise.all(worktrees.map(w => this.withLockReason(w)));\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprivate async withLockReason(worktree: GitWorktree): Promise<GitWorktree> {\n\t\tif (worktree.locked !== true || worktree.isDefault || worktree.type === 'bare') return worktree;\n\n\t\ttry {\n\t\t\t// A linked worktree's `.git` is a file: `gitdir: <admin dir>`, relative to the worktree when not absolute\n\t\t\tconst dotGit = join(worktree.uri.fsPath, '.git');\n\t\t\tconst match = /^gitdir:\\s*(.+?)\\s*$/m.exec(await fs.readFile(dotGit, 'utf8'));\n\t\t\tif (match == null) return worktree;\n\n\t\t\tconst reason = (await fs.readFile(join(resolve(worktree.uri.fsPath, match[1]), 'locked'), 'utf8')).trim();\n\t\t\tif (!reason) return worktree;\n\n\t\t\treturn new GitWorktree(\n\t\t\t\tworktree.isDefault,\n\t\t\t\tworktree.type,\n\t\t\t\tworktree.repoPath,\n\t\t\t\tworktree.uri,\n\t\t\t\treason,\n\t\t\t\tworktree.prunable,\n\t\t\t\tworktree.sha,\n\t\t\t\tworktree.branch,\n\t\t\t\tworktree.workspaceFolder,\n\t\t\t);\n\t\t} catch {\n\t\t\treturn worktree;\n\t\t}\n\t}\n\n\t@debug()\n\tgetWorktreesDefaultUri(repoPath: string): Uri | undefined {\n\t\treturn this.context.workspace?.getWorktreeDefaultUri?.(repoPath);\n\t}\n\n\t/**\n\t * Deletes a worktree (`git worktree remove`). Pass `force: 'locked'` to also override a locked worktree.\n\t *\n\t * `runOptions` are spread into the underlying `git.run` call (e.g. `{ timeout: 0 }` for a large worktree\n\t * whose removal may exceed the default command timeout).\n\t *\n\t * On failure, the thrown {@link WorktreeDeleteError}'s `original` property carries the raw\n\t * {@link GitError} (stderr/stdout/exit code) untouched — a caller that needs to classify a\n\t * platform-specific failure (e.g. a Windows file-lock retry) can read it directly rather than parsing\n\t * the typed error's message.\n\t */\n\t@debug()\n\tasync deleteWorktree(\n\t\trepoPath: string,\n\t\tpath: string | Uri,\n\t\toptions?: { force?: boolean | 'locked' },\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Deleting worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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 args = ['worktree', 'remove'];\n\t\tif (options?.force) {\n\t\t\targs.push('--force');\n\t\t\t// Git requires a second `--force` to remove a locked worktree\n\t\t\tif (options.force === 'locked') {\n\t\t\t\targs.push('--force');\n\t\t\t}\n\t\t}\n\n\t\tconst pathStr = normalizePath(toFsPath(path));\n\t\targs.push(pathStr);\n\n\t\tlet deleted = false;\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw', ...runOptions }, ...args);\n\t\t\tdeleted = true;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\t// A cancelled or timed-out removal (`runOptions.cancellation`/`timeout`), or a host-rejected index-lock\n\t\t\t// retry, is not git refusing it, and wrapping it would hand the caller a `WorktreeDeleteError` whose\n\t\t\t// `original` is no `GitError` at all\n\t\t\tif (isCancellationError(ex) || isRunHookFailure(ex)) throw ex;\n\n\t\t\tconst gitError = getGitCommandError(\n\t\t\t\t'worktree-delete',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew WorktreeDeleteError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\tlockReason: reason === 'locked' ? getLockReason(ex as GitError) : undefined,\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\n\t\t\tif (gitError.details.reason === 'directoryNotEmpty') {\n\t\t\t\tscope?.warn(\n\t\t\t\t\t`Failed to fully delete worktree '${pathStr}' because it is not empty. Attempting to delete it manually.`,\n\t\t\t\t);\n\t\t\t\ttry {\n\t\t\t\t\tawait fs.rm(pathStr, { force: true, recursive: true });\n\t\t\t\t\tdeleted = true;\n\t\t\t\t\treturn;\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tif (isWindows) {\n\t\t\t\t\t\tconst match = /EPERM: operation not permitted, unlink '(.*?)'/i.exec((ex as GitError).message);\n\t\t\t\t\t\tif (match != null) {\n\t\t\t\t\t\t\tscope?.warn(\n\t\t\t\t\t\t\t\t`Failed to manually delete '${pathStr}' because it is in use. Attempting to forcefully delete it.`,\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t// Windows-specific: `del` via cmd.exe to force-remove a locked symlink.\n\t\t\t\t\t\t\t// Node's fs.rm/unlink fails with EPERM when the symlink target is in use.\n\t\t\t\t\t\t\tfunction deleteInUseSymlink(symlink: string) {\n\t\t\t\t\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\t\t\t\t\texec(`del \"${symlink}\"`, (ex, stdout, stderr) => {\n\t\t\t\t\t\t\t\t\t\tif (ex) {\n\t\t\t\t\t\t\t\t\t\t\treject(ex instanceof Error ? ex : new Error(String(ex)));\n\t\t\t\t\t\t\t\t\t\t} else if (stderr) {\n\t\t\t\t\t\t\t\t\t\t\treject(new Error(stderr));\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tresolve(stdout);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst [, file] = match;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait deleteInUseSymlink(file);\n\t\t\t\t\t\t\t\tawait fs.rm(pathStr, { force: true, recursive: true, maxRetries: 1, retryDelay: 1 });\n\t\t\t\t\t\t\t\tdeleted = true;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t\t\tscope?.error(ex, `Failed to forcefully delete '${pathStr}' because it is in use.`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow gitError;\n\t\t} finally {\n\t\t\tif (deleted) {\n\t\t\t\t// Clean up Cache registry + per-worktree cache entries for the deleted worktree.\n\t\t\t\t// Order matters: unregister before emitting the repo-level change so any listener\n\t\t\t\t// that re-queries worktree-aware state sees the registry already updated.\n\t\t\t\tthis.cache.unregisterRepoPath(pathStr);\n\t\t\t}\n\t\t\t// A failed or cancelled removal may already have taken the worktree's files or admin entry\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t}\n\t}\n\n\t@debug()\n\tasync pruneWorktrees(repoPath: string, options?: { expire?: string }): Promise<void> {\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Pruning worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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 before = await this.listWorktreePaths(repoPath);\n\n\t\tconst args = ['worktree', 'prune'];\n\t\tif (options?.expire) {\n\t\t\targs.push('--expire', options.expire);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw' }, ...args);\n\n\t\t\tconst after = await this.listWorktreePaths(repoPath);\n\n\t\t\t// Order matters (see `deleteWorktree`): unregister before emitting the repo-level change so any\n\t\t\t// listener that re-queries worktree-aware state sees the registry already updated.\n\t\t\tif (before != null && after != null) {\n\t\t\t\tfor (const path of before) {\n\t\t\t\t\tif (!after.has(path)) {\n\t\t\t\t\t\tthis.cache.unregisterRepoPath(path);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t}\n\t}\n\n\t/**\n\t * Raw worktree paths currently known to git (`worktree <path>` lines from `--porcelain`), normalized the\n\t * same way {@link deleteWorktree} does. A failed listing (`errors: 'ignore'`) yields an empty set rather\n\t * than throwing — used by `pruneWorktrees` to diff before/after, where a transient read failure must not\n\t * be mistaken for every worktree having vanished.\n\t */\n\tprivate async listWorktreePaths(repoPath: string): Promise<Set<string> | undefined> {\n\t\tconst result = await this.git.run({ cwd: repoPath, errors: 'ignore' }, 'worktree', 'list', '--porcelain');\n\t\t// A failed listing is not an empty one: read as empty, the after-prune one would unregister everything\n\t\tif (result.completion.status !== 'exited' || result.exitCode !== 0) return undefined;\n\n\t\tconst paths = new Set<string>();\n\t\tfor (const line of result.stdout.split('\\n')) {\n\t\t\tif (line.startsWith('worktree ')) {\n\t\t\t\tpaths.add(normalizePath(toFsPath(line.slice('worktree '.length).trim())));\n\t\t\t}\n\t\t}\n\t\treturn paths;\n\t}\n\n\t@debug()\n\tasync lockWorktree(repoPath: string, path: string | Uri, options?: { reason?: string }): Promise<void> {\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Locking worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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 args = ['worktree', 'lock'];\n\t\tif (options?.reason) {\n\t\t\targs.push('--reason', options.reason);\n\t\t}\n\t\targs.push(normalizePath(toFsPath(path)));\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw' }, ...args);\n\t\t} finally {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t}\n\t}\n\n\t@debug()\n\tasync unlockWorktree(repoPath: string, path: string | Uri): Promise<void> {\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Unlocking worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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 pathStr = normalizePath(toFsPath(path));\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw' }, 'worktree', 'unlock', pathStr);\n\t\t} finally {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"worktrees.js","names":["basename","fs"],"sources":["../../../../git-cli/src/providers/worktrees.ts"],"sourcesContent":["import { exec } from 'child_process';\nimport { promises as fs } from 'fs';\nimport { join, resolve } from 'path';\nimport * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport { WorktreeCreateError, WorktreeDeleteError } from '@gitlens/git/errors.js';\nimport type { WorkspaceFolderResolver } from '@gitlens/git/models/worktree.js';\nimport { GitWorktree } from '@gitlens/git/models/worktree.js';\nimport type { GitOperationRunOptions } from '@gitlens/git/providers/operations.js';\nimport type { GitWorktreesSubProvider } from '@gitlens/git/providers/worktrees.js';\nimport { isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { isWindows } from '@gitlens/utils/env/node/platform.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { basename, normalizePath } from '@gitlens/utils/path.js';\nimport { getSettledValue } from '@gitlens/utils/promise.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fileUri, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport { mayWriteTracking } from '../exec/commandClassifier.js';\nimport type { Git, GitError } from '../exec/git.js';\nimport { getGitCommandError, GitErrors, isRunHookFailure } from '../exec/git.js';\nimport { parseGitWorktrees } from '../parsers/worktreeParser.js';\n\n/** Extracts the lock reason from Git's `cannot remove a locked working tree` output, when it provides one */\nfunction getLockReason(ex: GitError): string | undefined {\n\treturn GitErrors.worktreeLockedReason.exec(ex.stderr || ex.stdout || ex.message || '')?.[1].trim() || undefined;\n}\n\n/**\n * The branch `git worktree add` says it created, from the `Preparing worktree (new branch '<name>')` line it writes to\n * stderr (git 2.17+, in English since every run sets `LC_ALL=C`)\n */\nfunction getNewWorktreeBranch(stderr: string | undefined): string | undefined {\n\treturn stderr ? /^Preparing worktree \\(new branch '(.+)'\\)$/m.exec(stderr)?.[1] : undefined;\n}\n\nexport class WorktreesGitSubProvider implements GitWorktreesSubProvider {\n\tconstructor(\n\t\tprivate readonly context: GitServiceContext,\n\t\tprivate readonly git: Git,\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: CliGitProviderInternal,\n\t) {}\n\n\t/**\n\t * Creates a worktree (`git worktree add`). `runOptions` are spread into the underlying `git.run` call, so a\n\t * large checkout can run without the default command timeout (`{ timeout: 0 }`) and still be cancelled.\n\t */\n\t@debug()\n\tasync createWorktree(\n\t\trepoPath: string,\n\t\tpath: string,\n\t\toptions?: {\n\t\t\tcommitish?: string;\n\t\t\tcreateBranch?: string;\n\t\t\tdetach?: boolean;\n\t\t\tforce?: boolean;\n\t\t\tnoTracking?: boolean;\n\t\t},\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst args = ['worktree', 'add'];\n\t\tif (options?.force) {\n\t\t\targs.push('--force');\n\t\t}\n\t\tif (options?.createBranch) {\n\t\t\targs.push('-b', options.createBranch);\n\t\t}\n\t\tif (options?.createBranch && options.noTracking) {\n\t\t\targs.push('--no-track');\n\t\t}\n\t\tif (options?.detach) {\n\t\t\targs.push('--detach');\n\t\t}\n\t\targs.push(path);\n\t\tif (options?.commitish) {\n\t\t\targs.push(options.commitish);\n\t\t}\n\n\t\t// Without `-b`, git may still create a branch: from a remote branch of the commitish's name, or named after the\n\t\t// path when no commitish is given\n\t\tlet createdBranch = options?.createBranch;\n\t\t// A cancelled or timed-out run, or a host-rejected retry, leaves no output to name the branch git may have created\n\t\tlet mayHaveCreatedBranch = false;\n\t\ttry {\n\t\t\tconst result = await this.git.run({ cwd: repoPath, ...runOptions }, ...args);\n\t\t\tcreatedBranch ??= getNewWorktreeBranch(result.stderr);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\t// `?.`: a host's index-lock retry hook may reject with anything, `undefined` included\n\t\t\tcreatedBranch ??= getNewWorktreeBranch((ex as GitError | undefined)?.stderr);\n\n\t\t\t// A cancelled or timed-out checkout, or a host-rejected index-lock retry, is not git refusing the worktree\n\t\t\tif (isCancellationError(ex) || isRunHookFailure(ex)) {\n\t\t\t\tmayHaveCreatedBranch = createdBranch == null && !options?.detach;\n\t\t\t\tthrow ex;\n\t\t\t}\n\n\t\t\tthrow getGitCommandError(\n\t\t\t\t'worktree-create',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew WorktreeCreateError(\n\t\t\t\t\t\t{ reason: reason, 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\t// A failed or cancelled add may already have created the branch (and its tracking in `.git/config`) or\n\t\t\t// the worktree directory.\n\t\t\t//\n\t\t\t// The tracking isn't announced as a `config` change, only evicted: git may also write repository-wide\n\t\t\t// keys (`extensions.relativeWorktrees` under `worktree.useRelativePaths`), so the write can't claim its\n\t\t\t// config change is confined to the new branch, and an unconfined one would refresh every worktree on each\n\t\t\t// add. The watcher's report of the file says what changed in it instead.\n\t\t\tif (createdBranch) {\n\t\t\t\t// Evict the cached base only — see `checkout -b` for why the persisted keys are left alone.\n\t\t\t\tthis.cache.deleteBaseBranchName(repoPath, createdBranch);\n\t\t\t\t// A branch git created on its own may track a remote branch, whatever the commitish looks like\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(\n\t\t\t\t\trepoPath,\n\t\t\t\t\t...(!options?.createBranch || mayWriteTracking(options.commitish, options.noTracking)\n\t\t\t\t\t\t? (['branches', 'config', 'worktrees'] as const)\n\t\t\t\t\t\t: (['branches', 'worktrees'] as const)),\n\t\t\t\t);\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(\n\t\t\t\t\trepoPath,\n\t\t\t\t\t['worktrees', 'heads'],\n\t\t\t\t\t[`refs/heads/${createdBranch}`],\n\t\t\t\t);\n\t\t\t} else if (mayHaveCreatedBranch) {\n\t\t\t\t// Git creates the branch before checking it out, so a run cut short may have left one it never named\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'config', 'worktrees');\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees', 'heads']);\n\t\t\t} else {\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync createWorktreeWithResult(\n\t\trepoPath: string,\n\t\tpath: string,\n\t\toptions?: {\n\t\t\tcommitish?: string;\n\t\t\tcreateBranch?: string;\n\t\t\tdetach?: boolean;\n\t\t\tforce?: boolean;\n\t\t\tnoTracking?: boolean;\n\t\t},\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<GitWorktree | undefined> {\n\t\tawait this.createWorktree(repoPath, path, options, runOptions);\n\t\tconst normalized = normalizePath(path);\n\t\treturn this.getWorktree(repoPath, w => normalizePath(w.path) === normalized, runOptions?.cancellation);\n\t}\n\n\t@debug({ quiet: true })\n\tasync getWorktree(\n\t\trepoPath: string,\n\t\tpredicate: (w: GitWorktree) => boolean,\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitWorktree | undefined> {\n\t\treturn (await this.getWorktrees(repoPath, cancellation)).find(predicate);\n\t}\n\n\t@debug({ quiet: true })\n\tasync getWorktrees(repoPath: string, cancellation?: AbortSignal): Promise<GitWorktree[]> {\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Displaying worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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\treturn this.cache.getWorktrees(\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\tconst [dataResult, branchesResult] = await Promise.allSettled([\n\t\t\t\t\tthis.git.run({ cwd: commonPath, cancellation: signal }, 'worktree', 'list', '--porcelain'),\n\t\t\t\t\tthis.provider.branches.getBranches(commonPath, undefined, signal),\n\t\t\t\t]);\n\n\t\t\t\tif (dataResult.status === 'rejected') {\n\t\t\t\t\t// Don't cache a bogus empty result for a transient command failure — retry on next access.\n\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t}\n\n\t\t\t\tconst getWorkspaceFolder: WorkspaceFolderResolver | undefined = this.context.workspace\n\t\t\t\t\t? uri => {\n\t\t\t\t\t\t\tconst folder = this.context.workspace!.getFolder(uri.fsPath);\n\t\t\t\t\t\t\tif (folder == null) return undefined;\n\t\t\t\t\t\t\treturn { uri: fileUri(folder.path), name: basename(folder.path) };\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\n\t\t\t\tconst worktrees = parseGitWorktrees(\n\t\t\t\t\tgetSettledValue(dataResult)?.stdout,\n\t\t\t\t\tcommonPath,\n\t\t\t\t\tgetSettledValue(branchesResult)?.values ?? [],\n\t\t\t\t\tgetWorkspaceFolder,\n\t\t\t\t);\n\n\t\t\t\t// Older git prints a bare `locked` even when a reason exists; recover it from the admin dir\n\t\t\t\tif (await this.git.supports('git:worktree:list:lock-reason')) return worktrees;\n\n\t\t\t\treturn Promise.all(worktrees.map(w => this.withLockReason(w)));\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprivate async withLockReason(worktree: GitWorktree): Promise<GitWorktree> {\n\t\tif (worktree.locked !== true || worktree.isDefault || worktree.type === 'bare') return worktree;\n\n\t\ttry {\n\t\t\t// A linked worktree's `.git` is a file: `gitdir: <admin dir>`, relative to the worktree when not absolute\n\t\t\tconst dotGit = join(worktree.uri.fsPath, '.git');\n\t\t\tconst match = /^gitdir:\\s*(.+?)\\s*$/m.exec(await fs.readFile(dotGit, 'utf8'));\n\t\t\tif (match == null) return worktree;\n\n\t\t\tconst reason = (await fs.readFile(join(resolve(worktree.uri.fsPath, match[1]), 'locked'), 'utf8')).trim();\n\t\t\tif (!reason) return worktree;\n\n\t\t\treturn new GitWorktree(\n\t\t\t\tworktree.isDefault,\n\t\t\t\tworktree.type,\n\t\t\t\tworktree.repoPath,\n\t\t\t\tworktree.uri,\n\t\t\t\treason,\n\t\t\t\tworktree.prunable,\n\t\t\t\tworktree.sha,\n\t\t\t\tworktree.branch,\n\t\t\t\tworktree.workspaceFolder,\n\t\t\t);\n\t\t} catch {\n\t\t\treturn worktree;\n\t\t}\n\t}\n\n\t@debug({ quiet: true })\n\tgetWorktreesDefaultUri(repoPath: string): Uri | undefined {\n\t\treturn this.context.workspace?.getWorktreeDefaultUri?.(repoPath);\n\t}\n\n\t/**\n\t * Deletes a worktree (`git worktree remove`). Pass `force: 'locked'` to also override a locked worktree.\n\t *\n\t * `runOptions` are spread into the underlying `git.run` call (e.g. `{ timeout: 0 }` for a large worktree\n\t * whose removal may exceed the default command timeout).\n\t *\n\t * On failure, the thrown {@link WorktreeDeleteError}'s `original` property carries the raw\n\t * {@link GitError} (stderr/stdout/exit code) untouched — a caller that needs to classify a\n\t * platform-specific failure (e.g. a Windows file-lock retry) can read it directly rather than parsing\n\t * the typed error's message.\n\t */\n\t@debug()\n\tasync deleteWorktree(\n\t\trepoPath: string,\n\t\tpath: string | Uri,\n\t\toptions?: { force?: boolean | 'locked' },\n\t\trunOptions?: GitOperationRunOptions,\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Deleting worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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 args = ['worktree', 'remove'];\n\t\tif (options?.force) {\n\t\t\targs.push('--force');\n\t\t\t// Git requires a second `--force` to remove a locked worktree\n\t\t\tif (options.force === 'locked') {\n\t\t\t\targs.push('--force');\n\t\t\t}\n\t\t}\n\n\t\tconst pathStr = normalizePath(toFsPath(path));\n\t\targs.push(pathStr);\n\n\t\tlet deleted = false;\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw', ...runOptions }, ...args);\n\t\t\tdeleted = true;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\t// A cancelled or timed-out removal (`runOptions.cancellation`/`timeout`), or a host-rejected index-lock\n\t\t\t// retry, is not git refusing it, and wrapping it would hand the caller a `WorktreeDeleteError` whose\n\t\t\t// `original` is no `GitError` at all\n\t\t\tif (isCancellationError(ex) || isRunHookFailure(ex)) throw ex;\n\n\t\t\tconst gitError = getGitCommandError(\n\t\t\t\t'worktree-delete',\n\t\t\t\tex as GitError,\n\t\t\t\treason =>\n\t\t\t\t\tnew WorktreeDeleteError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treason: reason,\n\t\t\t\t\t\t\tlockReason: reason === 'locked' ? getLockReason(ex as GitError) : undefined,\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\n\t\t\tif (gitError.details.reason === 'directoryNotEmpty') {\n\t\t\t\tscope?.warn(\n\t\t\t\t\t`Failed to fully delete worktree '${pathStr}' because it is not empty. Attempting to delete it manually.`,\n\t\t\t\t);\n\t\t\t\ttry {\n\t\t\t\t\tawait fs.rm(pathStr, { force: true, recursive: true });\n\t\t\t\t\tdeleted = true;\n\t\t\t\t\treturn;\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tif (isWindows) {\n\t\t\t\t\t\tconst match = /EPERM: operation not permitted, unlink '(.*?)'/i.exec((ex as GitError).message);\n\t\t\t\t\t\tif (match != null) {\n\t\t\t\t\t\t\tscope?.warn(\n\t\t\t\t\t\t\t\t`Failed to manually delete '${pathStr}' because it is in use. Attempting to forcefully delete it.`,\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t// Windows-specific: `del` via cmd.exe to force-remove a locked symlink.\n\t\t\t\t\t\t\t// Node's fs.rm/unlink fails with EPERM when the symlink target is in use.\n\t\t\t\t\t\t\tfunction deleteInUseSymlink(symlink: string) {\n\t\t\t\t\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\t\t\t\t\texec(`del \"${symlink}\"`, (ex, stdout, stderr) => {\n\t\t\t\t\t\t\t\t\t\tif (ex) {\n\t\t\t\t\t\t\t\t\t\t\treject(ex instanceof Error ? ex : new Error(String(ex)));\n\t\t\t\t\t\t\t\t\t\t} else if (stderr) {\n\t\t\t\t\t\t\t\t\t\t\treject(new Error(stderr));\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tresolve(stdout);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst [, file] = match;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait deleteInUseSymlink(file);\n\t\t\t\t\t\t\t\tawait fs.rm(pathStr, { force: true, recursive: true, maxRetries: 1, retryDelay: 1 });\n\t\t\t\t\t\t\t\tdeleted = true;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t\t\tscope?.error(ex, `Failed to forcefully delete '${pathStr}' because it is in use.`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow gitError;\n\t\t} finally {\n\t\t\tif (deleted) {\n\t\t\t\t// Clean up Cache registry + per-worktree cache entries for the deleted worktree.\n\t\t\t\t// Order matters: unregister before emitting the repo-level change so any listener\n\t\t\t\t// that re-queries worktree-aware state sees the registry already updated.\n\t\t\t\tthis.cache.unregisterRepoPath(pathStr);\n\t\t\t}\n\t\t\t// A failed or cancelled removal may already have taken the worktree's files or admin entry\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t}\n\t}\n\n\t@debug()\n\tasync pruneWorktrees(repoPath: string, options?: { expire?: string }): Promise<void> {\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Pruning worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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 before = await this.listWorktreePaths(repoPath);\n\n\t\tconst args = ['worktree', 'prune'];\n\t\tif (options?.expire) {\n\t\t\targs.push('--expire', options.expire);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw' }, ...args);\n\n\t\t\tconst after = await this.listWorktreePaths(repoPath);\n\n\t\t\t// Order matters (see `deleteWorktree`): unregister before emitting the repo-level change so any\n\t\t\t// listener that re-queries worktree-aware state sees the registry already updated.\n\t\t\tif (before != null && after != null) {\n\t\t\t\tfor (const path of before) {\n\t\t\t\t\tif (!after.has(path)) {\n\t\t\t\t\t\tthis.cache.unregisterRepoPath(path);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t}\n\t}\n\n\t/**\n\t * Raw worktree paths currently known to git (`worktree <path>` lines from `--porcelain`), normalized the\n\t * same way {@link deleteWorktree} does. A failed listing (`errors: 'ignore'`) yields an empty set rather\n\t * than throwing — used by `pruneWorktrees` to diff before/after, where a transient read failure must not\n\t * be mistaken for every worktree having vanished.\n\t */\n\tprivate async listWorktreePaths(repoPath: string): Promise<Set<string> | undefined> {\n\t\tconst result = await this.git.run({ cwd: repoPath, errors: 'ignore' }, 'worktree', 'list', '--porcelain');\n\t\t// A failed listing is not an empty one: read as empty, the after-prune one would unregister everything\n\t\tif (result.completion.status !== 'exited' || result.exitCode !== 0) return undefined;\n\n\t\tconst paths = new Set<string>();\n\t\tfor (const line of result.stdout.split('\\n')) {\n\t\t\tif (line.startsWith('worktree ')) {\n\t\t\t\tpaths.add(normalizePath(toFsPath(line.slice('worktree '.length).trim())));\n\t\t\t}\n\t\t}\n\t\treturn paths;\n\t}\n\n\t@debug()\n\tasync lockWorktree(repoPath: string, path: string | Uri, options?: { reason?: string }): Promise<void> {\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Locking worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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 args = ['worktree', 'lock'];\n\t\tif (options?.reason) {\n\t\t\targs.push('--reason', options.reason);\n\t\t}\n\t\targs.push(normalizePath(toFsPath(path)));\n\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw' }, ...args);\n\t\t} finally {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t}\n\t}\n\n\t@debug()\n\tasync unlockWorktree(repoPath: string, path: string | Uri): Promise<void> {\n\t\tawait this.git.ensureSupports('git:worktrees', (requiredVersion, installedVersion) =>\n\t\t\tl10n.t(\n\t\t\t\t'Unlocking worktrees requires a newer version of Git (>= {0}) than is currently installed ({1}). Please 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 pathStr = normalizePath(toFsPath(path));\n\t\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, errors: 'throw' }, 'worktree', 'unlock', pathStr);\n\t\t} finally {\n\t\t\tthis.context.hooks?.cache?.onReset?.(repoPath, 'worktrees');\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, ['worktrees']);\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA0BA,SAAS,cAAc,IAAkC;CACxD,OAAO,UAAU,qBAAqB,KAAK,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,KAAK,KAAA;AACvG;;;;;AAMA,SAAS,qBAAqB,QAAgD;CAC7E,OAAO,SAAS,8CAA8C,KAAK,MAAM,CAAC,GAAG,KAAK,KAAA;AACnF;AAEA,IAAa,0BAAb,MAAwE;CAErD;CACA;CACA;CACA;CAJlB,YACC,SACA,KACA,OACA,UACC;EAJgB,KAAA,UAAA;EACA,KAAA,MAAA;EACA,KAAA,QAAA;EACA,KAAA,WAAA;CACf;;;;;CAMH,MACM,eACL,UACA,MACA,SAOA,YACgB;EAChB,MAAM,QAAQ,gBAAgB;EAE9B,MAAM,OAAO,CAAC,YAAY,KAAK;EAC/B,IAAI,SAAS,OACZ,KAAK,KAAK,SAAS;EAEpB,IAAI,SAAS,cACZ,KAAK,KAAK,MAAM,QAAQ,YAAY;EAErC,IAAI,SAAS,gBAAgB,QAAQ,YACpC,KAAK,KAAK,YAAY;EAEvB,IAAI,SAAS,QACZ,KAAK,KAAK,UAAU;EAErB,KAAK,KAAK,IAAI;EACd,IAAI,SAAS,WACZ,KAAK,KAAK,QAAQ,SAAS;EAK5B,IAAI,gBAAgB,SAAS;EAE7B,IAAI,uBAAuB;EAC3B,IAAI;GACH,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAU,GAAG;GAAW,GAAG,GAAG,IAAI;GAC3E,kBAAkB,qBAAqB,OAAO,MAAM;EACrD,SAAS,IAAI;GACZ,OAAO,MAAM,EAAE;GAEf,kBAAkB,qBAAsB,IAA6B,MAAM;GAG3E,IAAI,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,GAAG;IACpD,uBAAuB,iBAAiB,QAAQ,CAAC,SAAS;IAC1D,MAAM;GACP;GAEA,MAAM,mBACL,mBACA,KACA,WACC,IAAI,oBACH;IAAU;IAAQ,YAAY;KAAY;KAAgB;IAAK;GAAE,GACjE,EACD,CACF;EACD,UAAU;GAQT,IAAI,eAAe;IAElB,KAAK,MAAM,qBAAqB,UAAU,aAAa;IAEvD,KAAK,QAAQ,OAAO,OAAO,UAC1B,UACA,GAAI,CAAC,SAAS,gBAAgB,iBAAiB,QAAQ,WAAW,QAAQ,UAAU,IAChF;KAAC;KAAY;KAAU;IAAW,IAClC,CAAC,YAAY,WAAW,CAC7B;IACA,KAAK,QAAQ,OAAO,YAAY,YAC/B,UACA,CAAC,aAAa,OAAO,GACrB,CAAC,cAAc,eAAe,CAC/B;GACD,OAAO,IAAI,sBAAsB;IAEhC,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,YAAY,UAAU,WAAW;IAChF,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,aAAa,OAAO,CAAC;GAC7E,OAAO;IACN,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,WAAW;IAC1D,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,WAAW,CAAC;GACpE;EACD;CACD;CAEA,MAAM,yBACL,UACA,MACA,SAOA,YACmC;EACnC,MAAM,KAAK,eAAe,UAAU,MAAM,SAAS,UAAU;EAC7D,MAAM,aAAa,cAAc,IAAI;EACrC,OAAO,KAAK,YAAY,WAAU,MAAK,cAAc,EAAE,IAAI,MAAM,YAAY,YAAY,YAAY;CACtG;CAEA,MACM,YACL,UACA,WACA,cACmC;EACnC,QAAQ,MAAM,KAAK,aAAa,UAAU,YAAY,EAAA,CAAG,KAAK,SAAS;CACxE;CAEA,MACM,aAAa,UAAkB,cAAoD;EACxF,MAAM,KAAK,IAAI,eAAe,kBAAkB,iBAAiB,qBAChE,KAAK,EACJ,+JACA,iBACA,gBACD,CACD;EAEA,OAAO,KAAK,MAAM,aACjB,UACA,OAAO,YAAY,WAAW,WAAW;GAExC,WAAW;GACX,MAAM,CAAC,YAAY,kBAAkB,MAAM,QAAQ,WAAW,CAC7D,KAAK,IAAI,IAAI;IAAE,KAAK;IAAY,cAAc;GAAO,GAAG,YAAY,QAAQ,aAAa,GACzF,KAAK,SAAS,SAAS,YAAY,YAAY,KAAA,GAAW,MAAM,CACjE,CAAC;GAED,IAAI,WAAW,WAAW,YAEzB,UAAU,WAAW;GAGtB,MAAM,qBAA0D,KAAK,QAAQ,aAC1E,QAAO;IACP,MAAM,SAAS,KAAK,QAAQ,UAAW,UAAU,IAAI,MAAM;IAC3D,IAAI,UAAU,MAAM,OAAO,KAAA;IAC3B,OAAO;KAAE,KAAK,QAAQ,OAAO,IAAI;KAAG,MAAMA,WAAS,OAAO,IAAI;IAAE;GACjE,IACC,KAAA;GAEH,MAAM,YAAY,kBACjB,gBAAgB,UAAU,CAAC,EAAE,QAC7B,YACA,gBAAgB,cAAc,CAAC,EAAE,UAAU,CAAC,GAC5C,kBACD;GAGA,IAAI,MAAM,KAAK,IAAI,SAAS,+BAA+B,GAAG,OAAO;GAErE,OAAO,QAAQ,IAAI,UAAU,KAAI,MAAK,KAAK,eAAe,CAAC,CAAC,CAAC;EAC9D,GACA,YACD;CACD;CAEA,MAAc,eAAe,UAA6C;EACzE,IAAI,SAAS,WAAW,QAAQ,SAAS,aAAa,SAAS,SAAS,QAAQ,OAAO;EAEvF,IAAI;GAEH,MAAM,SAAS,KAAK,SAAS,IAAI,QAAQ,MAAM;GAC/C,MAAM,QAAQ,wBAAwB,KAAK,MAAMC,SAAG,SAAS,QAAQ,MAAM,CAAC;GAC5E,IAAI,SAAS,MAAM,OAAO;GAE1B,MAAM,UAAU,MAAMA,SAAG,SAAS,KAAK,QAAQ,SAAS,IAAI,QAAQ,MAAM,EAAE,GAAG,QAAQ,GAAG,MAAM,EAAA,CAAG,KAAK;GACxG,IAAI,CAAC,QAAQ,OAAO;GAEpB,OAAO,IAAI,YACV,SAAS,WACT,SAAS,MACT,SAAS,UACT,SAAS,KACT,QACA,SAAS,UACT,SAAS,KACT,SAAS,QACT,SAAS,eACV;EACD,QAAQ;GACP,OAAO;EACR;CACD;CAEA,uBACuB,UAAmC;EACzD,OAAO,KAAK,QAAQ,WAAW,wBAAwB,QAAQ;CAChE;;;;;;;;;;;;CAaA,MACM,eACL,UACA,MACA,SACA,YACgB;EAChB,MAAM,QAAQ,gBAAgB;EAE9B,MAAM,KAAK,IAAI,eAAe,kBAAkB,iBAAiB,qBAChE,KAAK,EACJ,6JACA,iBACA,gBACD,CACD;EAEA,MAAM,OAAO,CAAC,YAAY,QAAQ;EAClC,IAAI,SAAS,OAAO;GACnB,KAAK,KAAK,SAAS;GAEnB,IAAI,QAAQ,UAAU,UACrB,KAAK,KAAK,SAAS;EAErB;EAEA,MAAM,UAAU,cAAc,SAAS,IAAI,CAAC;EAC5C,KAAK,KAAK,OAAO;EAEjB,IAAI,UAAU;EACd,IAAI;GACH,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAU,QAAQ;IAAS,GAAG;GAAW,GAAG,GAAG,IAAI;GAC7E,UAAU;EACX,SAAS,IAAI;GACZ,OAAO,MAAM,EAAE;GAIf,IAAI,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,GAAG,MAAM;GAE3D,MAAM,WAAW,mBAChB,mBACA,KACA,WACC,IAAI,oBACH;IACS;IACR,YAAY,WAAW,WAAW,cAAc,EAAc,IAAI,KAAA;IAClE,YAAY;KAAY;KAAgB;IAAK;GAC9C,GACA,EACD,CACF;GAEA,IAAI,SAAS,QAAQ,WAAW,qBAAqB;IACpD,OAAO,KACN,oCAAoC,QAAQ,6DAC7C;IACA,IAAI;KACH,MAAMA,SAAG,GAAG,SAAS;MAAE,OAAO;MAAM,WAAW;KAAK,CAAC;KACrD,UAAU;KACV;IACD,SAAS,IAAI;KACZ,IAAI,WAAW;MACd,MAAM,QAAQ,kDAAkD,KAAM,GAAgB,OAAO;MAC7F,IAAI,SAAS,MAAM;OAClB,OAAO,KACN,8BAA8B,QAAQ,4DACvC;OAIA,SAAS,mBAAmB,SAAiB;QAC5C,OAAO,IAAI,SAAS,SAAS,WAAW;SACvC,KAAK,QAAQ,QAAQ,KAAK,IAAI,QAAQ,WAAW;UAChD,IAAI,IACH,OAAO,cAAc,QAAQ,KAAK,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;eACjD,IAAI,QACV,OAAO,IAAI,MAAM,MAAM,CAAC;eAExB,QAAQ,MAAM;SAEhB,CAAC;QACF,CAAC;OACF;OAEA,MAAM,GAAG,QAAQ;OACjB,IAAI;QACH,MAAM,mBAAmB,IAAI;QAC7B,MAAMA,SAAG,GAAG,SAAS;SAAE,OAAO;SAAM,WAAW;SAAM,YAAY;SAAG,YAAY;QAAE,CAAC;QACnF,UAAU;QACV;OACD,SAAS,IAAI;QACZ,OAAO,MAAM,IAAI,gCAAgC,QAAQ,wBAAwB;OAClF;MACD;KACD;IACD;GACD;GAEA,MAAM;EACP,UAAU;GACT,IAAI,SAIH,KAAK,MAAM,mBAAmB,OAAO;GAGtC,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,WAAW;GAC1D,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,WAAW,CAAC;EACpE;CACD;CAEA,MACM,eAAe,UAAkB,SAA8C;EACpF,MAAM,KAAK,IAAI,eAAe,kBAAkB,iBAAiB,qBAChE,KAAK,EACJ,4JACA,iBACA,gBACD,CACD;EAEA,MAAM,SAAS,MAAM,KAAK,kBAAkB,QAAQ;EAEpD,MAAM,OAAO,CAAC,YAAY,OAAO;EACjC,IAAI,SAAS,QACZ,KAAK,KAAK,YAAY,QAAQ,MAAM;EAGrC,IAAI;GACH,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAU,QAAQ;GAAQ,GAAG,GAAG,IAAI;GAE9D,MAAM,QAAQ,MAAM,KAAK,kBAAkB,QAAQ;GAInD,IAAI,UAAU,QAAQ,SAAS,MACzB;SAAA,MAAM,QAAQ,QAClB,IAAI,CAAC,MAAM,IAAI,IAAI,GAClB,KAAK,MAAM,mBAAmB,IAAI;GAAA;EAItC,UAAU;GACT,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,WAAW;GAC1D,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,WAAW,CAAC;EACpE;CACD;;;;;;;CAQA,MAAc,kBAAkB,UAAoD;EACnF,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI;GAAE,KAAK;GAAU,QAAQ;EAAS,GAAG,YAAY,QAAQ,aAAa;EAExG,IAAI,OAAO,WAAW,WAAW,YAAY,OAAO,aAAa,GAAG,OAAO,KAAA;EAE3E,MAAM,wBAAQ,IAAI,IAAY;EAC9B,KAAK,MAAM,QAAQ,OAAO,OAAO,MAAM,IAAI,GAC1C,IAAI,KAAK,WAAW,WAAW,GAC9B,MAAM,IAAI,cAAc,SAAS,KAAK,MAAM,CAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;EAG1E,OAAO;CACR;CAEA,MACM,aAAa,UAAkB,MAAoB,SAA8C;EACtG,MAAM,KAAK,IAAI,eAAe,kBAAkB,iBAAiB,qBAChE,KAAK,EACJ,4JACA,iBACA,gBACD,CACD;EAEA,MAAM,OAAO,CAAC,YAAY,MAAM;EAChC,IAAI,SAAS,QACZ,KAAK,KAAK,YAAY,QAAQ,MAAM;EAErC,KAAK,KAAK,cAAc,SAAS,IAAI,CAAC,CAAC;EAEvC,IAAI;GACH,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAU,QAAQ;GAAQ,GAAG,GAAG,IAAI;EAC/D,UAAU;GACT,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,WAAW;GAC1D,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,WAAW,CAAC;EACpE;CACD;CAEA,MACM,eAAe,UAAkB,MAAmC;EACzE,MAAM,KAAK,IAAI,eAAe,kBAAkB,iBAAiB,qBAChE,KAAK,EACJ,8JACA,iBACA,gBACD,CACD;EAEA,MAAM,UAAU,cAAc,SAAS,IAAI,CAAC;EAC5C,IAAI;GACH,MAAM,KAAK,IAAI,IAAI;IAAE,KAAK;IAAU,QAAQ;GAAQ,GAAG,YAAY,UAAU,OAAO;EACrF,UAAU;GACT,KAAK,QAAQ,OAAO,OAAO,UAAU,UAAU,WAAW;GAC1D,KAAK,QAAQ,OAAO,YAAY,YAAY,UAAU,CAAC,WAAW,CAAC;EACpE;CACD;AACD;AA3aE,WAAA,CAAA,MAAM,CAAA,GAAA,wBAAA,WAAA,kBAAA,IAAA;AAgHN,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,wBAAA,WAAA,eAAA,IAAA;AASrB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,wBAAA,WAAA,gBAAA,IAAA;AA6ErB,WAAA,CAAA,MAAM,EAAE,OAAO,KAAK,CAAC,CAAA,GAAA,wBAAA,WAAA,0BAAA,IAAA;AAgBrB,WAAA,CAAA,MAAM,CAAA,GAAA,wBAAA,WAAA,kBAAA,IAAA;AAkHN,WAAA,CAAA,MAAM,CAAA,GAAA,wBAAA,WAAA,kBAAA,IAAA;AAyDN,WAAA,CAAA,MAAM,CAAA,GAAA,wBAAA,WAAA,gBAAA,IAAA;AAwBN,WAAA,CAAA,MAAM,CAAA,GAAA,wBAAA,WAAA,kBAAA,IAAA"}
|
|
@@ -2,7 +2,7 @@ import { PagedResult, PagingOptions } from "../../../../utils/paging.js";
|
|
|
2
2
|
import { GitBranch } from "../../../../git/models/branch.js";
|
|
3
3
|
import { GitCommandPriority } from "../../../../git/run.types.js";
|
|
4
4
|
import { BranchSortOptions } from "../../../../git/utils/sorting.js";
|
|
5
|
-
import { BranchContributionsOverview, GitBranchesSubProvider } from "../../../../git/providers/branches.js";
|
|
5
|
+
import { BranchContributionsOverview, GitBranchesSubProvider, MergeTarget, MergeTargetOptions } from "../../../../git/providers/branches.js";
|
|
6
6
|
import { Cache } from "../../../../git/cache.js";
|
|
7
7
|
import { GitHubGitProviderInternal } from "../githubProvider.js";
|
|
8
8
|
//#region ../plus/git-github/src/providers/github/branches.d.ts
|
|
@@ -27,8 +27,16 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
27
27
|
};
|
|
28
28
|
};
|
|
29
29
|
} | undefined>;
|
|
30
|
+
getFallbackDefaultBranch?: () => Promise<string | undefined>;
|
|
30
31
|
priority?: GitCommandPriority;
|
|
31
32
|
}, _cancellation?: AbortSignal): Promise<BranchContributionsOverview | undefined>;
|
|
33
|
+
/**
|
|
34
|
+
* `preferredTarget`, then the pull request's base, then the repository's default branch, then the caller's
|
|
35
|
+
* fallback, each with the merge base the compare API reports. A remote repository has no stored targets, reflog or
|
|
36
|
+
* tracking refs, so the other options have nothing to act on; the default branch's own target is itself, kept only
|
|
37
|
+
* with `keepSelfAtTip`.
|
|
38
|
+
*/
|
|
39
|
+
getMergeTarget(repoPath: string, branch: string, options?: MergeTargetOptions, _cancellation?: AbortSignal): Promise<MergeTarget | undefined>;
|
|
32
40
|
getBranchesWithCommits(repoPath: string, shas: string[], branch?: string | undefined, options?: {
|
|
33
41
|
all?: boolean;
|
|
34
42
|
commitDate?: Date;
|
|
@@ -145,20 +145,65 @@ var BranchesGitSubProvider = class {
|
|
|
145
145
|
};
|
|
146
146
|
};
|
|
147
147
|
try {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (
|
|
155
|
-
const resolvedTarget =
|
|
148
|
+
const associatedPullRequest = options?.associatedPullRequest;
|
|
149
|
+
const target = await this.getMergeTarget(repoPath, ref, {
|
|
150
|
+
getAssociatedPullRequest: associatedPullRequest != null ? () => associatedPullRequest : void 0,
|
|
151
|
+
getFallbackDefaultBranch: options?.getFallbackDefaultBranch,
|
|
152
|
+
keepSelfAtTip: true
|
|
153
|
+
});
|
|
154
|
+
if (target == null) return void 0;
|
|
155
|
+
const resolvedTarget = target.ref;
|
|
156
156
|
return await this.cache.getBranchOverview(repoPath, `${ref}|${resolvedTarget}`, () => fetchBody(resolvedTarget));
|
|
157
157
|
} catch (ex) {
|
|
158
158
|
scope?.error(ex);
|
|
159
159
|
return;
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* `preferredTarget`, then the pull request's base, then the repository's default branch, then the caller's
|
|
164
|
+
* fallback, each with the merge base the compare API reports. A remote repository has no stored targets, reflog or
|
|
165
|
+
* tracking refs, so the other options have nothing to act on; the default branch's own target is itself, kept only
|
|
166
|
+
* with `keepSelfAtTip`.
|
|
167
|
+
*/
|
|
168
|
+
async getMergeTarget(repoPath, branch, options, _cancellation) {
|
|
169
|
+
if (!branch) return void 0;
|
|
170
|
+
const scope = getScopedLogger();
|
|
171
|
+
const read = async (getName) => {
|
|
172
|
+
try {
|
|
173
|
+
return (await getName?.())?.trim() || void 0;
|
|
174
|
+
} catch (ex) {
|
|
175
|
+
scope?.error(ex);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const measure = async (candidate, tier) => {
|
|
180
|
+
candidate = candidate?.trim();
|
|
181
|
+
if (!candidate || candidate.startsWith("-") || candidate === branch) return void 0;
|
|
182
|
+
return {
|
|
183
|
+
ref: candidate,
|
|
184
|
+
forkPoint: await this.provider.refs.getMergeBase(repoPath, branch, candidate),
|
|
185
|
+
tier
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
let target = await measure(options?.preferredTarget, "preferred");
|
|
189
|
+
if (target != null) return target;
|
|
190
|
+
const getAssociatedPullRequest = options?.getAssociatedPullRequest;
|
|
191
|
+
if (getAssociatedPullRequest != null) {
|
|
192
|
+
target = await measure(await read(async () => (await getAssociatedPullRequest())?.refs?.base?.branch), "pr");
|
|
193
|
+
if (target != null) return target;
|
|
194
|
+
}
|
|
195
|
+
const defaultName = stripOrigin(await read(() => this.getDefaultBranchName(repoPath)) ?? await read(options?.getFallbackDefaultBranch));
|
|
196
|
+
if (defaultName == null) return void 0;
|
|
197
|
+
if (defaultName === branch) {
|
|
198
|
+
if (!options?.keepSelfAtTip) return void 0;
|
|
199
|
+
return {
|
|
200
|
+
ref: defaultName,
|
|
201
|
+
forkPoint: await this.provider.refs.getMergeBase(repoPath, branch, defaultName),
|
|
202
|
+
tier: "default"
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return measure(defaultName, "default");
|
|
206
|
+
}
|
|
162
207
|
async getBranchesWithCommits(repoPath, shas, branch, options, _cancellation) {
|
|
163
208
|
if (repoPath == null || options?.commitDate == null) return [];
|
|
164
209
|
const scope = getScopedLogger();
|
|
@@ -194,6 +239,7 @@ var BranchesGitSubProvider = class {
|
|
|
194
239
|
__decorate([debug()], BranchesGitSubProvider.prototype, "getBranch", null);
|
|
195
240
|
__decorate([debug({ args: (repoPath) => ({ repoPath }) })], BranchesGitSubProvider.prototype, "getBranches", null);
|
|
196
241
|
__decorate([debug()], BranchesGitSubProvider.prototype, "getBranchContributionsOverview", null);
|
|
242
|
+
__decorate([debug()], BranchesGitSubProvider.prototype, "getMergeTarget", null);
|
|
197
243
|
__decorate([debug()], BranchesGitSubProvider.prototype, "getBranchesWithCommits", null);
|
|
198
244
|
__decorate([debug()], BranchesGitSubProvider.prototype, "getDefaultBranchName", null);
|
|
199
245
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branches.js","names":[],"sources":["../../../../../../plus/git-github/src/providers/github/branches.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport { GitBranch } from '@gitlens/git/models/branch.js';\nimport type { BranchContributionsOverview, GitBranchesSubProvider } from '@gitlens/git/providers/branches.js';\nimport type { GitCommandPriority } from '@gitlens/git/run.types.js';\nimport { createRevisionRange, stripOrigin } from '@gitlens/git/utils/revision.utils.js';\nimport type { BranchSortOptions } from '@gitlens/git/utils/sorting.js';\nimport { sortBranches, sortContributors } from '@gitlens/git/utils/sorting.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 { getSettledValue } from '@gitlens/utils/promise.js';\nimport type { CacheController } from '@gitlens/utils/promiseCache.js';\nimport { toTokenInfo } from '../../api/tokenUtils.js';\nimport { HeadType } from '../../context.js';\nimport type { GitHubBranch } from '../../models.js';\nimport type { GitHubGitProviderInternal } from '../githubProvider.js';\n\nexport class BranchesGitSubProvider implements GitBranchesSubProvider {\n\tconstructor(\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: GitHubGitProviderInternal,\n\t) {}\n\n\t@debug()\n\tasync getBranch(\n\t\trepoPath: string,\n\t\tname?: string,\n\t\toptions?: { force?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitBranch | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif (options?.force) {\n\t\t\tthis.cache.evictCaches(repoPath, 'branches');\n\t\t}\n\n\t\tif (name != null) {\n\t\t\tconst {\n\t\t\t\tvalues: [branch],\n\t\t\t} = await this.getBranches(repoPath, { filter: b => b.name === name }, cancellation);\n\t\t\treturn branch;\n\t\t}\n\n\t\treturn this.cache.branch.getOrCreate(\n\t\t\trepoPath,\n\t\t\tasync (_cacheable, signal): Promise<GitBranch | undefined> => {\n\t\t\t\t// Prefer the cache-provided aggregate signal (only fires when every joined\n\t\t\t\t// caller aborts); fall back to this caller's cancellation for the first-caller path.\n\t\t\t\tsignal ??= cancellation;\n\t\t\t\tconst {\n\t\t\t\t\tvalues: [branch],\n\t\t\t\t} = await this.getBranches(repoPath, { filter: b => b.current }, signal);\n\t\t\t\tif (branch != null) return branch;\n\n\t\t\t\ttry {\n\t\t\t\t\tconst { metadata } = await this.provider.ensureRepositoryContext(repoPath);\n\n\t\t\t\t\tconst revision = await metadata.getRevision();\n\t\t\t\t\tswitch (revision.type) {\n\t\t\t\t\t\tcase HeadType.Tag:\n\t\t\t\t\t\tcase HeadType.Commit:\n\t\t\t\t\t\t\treturn new GitBranch(\n\t\t\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\t\t\t`refs/heads/${revision.name}`,\n\t\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\trevision.revision,\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn undefined;\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tdebugger;\n\t\t\t\t\tscope?.error(ex);\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@debug({ args: repoPath => ({ repoPath: repoPath }) })\n\tasync getBranches(\n\t\trepoPath: string | undefined,\n\t\toptions?: {\n\t\t\tfilter?: (b: GitBranch) => boolean;\n\t\t\tordering?: 'date' | 'author-date' | 'topo' | null;\n\t\t\tpaging?: PagingOptions;\n\t\t\tsort?: boolean | BranchSortOptions;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PagedResult<GitBranch>> {\n\t\tif (repoPath == null) return emptyPagedResult;\n\n\t\tconst path = repoPath;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tconst load = async (cacheable?: CacheController): Promise<PagedResult<GitBranch>> => {\n\t\t\ttry {\n\t\t\t\tconst { metadata, github, session } = await this.provider.ensureRepositoryContext(path);\n\n\t\t\t\tconst branches: GitBranch[] = [];\n\n\t\t\t\tconst commitOrdering = options?.ordering;\n\n\t\t\t\tfunction addBranches(branch: GitHubBranch, current: boolean) {\n\t\t\t\t\tconst date = new Date(\n\t\t\t\t\t\tcommitOrdering === 'author-date' ? branch.target.authoredDate : branch.target.committedDate,\n\t\t\t\t\t);\n\t\t\t\t\tconst ref = branch.target.oid;\n\n\t\t\t\t\tbranches.push(\n\t\t\t\t\t\tnew GitBranch(\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t`refs/heads/${branch.name}`,\n\t\t\t\t\t\t\tcurrent,\n\t\t\t\t\t\t\tdate,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tref,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: `origin/${branch.name}`,\n\t\t\t\t\t\t\t\tmissing: false,\n\t\t\t\t\t\t\t\tstate: { ahead: 0, behind: 0 },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tnew GitBranch(\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t`refs/remotes/origin/${branch.name}`,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tdate,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tref,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tlet currentBranch: string | undefined;\n\n\t\t\t\tconst revision = await metadata.getRevision();\n\t\t\t\tswitch (revision.type) {\n\t\t\t\t\tcase HeadType.Branch:\n\t\t\t\t\t\tcurrentBranch = revision.name;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HeadType.RemoteBranch: {\n\t\t\t\t\t\tconst index = revision.name.indexOf(':');\n\t\t\t\t\t\tcurrentBranch = index === -1 ? revision.name : revision.name.substring(index + 1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet cursor = options?.paging?.cursor;\n\t\t\t\tconst loadAll = cursor == null;\n\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst result = await github.getBranches(\n\t\t\t\t\t\ttoTokenInfo(this.provider.authenticationProviderId, session),\n\t\t\t\t\t\tmetadata.repo.owner,\n\t\t\t\t\t\tmetadata.repo.name,\n\t\t\t\t\t\t{ cursor: cursor },\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const branch of result.values) {\n\t\t\t\t\t\taddBranches(branch, branch.name === currentBranch);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!result.paging?.more || !loadAll) return { ...result, values: branches };\n\n\t\t\t\t\tcursor = result.paging.cursor;\n\t\t\t\t}\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\tdebugger;\n\n\t\t\t\t// Mark the cache entry invalidated so the empty fallback self-evicts on settle\n\t\t\t\t// rather than getting stuck serving stale emptiness to subsequent callers.\n\t\t\t\tcacheable?.invalidate();\n\t\t\t\treturn emptyPagedResult;\n\t\t\t}\n\t\t};\n\n\t\t// Compose cache key with cursor so re-loads of the same page hit the cache;\n\t\t// `repoPath` (no suffix) is reserved for the full \"all branches\" entry.\n\t\t// TODO: `cache.branches` is `PromiseMap<RepoPath, ...>` keyed exactly by repoPath, so\n\t\t// `clearCaches('branches')` / `unregisterRepoPath` will not invalidate composite-key entries.\n\t\t// Acceptable today because branches don't change during a virtual-repo session, but the entries\n\t\t// leak in memory until provider GC. Long-term: switch to RepoPromiseCacheMap or add prefix-invalidate.\n\t\tconst cacheKey = options?.paging?.cursor != null ? `${path}#${options.paging.cursor}` : path;\n\t\tconst branchesPromise = this.cache.branches.getOrCreate(cacheKey, cacheable => load(cacheable), cancellation);\n\n\t\tlet result = await branchesPromise;\n\t\tif (options?.filter != null) {\n\t\t\tresult = {\n\t\t\t\t...result,\n\t\t\t\tvalues: result.values.filter(options.filter),\n\t\t\t};\n\t\t}\n\n\t\tif (options?.sort != null) {\n\t\t\tsortBranches(result.values, typeof options.sort === 'boolean' ? undefined : options.sort);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t@debug()\n\tasync getBranchContributionsOverview(\n\t\trepoPath: string,\n\t\tref: string,\n\t\t// `priority` is unused — the GitHub provider doesn't go through the local git command\n\t\t// queue, so the priority signal has no effect here. Accepted for interface compatibility.\n\t\toptions?: {\n\t\t\tassociatedPullRequest?: Promise<{ refs?: { base?: { branch: string } } } | undefined>;\n\t\t\tpriority?: GitCommandPriority;\n\t\t},\n\t\t_cancellation?: AbortSignal,\n\t): Promise<BranchContributionsOverview | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\t// Expensive body — runs only on cache miss. Closes over `mergeTarget` so the cache key\n\t\t// (`${ref}|${mergeTarget}`) fully captures every input that affects the result.\n\t\tconst fetchBody = async (mergeTarget: string): Promise<BranchContributionsOverview | undefined> => {\n\t\t\tconst mergeBase = await this.provider.refs.getMergeBase(repoPath, ref, mergeTarget);\n\t\t\tif (mergeBase == null) return undefined;\n\n\t\t\t// Fetch the merge-base commit's committer date in parallel with contributors so consumers\n\t\t\t// that just need the date for the scope window don't pay a separate round-trip.\n\t\t\t// `allSettled` so a transient failure in one side doesn't drop the overview entirely.\n\t\t\tconst [contributorsSettled, mergeBaseCommitSettled] = await Promise.allSettled([\n\t\t\t\tthis.provider.contributors.getContributors(repoPath, createRevisionRange(mergeBase, ref, '..'), {\n\t\t\t\t\tstats: true,\n\t\t\t\t}),\n\t\t\t\tthis.provider.commits.getCommit(repoPath, mergeBase),\n\t\t\t]);\n\n\t\t\tconst result = getSettledValue(contributorsSettled) ?? { contributors: [] };\n\t\t\tconst mergeBaseCommit = getSettledValue(mergeBaseCommitSettled);\n\n\t\t\tsortContributors(result.contributors, { orderBy: 'score:desc' });\n\n\t\t\tlet totalCommits = 0;\n\t\t\tlet totalFiles = 0;\n\t\t\tlet totalAdditions = 0;\n\t\t\tlet totalDeletions = 0;\n\t\t\tlet firstCommitTimestamp;\n\t\t\tlet latestCommitTimestamp;\n\n\t\t\tfor (const c of result.contributors) {\n\t\t\t\ttotalCommits += c.contributionCount;\n\t\t\t\ttotalFiles += c.stats?.files ?? 0;\n\t\t\t\ttotalAdditions += c.stats?.additions ?? 0;\n\t\t\t\ttotalDeletions += c.stats?.deletions ?? 0;\n\n\t\t\t\tconst firstTimestamp = c.firstCommitDate?.getTime();\n\t\t\t\tconst latestTimestamp = c.latestCommitDate?.getTime();\n\n\t\t\t\tif (firstTimestamp != null || latestTimestamp != null) {\n\t\t\t\t\tfirstCommitTimestamp =\n\t\t\t\t\t\tfirstCommitTimestamp != null\n\t\t\t\t\t\t\t? Math.min(firstCommitTimestamp, firstTimestamp ?? Infinity, latestTimestamp ?? Infinity)\n\t\t\t\t\t\t\t: (firstTimestamp ?? latestTimestamp);\n\n\t\t\t\t\tlatestCommitTimestamp =\n\t\t\t\t\t\tlatestCommitTimestamp != null\n\t\t\t\t\t\t\t? Math.max(latestCommitTimestamp, firstTimestamp ?? -Infinity, latestTimestamp ?? -Infinity)\n\t\t\t\t\t\t\t: (latestTimestamp ?? firstTimestamp);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tbranch: ref,\n\t\t\t\tmergeTarget: mergeTarget,\n\t\t\t\tmergeBase: mergeBase,\n\t\t\t\tmergeBaseDate: mergeBaseCommit?.committer?.date ?? mergeBaseCommit?.author?.date,\n\n\t\t\t\tcommits: totalCommits,\n\t\t\t\tfiles: totalFiles,\n\t\t\t\tadditions: totalAdditions,\n\t\t\t\tdeletions: totalDeletions,\n\n\t\t\t\tlatestCommitDate: latestCommitTimestamp != null ? new Date(latestCommitTimestamp) : undefined,\n\t\t\t\tfirstCommitDate: firstCommitTimestamp != null ? new Date(firstCommitTimestamp) : undefined,\n\n\t\t\t\tcontributors: result.contributors,\n\t\t\t};\n\t\t};\n\n\t\ttry {\n\t\t\t// Resolve `mergeTarget` (PR base or default branch). Only the expensive body below is\n\t\t\t// cached — keyed on `${ref}|${mergeTarget}` so callers that resolve to the same target\n\t\t\t// share the result, while differing targets get independent slots.\n\t\t\tlet mergeTarget: string | undefined;\n\n\t\t\tif (options?.associatedPullRequest != null) {\n\t\t\t\tconst pr = await options.associatedPullRequest;\n\t\t\t\tif (pr?.refs?.base != null) {\n\t\t\t\t\tmergeTarget = pr.refs.base.branch;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmergeTarget ??= await this.getDefaultBranchName(repoPath);\n\t\t\tif (mergeTarget == null) return undefined;\n\n\t\t\t// Safe to cache despite PR retargeting: the cache key includes the resolved `mergeTarget`,\n\t\t\t// so a retargeted PR resolves to a fresh slot and the old entry is stale-but-unused (and\n\t\t\t// TTL-evicts). The prior \"no outer cache here\" rationale assumed a `ref`-only key.\n\t\t\tconst resolvedTarget = mergeTarget;\n\t\t\treturn await this.cache.getBranchOverview(repoPath, `${ref}|${resolvedTarget}`, () =>\n\t\t\t\tfetchBody(resolvedTarget),\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getBranchesWithCommits(\n\t\trepoPath: string,\n\t\tshas: string[],\n\t\tbranch?: string | undefined,\n\t\toptions?:\n\t\t\t| { all?: boolean; commitDate?: Date; mode?: 'contains' | 'pointsAt' }\n\t\t\t| { commitDate?: Date; mode?: 'contains' | 'pointsAt'; remotes?: boolean },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<string[]> {\n\t\tif (repoPath == null || options?.commitDate == null) return [];\n\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);\n\n\t\t\tlet branches;\n\n\t\t\tif (branch) {\n\t\t\t\tbranches = await github.getBranchWithCommit(\n\t\t\t\t\ttoTokenInfo(this.provider.authenticationProviderId, session),\n\t\t\t\t\tmetadata.repo.owner,\n\t\t\t\t\tmetadata.repo.name,\n\t\t\t\t\tbranch,\n\t\t\t\t\tshas.map(stripOrigin),\n\t\t\t\t\toptions?.mode ?? 'contains',\n\t\t\t\t\toptions?.commitDate,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tbranches = await github.getBranchesWithCommits(\n\t\t\t\t\ttoTokenInfo(this.provider.authenticationProviderId, session),\n\t\t\t\t\tmetadata.repo.owner,\n\t\t\t\t\tmetadata.repo.name,\n\t\t\t\t\tshas.map(stripOrigin),\n\t\t\t\t\toptions?.mode ?? 'contains',\n\t\t\t\t\toptions?.commitDate,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn branches;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tdebugger;\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDefaultBranchName(\n\t\trepoPath: string | undefined,\n\t\tremote?: string,\n\t\t// `priority` is unused — the GitHub provider doesn't go through the local git command queue, so the\n\t\t// priority signal has no effect here. `local` asks for a network-free resolution (the graph's hot\n\t\t// path): a remote repo has no local symref to read, so honor that contract by returning undefined\n\t\t// rather than making the API round-trip the caller explicitly asked to avoid.\n\t\toptions?: { priority?: GitCommandPriority; local?: boolean },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tif (repoPath == null) return undefined;\n\t\tif (options?.local) return undefined;\n\n\t\tremote ??= 'origin';\n\n\t\tconst scope = getScopedLogger();\n\n\t\t// Throw inside the factory so RepoPromiseCacheMap's default `expireOnError` evicts the\n\t\t// entry — a transient API failure shouldn't poison the cache for the rest of the session.\n\t\t// The outer try/catch preserves the existing `undefined`-on-error contract for callers.\n\t\ttry {\n\t\t\treturn await this.cache.getDefaultBranchName(repoPath, remote, async () => {\n\t\t\t\tconst { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);\n\t\t\t\treturn github.getDefaultBranchName(\n\t\t\t\t\ttoTokenInfo(this.provider.authenticationProviderId, session),\n\t\t\t\t\tmetadata.repo.owner,\n\t\t\t\t\tmetadata.repo.name,\n\t\t\t\t);\n\t\t\t});\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tdebugger;\n\t\t\treturn undefined;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"branches.js","names":[],"sources":["../../../../../../plus/git-github/src/providers/github/branches.ts"],"sourcesContent":["import type { Cache } from '@gitlens/git/cache.js';\nimport { GitBranch } from '@gitlens/git/models/branch.js';\nimport type {\n\tBranchContributionsOverview,\n\tGitBranchesSubProvider,\n\tMergeTarget,\n\tMergeTargetOptions,\n\tMergeTargetTier,\n} from '@gitlens/git/providers/branches.js';\nimport type { GitCommandPriority } from '@gitlens/git/run.types.js';\nimport { createRevisionRange, stripOrigin } from '@gitlens/git/utils/revision.utils.js';\nimport type { BranchSortOptions } from '@gitlens/git/utils/sorting.js';\nimport { sortBranches, sortContributors } from '@gitlens/git/utils/sorting.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 { getSettledValue } from '@gitlens/utils/promise.js';\nimport type { CacheController } from '@gitlens/utils/promiseCache.js';\nimport { toTokenInfo } from '../../api/tokenUtils.js';\nimport { HeadType } from '../../context.js';\nimport type { GitHubBranch } from '../../models.js';\nimport type { GitHubGitProviderInternal } from '../githubProvider.js';\n\nexport class BranchesGitSubProvider implements GitBranchesSubProvider {\n\tconstructor(\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: GitHubGitProviderInternal,\n\t) {}\n\n\t@debug()\n\tasync getBranch(\n\t\trepoPath: string,\n\t\tname?: string,\n\t\toptions?: { force?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<GitBranch | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif (options?.force) {\n\t\t\tthis.cache.evictCaches(repoPath, 'branches');\n\t\t}\n\n\t\tif (name != null) {\n\t\t\tconst {\n\t\t\t\tvalues: [branch],\n\t\t\t} = await this.getBranches(repoPath, { filter: b => b.name === name }, cancellation);\n\t\t\treturn branch;\n\t\t}\n\n\t\treturn this.cache.branch.getOrCreate(\n\t\t\trepoPath,\n\t\t\tasync (_cacheable, signal): Promise<GitBranch | undefined> => {\n\t\t\t\t// Prefer the cache-provided aggregate signal (only fires when every joined\n\t\t\t\t// caller aborts); fall back to this caller's cancellation for the first-caller path.\n\t\t\t\tsignal ??= cancellation;\n\t\t\t\tconst {\n\t\t\t\t\tvalues: [branch],\n\t\t\t\t} = await this.getBranches(repoPath, { filter: b => b.current }, signal);\n\t\t\t\tif (branch != null) return branch;\n\n\t\t\t\ttry {\n\t\t\t\t\tconst { metadata } = await this.provider.ensureRepositoryContext(repoPath);\n\n\t\t\t\t\tconst revision = await metadata.getRevision();\n\t\t\t\t\tswitch (revision.type) {\n\t\t\t\t\t\tcase HeadType.Tag:\n\t\t\t\t\t\tcase HeadType.Commit:\n\t\t\t\t\t\t\treturn new GitBranch(\n\t\t\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\t\t\t`refs/heads/${revision.name}`,\n\t\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\trevision.revision,\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn undefined;\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tdebugger;\n\t\t\t\t\tscope?.error(ex);\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@debug({ args: repoPath => ({ repoPath: repoPath }) })\n\tasync getBranches(\n\t\trepoPath: string | undefined,\n\t\toptions?: {\n\t\t\tfilter?: (b: GitBranch) => boolean;\n\t\t\tordering?: 'date' | 'author-date' | 'topo' | null;\n\t\t\tpaging?: PagingOptions;\n\t\t\tsort?: boolean | BranchSortOptions;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PagedResult<GitBranch>> {\n\t\tif (repoPath == null) return emptyPagedResult;\n\n\t\tconst path = repoPath;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tconst load = async (cacheable?: CacheController): Promise<PagedResult<GitBranch>> => {\n\t\t\ttry {\n\t\t\t\tconst { metadata, github, session } = await this.provider.ensureRepositoryContext(path);\n\n\t\t\t\tconst branches: GitBranch[] = [];\n\n\t\t\t\tconst commitOrdering = options?.ordering;\n\n\t\t\t\tfunction addBranches(branch: GitHubBranch, current: boolean) {\n\t\t\t\t\tconst date = new Date(\n\t\t\t\t\t\tcommitOrdering === 'author-date' ? branch.target.authoredDate : branch.target.committedDate,\n\t\t\t\t\t);\n\t\t\t\t\tconst ref = branch.target.oid;\n\n\t\t\t\t\tbranches.push(\n\t\t\t\t\t\tnew GitBranch(\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t`refs/heads/${branch.name}`,\n\t\t\t\t\t\t\tcurrent,\n\t\t\t\t\t\t\tdate,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tref,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: `origin/${branch.name}`,\n\t\t\t\t\t\t\t\tmissing: false,\n\t\t\t\t\t\t\t\tstate: { ahead: 0, behind: 0 },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tnew GitBranch(\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t`refs/remotes/origin/${branch.name}`,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tdate,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tref,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tlet currentBranch: string | undefined;\n\n\t\t\t\tconst revision = await metadata.getRevision();\n\t\t\t\tswitch (revision.type) {\n\t\t\t\t\tcase HeadType.Branch:\n\t\t\t\t\t\tcurrentBranch = revision.name;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HeadType.RemoteBranch: {\n\t\t\t\t\t\tconst index = revision.name.indexOf(':');\n\t\t\t\t\t\tcurrentBranch = index === -1 ? revision.name : revision.name.substring(index + 1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet cursor = options?.paging?.cursor;\n\t\t\t\tconst loadAll = cursor == null;\n\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst result = await github.getBranches(\n\t\t\t\t\t\ttoTokenInfo(this.provider.authenticationProviderId, session),\n\t\t\t\t\t\tmetadata.repo.owner,\n\t\t\t\t\t\tmetadata.repo.name,\n\t\t\t\t\t\t{ cursor: cursor },\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const branch of result.values) {\n\t\t\t\t\t\taddBranches(branch, branch.name === currentBranch);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!result.paging?.more || !loadAll) return { ...result, values: branches };\n\n\t\t\t\t\tcursor = result.paging.cursor;\n\t\t\t\t}\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\tdebugger;\n\n\t\t\t\t// Mark the cache entry invalidated so the empty fallback self-evicts on settle\n\t\t\t\t// rather than getting stuck serving stale emptiness to subsequent callers.\n\t\t\t\tcacheable?.invalidate();\n\t\t\t\treturn emptyPagedResult;\n\t\t\t}\n\t\t};\n\n\t\t// Compose cache key with cursor so re-loads of the same page hit the cache;\n\t\t// `repoPath` (no suffix) is reserved for the full \"all branches\" entry.\n\t\t// TODO: `cache.branches` is `PromiseMap<RepoPath, ...>` keyed exactly by repoPath, so\n\t\t// `clearCaches('branches')` / `unregisterRepoPath` will not invalidate composite-key entries.\n\t\t// Acceptable today because branches don't change during a virtual-repo session, but the entries\n\t\t// leak in memory until provider GC. Long-term: switch to RepoPromiseCacheMap or add prefix-invalidate.\n\t\tconst cacheKey = options?.paging?.cursor != null ? `${path}#${options.paging.cursor}` : path;\n\t\tconst branchesPromise = this.cache.branches.getOrCreate(cacheKey, cacheable => load(cacheable), cancellation);\n\n\t\tlet result = await branchesPromise;\n\t\tif (options?.filter != null) {\n\t\t\tresult = {\n\t\t\t\t...result,\n\t\t\t\tvalues: result.values.filter(options.filter),\n\t\t\t};\n\t\t}\n\n\t\tif (options?.sort != null) {\n\t\t\tsortBranches(result.values, typeof options.sort === 'boolean' ? undefined : options.sort);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t@debug()\n\tasync getBranchContributionsOverview(\n\t\trepoPath: string,\n\t\tref: string,\n\t\t// `priority` is unused — the GitHub provider doesn't go through the local git command\n\t\t// queue, so the priority signal has no effect here. Accepted for interface compatibility.\n\t\toptions?: {\n\t\t\tassociatedPullRequest?: Promise<{ refs?: { base?: { branch: string } } } | undefined>;\n\t\t\tgetFallbackDefaultBranch?: () => Promise<string | undefined>;\n\t\t\tpriority?: GitCommandPriority;\n\t\t},\n\t\t_cancellation?: AbortSignal,\n\t): Promise<BranchContributionsOverview | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\t// Expensive body — runs only on cache miss. Closes over `mergeTarget` so the cache key\n\t\t// (`${ref}|${mergeTarget}`) fully captures every input that affects the result.\n\t\tconst fetchBody = async (mergeTarget: string): Promise<BranchContributionsOverview | undefined> => {\n\t\t\tconst mergeBase = await this.provider.refs.getMergeBase(repoPath, ref, mergeTarget);\n\t\t\tif (mergeBase == null) return undefined;\n\n\t\t\t// Fetch the merge-base commit's committer date in parallel with contributors so consumers\n\t\t\t// that just need the date for the scope window don't pay a separate round-trip.\n\t\t\t// `allSettled` so a transient failure in one side doesn't drop the overview entirely.\n\t\t\tconst [contributorsSettled, mergeBaseCommitSettled] = await Promise.allSettled([\n\t\t\t\tthis.provider.contributors.getContributors(repoPath, createRevisionRange(mergeBase, ref, '..'), {\n\t\t\t\t\tstats: true,\n\t\t\t\t}),\n\t\t\t\tthis.provider.commits.getCommit(repoPath, mergeBase),\n\t\t\t]);\n\n\t\t\tconst result = getSettledValue(contributorsSettled) ?? { contributors: [] };\n\t\t\tconst mergeBaseCommit = getSettledValue(mergeBaseCommitSettled);\n\n\t\t\tsortContributors(result.contributors, { orderBy: 'score:desc' });\n\n\t\t\tlet totalCommits = 0;\n\t\t\tlet totalFiles = 0;\n\t\t\tlet totalAdditions = 0;\n\t\t\tlet totalDeletions = 0;\n\t\t\tlet firstCommitTimestamp;\n\t\t\tlet latestCommitTimestamp;\n\n\t\t\tfor (const c of result.contributors) {\n\t\t\t\ttotalCommits += c.contributionCount;\n\t\t\t\ttotalFiles += c.stats?.files ?? 0;\n\t\t\t\ttotalAdditions += c.stats?.additions ?? 0;\n\t\t\t\ttotalDeletions += c.stats?.deletions ?? 0;\n\n\t\t\t\tconst firstTimestamp = c.firstCommitDate?.getTime();\n\t\t\t\tconst latestTimestamp = c.latestCommitDate?.getTime();\n\n\t\t\t\tif (firstTimestamp != null || latestTimestamp != null) {\n\t\t\t\t\tfirstCommitTimestamp =\n\t\t\t\t\t\tfirstCommitTimestamp != null\n\t\t\t\t\t\t\t? Math.min(firstCommitTimestamp, firstTimestamp ?? Infinity, latestTimestamp ?? Infinity)\n\t\t\t\t\t\t\t: (firstTimestamp ?? latestTimestamp);\n\n\t\t\t\t\tlatestCommitTimestamp =\n\t\t\t\t\t\tlatestCommitTimestamp != null\n\t\t\t\t\t\t\t? Math.max(latestCommitTimestamp, firstTimestamp ?? -Infinity, latestTimestamp ?? -Infinity)\n\t\t\t\t\t\t\t: (latestTimestamp ?? firstTimestamp);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tbranch: ref,\n\t\t\t\tmergeTarget: mergeTarget,\n\t\t\t\tmergeBase: mergeBase,\n\t\t\t\tmergeBaseDate: mergeBaseCommit?.committer?.date ?? mergeBaseCommit?.author?.date,\n\n\t\t\t\tcommits: totalCommits,\n\t\t\t\tfiles: totalFiles,\n\t\t\t\tadditions: totalAdditions,\n\t\t\t\tdeletions: totalDeletions,\n\n\t\t\t\tlatestCommitDate: latestCommitTimestamp != null ? new Date(latestCommitTimestamp) : undefined,\n\t\t\t\tfirstCommitDate: firstCommitTimestamp != null ? new Date(firstCommitTimestamp) : undefined,\n\n\t\t\t\tcontributors: result.contributors,\n\t\t\t};\n\t\t};\n\n\t\ttry {\n\t\t\t// Only the expensive body below is cached — keyed on `${ref}|${mergeTarget}` so callers that resolve to\n\t\t\t// the same target share the result, while differing targets get independent slots.\n\t\t\tconst associatedPullRequest = options?.associatedPullRequest;\n\t\t\tconst target = await this.getMergeTarget(repoPath, ref, {\n\t\t\t\tgetAssociatedPullRequest: associatedPullRequest != null ? () => associatedPullRequest : undefined,\n\t\t\t\tgetFallbackDefaultBranch: options?.getFallbackDefaultBranch,\n\t\t\t\tkeepSelfAtTip: true,\n\t\t\t});\n\t\t\tif (target == null) return undefined;\n\n\t\t\t// Safe to cache despite PR retargeting: the cache key includes the resolved `mergeTarget`,\n\t\t\t// so a retargeted PR resolves to a fresh slot and the old entry is stale-but-unused (and\n\t\t\t// TTL-evicts). The prior \"no outer cache here\" rationale assumed a `ref`-only key.\n\t\t\tconst resolvedTarget = target.ref;\n\t\t\treturn await this.cache.getBranchOverview(repoPath, `${ref}|${resolvedTarget}`, () =>\n\t\t\t\tfetchBody(resolvedTarget),\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * `preferredTarget`, then the pull request's base, then the repository's default branch, then the caller's\n\t * fallback, each with the merge base the compare API reports. A remote repository has no stored targets, reflog or\n\t * tracking refs, so the other options have nothing to act on; the default branch's own target is itself, kept only\n\t * with `keepSelfAtTip`.\n\t */\n\t@debug()\n\tasync getMergeTarget(\n\t\trepoPath: string,\n\t\tbranch: string,\n\t\toptions?: MergeTargetOptions,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<MergeTarget | undefined> {\n\t\tif (!branch) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tconst read = async (getName: (() => Promise<string | undefined>) | undefined): Promise<string | undefined> => {\n\t\t\ttry {\n\t\t\t\treturn (await getName?.())?.trim() || undefined;\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t};\n\t\tconst measure = async (\n\t\t\tcandidate: string | undefined,\n\t\t\ttier: MergeTargetTier,\n\t\t): Promise<MergeTarget | undefined> => {\n\t\t\tcandidate = candidate?.trim();\n\t\t\t// A ref starting with `-` would be parsed as a flag, and a branch measured against itself says nothing\n\t\t\tif (!candidate || candidate.startsWith('-') || candidate === branch) return undefined;\n\n\t\t\t// The candidate as-is, with the merge base the compare API reports: a remote repository has no tracking refs\n\t\t\t// to weigh it against\n\t\t\treturn {\n\t\t\t\tref: candidate,\n\t\t\t\tforkPoint: await this.provider.refs.getMergeBase(repoPath, branch, candidate),\n\t\t\t\ttier: tier,\n\t\t\t};\n\t\t};\n\n\t\tlet target = await measure(options?.preferredTarget, 'preferred');\n\t\tif (target != null) return target;\n\n\t\tconst getAssociatedPullRequest = options?.getAssociatedPullRequest;\n\t\tif (getAssociatedPullRequest != null) {\n\t\t\ttarget = await measure(\n\t\t\t\tawait read(async () => (await getAssociatedPullRequest())?.refs?.base?.branch),\n\t\t\t\t'pr',\n\t\t\t);\n\t\t\tif (target != null) return target;\n\t\t}\n\n\t\t// The fallback can name it remote-qualified (`origin/main`), where this repository's branches are bare\n\t\tconst defaultName = stripOrigin(\n\t\t\t(await read(() => this.getDefaultBranchName(repoPath))) ?? (await read(options?.getFallbackDefaultBranch)),\n\t\t);\n\t\tif (defaultName == null) return undefined;\n\n\t\tif (defaultName === branch) {\n\t\t\tif (!options?.keepSelfAtTip) return undefined;\n\n\t\t\treturn {\n\t\t\t\tref: defaultName,\n\t\t\t\tforkPoint: await this.provider.refs.getMergeBase(repoPath, branch, defaultName),\n\t\t\t\ttier: 'default',\n\t\t\t};\n\t\t}\n\t\treturn measure(defaultName, 'default');\n\t}\n\n\t@debug()\n\tasync getBranchesWithCommits(\n\t\trepoPath: string,\n\t\tshas: string[],\n\t\tbranch?: string | undefined,\n\t\toptions?:\n\t\t\t| { all?: boolean; commitDate?: Date; mode?: 'contains' | 'pointsAt' }\n\t\t\t| { commitDate?: Date; mode?: 'contains' | 'pointsAt'; remotes?: boolean },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<string[]> {\n\t\tif (repoPath == null || options?.commitDate == null) return [];\n\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);\n\n\t\t\tlet branches;\n\n\t\t\tif (branch) {\n\t\t\t\tbranches = await github.getBranchWithCommit(\n\t\t\t\t\ttoTokenInfo(this.provider.authenticationProviderId, session),\n\t\t\t\t\tmetadata.repo.owner,\n\t\t\t\t\tmetadata.repo.name,\n\t\t\t\t\tbranch,\n\t\t\t\t\tshas.map(stripOrigin),\n\t\t\t\t\toptions?.mode ?? 'contains',\n\t\t\t\t\toptions?.commitDate,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tbranches = await github.getBranchesWithCommits(\n\t\t\t\t\ttoTokenInfo(this.provider.authenticationProviderId, session),\n\t\t\t\t\tmetadata.repo.owner,\n\t\t\t\t\tmetadata.repo.name,\n\t\t\t\t\tshas.map(stripOrigin),\n\t\t\t\t\toptions?.mode ?? 'contains',\n\t\t\t\t\toptions?.commitDate,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn branches;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tdebugger;\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDefaultBranchName(\n\t\trepoPath: string | undefined,\n\t\tremote?: string,\n\t\t// `priority` is unused — the GitHub provider doesn't go through the local git command queue, so the\n\t\t// priority signal has no effect here. `local` asks for a network-free resolution (the graph's hot\n\t\t// path): a remote repo has no local symref to read, so honor that contract by returning undefined\n\t\t// rather than making the API round-trip the caller explicitly asked to avoid.\n\t\toptions?: { priority?: GitCommandPriority; local?: boolean },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<string | undefined> {\n\t\tif (repoPath == null) return undefined;\n\t\tif (options?.local) return undefined;\n\n\t\tremote ??= 'origin';\n\n\t\tconst scope = getScopedLogger();\n\n\t\t// Throw inside the factory so RepoPromiseCacheMap's default `expireOnError` evicts the\n\t\t// entry — a transient API failure shouldn't poison the cache for the rest of the session.\n\t\t// The outer try/catch preserves the existing `undefined`-on-error contract for callers.\n\t\ttry {\n\t\t\treturn await this.cache.getDefaultBranchName(repoPath, remote, async () => {\n\t\t\t\tconst { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);\n\t\t\t\treturn github.getDefaultBranchName(\n\t\t\t\t\ttoTokenInfo(this.provider.authenticationProviderId, session),\n\t\t\t\t\tmetadata.repo.owner,\n\t\t\t\t\tmetadata.repo.name,\n\t\t\t\t);\n\t\t\t});\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tdebugger;\n\t\t\treturn undefined;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IssueSorting } from "../../../git/models/issue.js";
|
|
2
|
+
import "../providerFilters.js";
|
|
2
3
|
//#region ../plus/integrations/src/providers/issueSorts.d.ts
|
|
3
4
|
/** GitHub and GHE: one `search` channel serves all three issue reads, so all three order the same way. */
|
|
4
5
|
export declare const githubIssueSorts: IssueSorting[];
|
|
@@ -2,6 +2,7 @@ import { ResourceDescriptor } from "../../../git/models/resourceDescriptor.js";
|
|
|
2
2
|
import { PullRequest, PullRequestFilter, PullRequestStateFilter } from "../../../git/models/pullRequest.js";
|
|
3
3
|
import { IntegrationIds } from "../constants.js";
|
|
4
4
|
import { ProviderWarning } from "../results.js";
|
|
5
|
+
import "../providerFilters.js";
|
|
5
6
|
import { ProviderPullRequest, ProviderReposInput, ProviderRepository } from "../providers/models.js";
|
|
6
7
|
import { GitHostIntegration } from "../models/gitHostIntegration.js";
|
|
7
8
|
import { IssuesIntegration } from "../models/issuesIntegration.js";
|
|
@@ -16,10 +16,12 @@ interface LogOptions<T extends (...args: any[]) => any> {
|
|
|
16
16
|
exit?: ((result: PromiseType<ReturnType<T>>) => string) | true;
|
|
17
17
|
/** Overrides the log line prefix. Receives a {@link LogContext} and the method args. */
|
|
18
18
|
prefix?(context: LogContext, ...args: Parameters<T>): string;
|
|
19
|
-
/** Suppresses the entry log line and only logs on exit. `{ after: N }` further suppresses exit unless duration exceeds N ms. */
|
|
19
|
+
/** Suppresses the entry log line and only logs on exit. `{ after: N }` further suppresses exit unless duration exceeds N ms, the call ran slow, or it failed. */
|
|
20
20
|
onlyExit?: true | {
|
|
21
21
|
after: number;
|
|
22
22
|
};
|
|
23
|
+
/** Marks a read whose only work worth logging shows up as lines of its own (e.g. git commands) and that changes no state silently. When the logger sets `quietCallsUnder`, it writes no entry line up front, and logs only if it took that long, failed, ran slow, or something was logged while it ran. */
|
|
24
|
+
quiet?: true;
|
|
23
25
|
/** Controls duration timing. `false` disables timing. `{ warnAfter: N }` overrides the slow call warning threshold (default 500ms). */
|
|
24
26
|
timing?: boolean | {
|
|
25
27
|
warnAfter: number;
|