@gitkraken/core-gitlens 0.15.4 → 0.15.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/dist/git/cache.d.ts +9 -12
  3. package/dist/git/cache.js +34 -16
  4. package/dist/git/cache.js.map +1 -1
  5. package/dist/git/context.d.ts +19 -2
  6. package/dist/git/context.js.map +1 -1
  7. package/dist/git/providers/provider.d.ts +7 -0
  8. package/dist/git/service.d.ts +5 -1
  9. package/dist/git/service.js +8 -4
  10. package/dist/git/service.js.map +1 -1
  11. package/dist/git/watching/changeEvent.d.ts +25 -1
  12. package/dist/git/watching/changeEvent.js +36 -2
  13. package/dist/git/watching/changeEvent.js.map +1 -1
  14. package/dist/git/watching/configSections.d.ts +35 -0
  15. package/dist/git/watching/configSections.js +210 -0
  16. package/dist/git/watching/configSections.js.map +1 -0
  17. package/dist/git/watching/watchGroup.d.ts +36 -3
  18. package/dist/git/watching/watchGroup.js +107 -2
  19. package/dist/git/watching/watchGroup.js.map +1 -1
  20. package/dist/git/watching/watchService.d.ts +14 -3
  21. package/dist/git/watching/watchService.js +10 -7
  22. package/dist/git/watching/watchService.js.map +1 -1
  23. package/dist/git/watching/watchSession.d.ts +52 -21
  24. package/dist/git/watching/watchSession.js +164 -42
  25. package/dist/git/watching/watchSession.js.map +1 -1
  26. package/dist/git/watching/worktreeSummary.d.ts +9 -7
  27. package/dist/git/watching/worktreeSummary.js +21 -10
  28. package/dist/git/watching/worktreeSummary.js.map +1 -1
  29. package/dist/git-cli/cliGitProvider.d.ts +6 -1
  30. package/dist/git-cli/cliGitProvider.js +45 -5
  31. package/dist/git-cli/cliGitProvider.js.map +1 -1
  32. package/dist/git-cli/providers/branches.d.ts +2 -2
  33. package/dist/git-cli/providers/branches.js +17 -15
  34. package/dist/git-cli/providers/branches.js.map +1 -1
  35. package/dist/git-cli/providers/config.d.ts +13 -0
  36. package/dist/git-cli/providers/config.js +38 -1
  37. package/dist/git-cli/providers/config.js.map +1 -1
  38. package/dist/git-cli/providers/operations.d.ts +35 -1
  39. package/dist/git-cli/providers/operations.js +175 -16
  40. package/dist/git-cli/providers/operations.js.map +1 -1
  41. package/dist/git-cli/providers/stash.d.ts +1 -0
  42. package/dist/git-cli/providers/stash.js +9 -3
  43. package/dist/git-cli/providers/stash.js.map +1 -1
  44. package/dist/git-cli/providers/worktrees.js +11 -4
  45. package/dist/git-cli/providers/worktrees.js.map +1 -1
  46. package/dist/git-cli/service.js +5 -1
  47. package/dist/git-cli/service.js.map +1 -1
  48. package/dist/plus/integrations/providers/issueSorts.d.ts +0 -1
  49. package/dist/plus/integrations/reads/drains.d.ts +0 -1
  50. package/package.json +1 -1
@@ -61,10 +61,17 @@ var WorktreesGitSubProvider = class {
61
61
  }
62
62
  }, ex));
63
63
  } finally {
64
- this.context.hooks?.cache?.onReset?.(repoPath, ...options?.createBranch ? ["branches", "worktrees"] : ["worktrees"]);
65
- const changes = options?.createBranch ? ["worktrees", "heads"] : ["worktrees"];
66
- if (options?.createBranch && mayWriteTracking(options.commitish, options.noTracking)) changes.unshift("config");
67
- this.context.hooks?.repository?.onChanged?.(repoPath, changes);
64
+ if (options?.createBranch) {
65
+ this.context.hooks?.cache?.onReset?.(repoPath, ...mayWriteTracking(options.commitish, options.noTracking) ? [
66
+ "branches",
67
+ "config",
68
+ "worktrees"
69
+ ] : ["branches", "worktrees"]);
70
+ this.context.hooks?.repository?.onChanged?.(repoPath, ["worktrees", "heads"], [`refs/heads/${options.createBranch}`]);
71
+ } else {
72
+ this.context.hooks?.cache?.onReset?.(repoPath, "worktrees");
73
+ this.context.hooks?.repository?.onChanged?.(repoPath, ["worktrees"]);
74
+ }
68
75
  }
69
76
  }
70
77
  async createWorktreeWithResult(repoPath, path, options, runOptions) {
@@ -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 { RepositoryChange } from '@gitlens/git/models/repository.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\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\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, ...runOptions }, ...args);\n\n\t\t\tif (options?.createBranch) {\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, options.createBranch);\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\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)) throw ex;\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\tthis.context.hooks?.cache?.onReset?.(\n\t\t\t\trepoPath,\n\t\t\t\t...(options?.createBranch ? (['branches', 'worktrees'] as const) : (['worktrees'] as const)),\n\t\t\t);\n\t\t\tconst changes: RepositoryChange[] = options?.createBranch ? ['worktrees', 'heads'] : ['worktrees'];\n\t\t\tif (options?.createBranch && mayWriteTracking(options.commitish, options.noTracking)) {\n\t\t\t\tchanges.unshift('config');\n\t\t\t}\n\t\t\tthis.context.hooks?.repository?.onChanged?.(repoPath, changes);\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\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\ttry {\n\t\t\tawait this.git.run({ cwd: repoPath, ...runOptions }, ...args);\n\n\t\t\tif (options?.createBranch) {\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, options.createBranch);\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\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)) throw ex;\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 (options?.createBranch) {\n\t\t\t\tthis.context.hooks?.cache?.onReset?.(\n\t\t\t\t\trepoPath,\n\t\t\t\t\t...(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/${options.createBranch}`],\n\t\t\t\t);\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,3 +1,4 @@
1
+ import { fileUri } from "../utils/uri.js";
1
2
  import { GitService } from "../git/service.js";
2
3
  import { CliGitProvider } from "./cliGitProvider.js";
3
4
  import { findGitPath } from "./exec/locator.js";
@@ -22,7 +23,10 @@ import { findGitPath } from "./exec/locator.js";
22
23
  * ```
23
24
  */
24
25
  function createCliGitService(options) {
25
- const service = GitService.createSingleton(options.watchingProvider, { watchPolling: options.watchPolling });
26
+ const service = GitService.createSingleton(options.watchingProvider, {
27
+ watchPolling: options.watchPolling,
28
+ readFile: (path) => options.context.fs.readFile(fileUri(path))
29
+ });
26
30
  const locator = options.locator ?? (() => findGitPath(options.gitPath ?? null));
27
31
  const provider = new CliGitProvider({
28
32
  context: options.context,
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","names":[],"sources":["../../../git-cli/src/service.ts"],"sourcesContent":["import { GitService } from '@gitlens/git/service.js';\nimport type { FileWatchingProvider } from '@gitlens/git/watching/provider.js';\nimport type { WatchPollingOptions } from '@gitlens/git/watching/watchService.js';\nimport type { CliGitProviderOptions } from './cliGitProvider.js';\nimport { CliGitProvider } from './cliGitProvider.js';\nimport type { GitLocation } from './exec/locator.js';\nimport { findGitPath } from './exec/locator.js';\n\n/**\n * Options for {@link createCliGitService}.\n */\nexport interface CliGitServiceOptions {\n\t/**\n\t * Path(s) to the git binary.\n\t * Auto-detected if omitted (searches PATH, platform-specific locations).\n\t * Ignored when {@link locator} is provided.\n\t */\n\tgitPath?: string | string[];\n\n\t/**\n\t * Custom git binary resolver. When provided, used instead of the\n\t * default `findGitPath(gitPath)` lookup.\n\t */\n\tlocator?: () => Promise<GitLocation>;\n\n\t/** Host-provided context hooks (cache events, workspace, integrations, telemetry, fs) */\n\tcontext: CliGitProviderOptions['context'];\n\n\t/** Git execution options passed through to the underlying Git executor */\n\tgitOptions?: CliGitProviderOptions['gitOptions'];\n\n\t/** Use an existing Cache instance, or one will be created */\n\tcache?: CliGitProviderOptions['cache'];\n\n\t/**\n\t * Filesystem watching provider. When provided, the {@link GitService}\n\t * will watch repositories for changes (file creates, edits, deletes).\n\t */\n\twatchingProvider?: FileWatchingProvider;\n\n\t/**\n\t * Polls in place of (or beside) the watchers {@link watchingProvider} reports it can't trust. When omitted, no\n\t * watcher is asked.\n\t */\n\twatchPolling?: WatchPollingOptions;\n}\n\n/**\n * Creates a ready-to-use {@link GitService} backed by the CLI git provider.\n *\n * This is the primary entry point for standalone (non-VS Code) consumers\n * of the `@gitlens/git-cli` library. It creates a singleton {@link GitService},\n * wires up a {@link CliGitProvider}, and registers it for all repository paths.\n *\n * @example\n * ```typescript\n * const git = createCliGitService({ context: {} });\n *\n * const repo = git.forRepo('/path/to/repo')!;\n * const branches = await repo.branches.getBranches();\n * const status = await repo.status.getStatus();\n * await repo.ops!.fetch({ remote: 'origin' });\n *\n * git.dispose(); // cleans up provider, cache, and module-level state\n * ```\n */\nexport function createCliGitService(options: CliGitServiceOptions): GitService {\n\tconst service = GitService.createSingleton(options.watchingProvider, { watchPolling: options.watchPolling });\n\n\tconst locator = options.locator ?? (() => findGitPath(options.gitPath ?? null));\n\tconst provider = new CliGitProvider({\n\t\tcontext: options.context,\n\t\tlocator: locator,\n\t\tgitOptions: options.gitOptions,\n\t\tcache: options.cache,\n\t});\n\n\tservice.register(provider, () => true);\n\n\t// Advance the provider cache's status generation clock from the watch session's global events — the standalone\n\t// analogue of what the VS Code host wires in `GitProviderService`. Without this, a consumer that passes a\n\t// `watchingProvider` and drives watch sessions gets FS events but a FROZEN clock, so `dedupeByStatusGeneration`\n\t// degrades to the pre-change/post-change stale-join this branch exists to fix. Standalone has no `Repository`\n\t// models, so there are no force-fired `closed`/`lastFetched` bypassing the session for the global repo event to\n\t// miss. Subscriptions are torn down with the service (its `watchService`'s emitters are disposed on dispose).\n\tservice.watchService?.onDidChangeWorkingTree(repoPath => provider.cache.onWorkingTreeChanged(repoPath));\n\t// Announced kinds were evicted when core announced its write; evicting them again would discard what the host\n\t// re-read since\n\tservice.watchService?.onDidChangeRepository(e => {\n\t\tconst changes = e.getUnannouncedChanges();\n\t\tif (changes.length) {\n\t\t\tprovider.cache.onRepositoryChanged(e.repoPath, changes);\n\t\t}\n\t});\n\t// FETCH_HEAD maps to no session change, and there's no `Repository` model here to force-fire `lastFetched` (as\n\t// the VS Code host does), so bridge it straight to the cache or the last-fetched time is never re-read.\n\tservice.watchService?.onDidChangeFetchHead(repoPath =>\n\t\tprovider.cache.onRepositoryChanged(repoPath, ['lastFetched']),\n\t);\n\treturn service;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAkEA,SAAgB,oBAAoB,SAA2C;CAC9E,MAAM,UAAU,WAAW,gBAAgB,QAAQ,kBAAkB,EAAE,cAAc,QAAQ,aAAa,CAAC;CAE3G,MAAM,UAAU,QAAQ,kBAAkB,YAAY,QAAQ,WAAW,IAAI;CAC7E,MAAM,WAAW,IAAI,eAAe;EACnC,SAAS,QAAQ;EACR;EACT,YAAY,QAAQ;EACpB,OAAO,QAAQ;CAChB,CAAC;CAED,QAAQ,SAAS,gBAAgB,IAAI;CAQrC,QAAQ,cAAc,wBAAuB,aAAY,SAAS,MAAM,qBAAqB,QAAQ,CAAC;CAGtG,QAAQ,cAAc,uBAAsB,MAAK;EAChD,MAAM,UAAU,EAAE,sBAAsB;EACxC,IAAI,QAAQ,QACX,SAAS,MAAM,oBAAoB,EAAE,UAAU,OAAO;CAExD,CAAC;CAGD,QAAQ,cAAc,sBAAqB,aAC1C,SAAS,MAAM,oBAAoB,UAAU,CAAC,aAAa,CAAC,CAC7D;CACA,OAAO;AACR"}
1
+ {"version":3,"file":"service.js","names":[],"sources":["../../../git-cli/src/service.ts"],"sourcesContent":["import { GitService } from '@gitlens/git/service.js';\nimport type { FileWatchingProvider } from '@gitlens/git/watching/provider.js';\nimport type { WatchPollingOptions } from '@gitlens/git/watching/watchService.js';\nimport { fileUri } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderOptions } from './cliGitProvider.js';\nimport { CliGitProvider } from './cliGitProvider.js';\nimport type { GitLocation } from './exec/locator.js';\nimport { findGitPath } from './exec/locator.js';\n\n/**\n * Options for {@link createCliGitService}.\n */\nexport interface CliGitServiceOptions {\n\t/**\n\t * Path(s) to the git binary.\n\t * Auto-detected if omitted (searches PATH, platform-specific locations).\n\t * Ignored when {@link locator} is provided.\n\t */\n\tgitPath?: string | string[];\n\n\t/**\n\t * Custom git binary resolver. When provided, used instead of the\n\t * default `findGitPath(gitPath)` lookup.\n\t */\n\tlocator?: () => Promise<GitLocation>;\n\n\t/** Host-provided context hooks (cache events, workspace, integrations, telemetry, fs) */\n\tcontext: CliGitProviderOptions['context'];\n\n\t/** Git execution options passed through to the underlying Git executor */\n\tgitOptions?: CliGitProviderOptions['gitOptions'];\n\n\t/** Use an existing Cache instance, or one will be created */\n\tcache?: CliGitProviderOptions['cache'];\n\n\t/**\n\t * Filesystem watching provider. When provided, the {@link GitService}\n\t * will watch repositories for changes (file creates, edits, deletes).\n\t */\n\twatchingProvider?: FileWatchingProvider;\n\n\t/**\n\t * Polls in place of (or beside) the watchers {@link watchingProvider} reports it can't trust. When omitted, no\n\t * watcher is asked.\n\t */\n\twatchPolling?: WatchPollingOptions;\n}\n\n/**\n * Creates a ready-to-use {@link GitService} backed by the CLI git provider.\n *\n * This is the primary entry point for standalone (non-VS Code) consumers\n * of the `@gitlens/git-cli` library. It creates a singleton {@link GitService},\n * wires up a {@link CliGitProvider}, and registers it for all repository paths.\n *\n * @example\n * ```typescript\n * const git = createCliGitService({ context: {} });\n *\n * const repo = git.forRepo('/path/to/repo')!;\n * const branches = await repo.branches.getBranches();\n * const status = await repo.status.getStatus();\n * await repo.ops!.fetch({ remote: 'origin' });\n *\n * git.dispose(); // cleans up provider, cache, and module-level state\n * ```\n */\nexport function createCliGitService(options: CliGitServiceOptions): GitService {\n\tconst service = GitService.createSingleton(options.watchingProvider, {\n\t\twatchPolling: options.watchPolling,\n\t\t// The host's file system reads the shared `.git/config` the watch service compares reports of\n\t\treadFile: path => options.context.fs.readFile(fileUri(path)),\n\t});\n\n\tconst locator = options.locator ?? (() => findGitPath(options.gitPath ?? null));\n\tconst provider = new CliGitProvider({\n\t\tcontext: options.context,\n\t\tlocator: locator,\n\t\tgitOptions: options.gitOptions,\n\t\tcache: options.cache,\n\t});\n\n\tservice.register(provider, () => true);\n\n\t// Advance the provider cache's status generation clock from the watch session's global events — the standalone\n\t// analogue of what the VS Code host wires in `GitProviderService`. Without this, a consumer that passes a\n\t// `watchingProvider` and drives watch sessions gets FS events but a FROZEN clock, so `dedupeByStatusGeneration`\n\t// degrades to the pre-change/post-change stale-join this branch exists to fix. Standalone has no `Repository`\n\t// models, so there are no force-fired `closed`/`lastFetched` bypassing the session for the global repo event to\n\t// miss. Subscriptions are torn down with the service (its `watchService`'s emitters are disposed on dispose).\n\tservice.watchService?.onDidChangeWorkingTree(repoPath => provider.cache.onWorkingTreeChanged(repoPath));\n\t// Announced kinds were evicted when core announced its write; evicting them again would discard what the host\n\t// re-read since\n\tservice.watchService?.onDidChangeRepository(e => {\n\t\tconst changes = e.getUnannouncedChanges();\n\t\tif (changes.length) {\n\t\t\tprovider.cache.onRepositoryChanged(e.repoPath, changes);\n\t\t}\n\t});\n\t// FETCH_HEAD maps to no session change, and there's no `Repository` model here to force-fire `lastFetched` (as\n\t// the VS Code host does), so bridge it straight to the cache or the last-fetched time is never re-read.\n\tservice.watchService?.onDidChangeFetchHead(repoPath =>\n\t\tprovider.cache.onRepositoryChanged(repoPath, ['lastFetched']),\n\t);\n\treturn service;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAmEA,SAAgB,oBAAoB,SAA2C;CAC9E,MAAM,UAAU,WAAW,gBAAgB,QAAQ,kBAAkB;EACpE,cAAc,QAAQ;EAEtB,WAAU,SAAQ,QAAQ,QAAQ,GAAG,SAAS,QAAQ,IAAI,CAAC;CAC5D,CAAC;CAED,MAAM,UAAU,QAAQ,kBAAkB,YAAY,QAAQ,WAAW,IAAI;CAC7E,MAAM,WAAW,IAAI,eAAe;EACnC,SAAS,QAAQ;EACR;EACT,YAAY,QAAQ;EACpB,OAAO,QAAQ;CAChB,CAAC;CAED,QAAQ,SAAS,gBAAgB,IAAI;CAQrC,QAAQ,cAAc,wBAAuB,aAAY,SAAS,MAAM,qBAAqB,QAAQ,CAAC;CAGtG,QAAQ,cAAc,uBAAsB,MAAK;EAChD,MAAM,UAAU,EAAE,sBAAsB;EACxC,IAAI,QAAQ,QACX,SAAS,MAAM,oBAAoB,EAAE,UAAU,OAAO;CAExD,CAAC;CAGD,QAAQ,cAAc,sBAAqB,aAC1C,SAAS,MAAM,oBAAoB,UAAU,CAAC,aAAa,CAAC,CAC7D;CACA,OAAO;AACR"}
@@ -1,5 +1,4 @@
1
1
  import { IssueSorting } from "../../../git/models/issue.js";
2
- import "../providerFilters.js";
3
2
  //#region ../plus/integrations/src/providers/issueSorts.d.ts
4
3
  /** GitHub and GHE: one `search` channel serves all three issue reads, so all three order the same way. */
5
4
  export declare const githubIssueSorts: IssueSorting[];
@@ -2,7 +2,6 @@ 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";
6
5
  import { ProviderPullRequest, ProviderReposInput, ProviderRepository } from "../providers/models.js";
7
6
  import { GitHostIntegration } from "../models/gitHostIntegration.js";
8
7
  import { IssuesIntegration } from "../models/issuesIntegration.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gitkraken/core-gitlens",
3
3
  "description": "GitLens core — shared Git / AI / GitHub primitives for internal GitKraken consumption",
4
- "version": "0.15.4",
4
+ "version": "0.15.5",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": {
7
7
  "name": "GitKraken",