@gitkraken/core-gitlens 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/CHANGELOG.md +78 -1
  2. package/dist/git/cache.d.ts +84 -29
  3. package/dist/git/cache.js +188 -54
  4. package/dist/git/cache.js.map +1 -1
  5. package/dist/git/features.d.ts +1 -1
  6. package/dist/git/features.js +5 -0
  7. package/dist/git/features.js.map +1 -1
  8. package/dist/git/models/branch.d.ts +20 -2
  9. package/dist/git/models/branch.js +28 -6
  10. package/dist/git/models/branch.js.map +1 -1
  11. package/dist/git/models/reference.d.ts +3 -0
  12. package/dist/git/models/status.js +2 -2
  13. package/dist/git/models/worktree.d.ts +4 -1
  14. package/dist/git/models/worktree.js +4 -2
  15. package/dist/git/models/worktree.js.map +1 -1
  16. package/dist/git/parsers/diffParser.js +1 -1
  17. package/dist/git/providers/branches.d.ts +73 -8
  18. package/dist/git/providers/operations.d.ts +3 -2
  19. package/dist/git/providers/pausedOperations.d.ts +6 -0
  20. package/dist/git/providers/provider.d.ts +45 -2
  21. package/dist/git/providers/revision.d.ts +17 -3
  22. package/dist/git/providers/status.d.ts +8 -2
  23. package/dist/git/remotes/azure-devops.js +61 -53
  24. package/dist/git/remotes/azure-devops.js.map +1 -1
  25. package/dist/git/run.types.d.ts +12 -0
  26. package/dist/git/service.d.ts +8 -5
  27. package/dist/git/service.js +16 -8
  28. package/dist/git/service.js.map +1 -1
  29. package/dist/git/utils/branch.utils.d.ts +12 -2
  30. package/dist/git/utils/branch.utils.js +49 -5
  31. package/dist/git/utils/branch.utils.js.map +1 -1
  32. package/dist/git/utils/reference.utils.d.ts +1 -0
  33. package/dist/git/utils/reference.utils.js.map +1 -1
  34. package/dist/git/watching/changeEvent.d.ts +13 -2
  35. package/dist/git/watching/changeEvent.js +17 -3
  36. package/dist/git/watching/changeEvent.js.map +1 -1
  37. package/dist/git/watching/gitDirPoller.d.ts +111 -0
  38. package/dist/git/watching/gitDirPoller.js +266 -0
  39. package/dist/git/watching/gitDirPoller.js.map +1 -0
  40. package/dist/git/watching/provider.d.ts +16 -0
  41. package/dist/git/watching/watchGroup.d.ts +40 -4
  42. package/dist/git/watching/watchGroup.js +143 -17
  43. package/dist/git/watching/watchGroup.js.map +1 -1
  44. package/dist/git/watching/watchService.d.ts +70 -1
  45. package/dist/git/watching/watchService.js +158 -13
  46. package/dist/git/watching/watchService.js.map +1 -1
  47. package/dist/git/watching/watchSession.d.ts +44 -0
  48. package/dist/git/watching/watchSession.js +91 -6
  49. package/dist/git/watching/watchSession.js.map +1 -1
  50. package/dist/git/watching/watcherPatterns.d.ts +21 -0
  51. package/dist/git/watching/watcherPatterns.js +67 -1
  52. package/dist/git/watching/watcherPatterns.js.map +1 -1
  53. package/dist/git/watching/worktreeSummary.d.ts +34 -7
  54. package/dist/git/watching/worktreeSummary.js +39 -12
  55. package/dist/git/watching/worktreeSummary.js.map +1 -1
  56. package/dist/git-cli/cliGitProvider.d.ts +40 -2
  57. package/dist/git-cli/cliGitProvider.js +182 -18
  58. package/dist/git-cli/cliGitProvider.js.map +1 -1
  59. package/dist/git-cli/exec/commandClassifier.d.ts +15 -0
  60. package/dist/git-cli/exec/commandClassifier.js +48 -2
  61. package/dist/git-cli/exec/commandClassifier.js.map +1 -1
  62. package/dist/git-cli/exec/git.d.ts +20 -3
  63. package/dist/git-cli/exec/git.js +63 -19
  64. package/dist/git-cli/exec/git.js.map +1 -1
  65. package/dist/git-cli/exec/gitQueue.d.ts +2 -0
  66. package/dist/git-cli/exec/gitQueue.js +2 -1
  67. package/dist/git-cli/exec/gitQueue.js.map +1 -1
  68. package/dist/git-cli/exec/indexLock.d.ts +39 -0
  69. package/dist/git-cli/exec/indexLock.js +160 -0
  70. package/dist/git-cli/exec/indexLock.js.map +1 -0
  71. package/dist/git-cli/parsers/blameParser.js +2 -2
  72. package/dist/git-cli/parsers/refParser.js +4 -2
  73. package/dist/git-cli/parsers/refParser.js.map +1 -1
  74. package/dist/git-cli/parsers/statusParser.d.ts +6 -0
  75. package/dist/git-cli/parsers/statusParser.js +33 -3
  76. package/dist/git-cli/parsers/statusParser.js.map +1 -1
  77. package/dist/git-cli/parsers/worktreeParser.js +42 -2
  78. package/dist/git-cli/parsers/worktreeParser.js.map +1 -1
  79. package/dist/git-cli/providers/branchRemote.d.ts +14 -0
  80. package/dist/git-cli/providers/branchRemote.js +36 -0
  81. package/dist/git-cli/providers/branchRemote.js.map +1 -0
  82. package/dist/git-cli/providers/branches.d.ts +109 -10
  83. package/dist/git-cli/providers/branches.js +630 -134
  84. package/dist/git-cli/providers/branches.js.map +1 -1
  85. package/dist/git-cli/providers/commits.js +2 -2
  86. package/dist/git-cli/providers/config.d.ts +9 -5
  87. package/dist/git-cli/providers/config.js +58 -25
  88. package/dist/git-cli/providers/config.js.map +1 -1
  89. package/dist/git-cli/providers/contributors.js +1 -1
  90. package/dist/git-cli/providers/graph.js +9 -6
  91. package/dist/git-cli/providers/graph.js.map +1 -1
  92. package/dist/git-cli/providers/operations.d.ts +17 -0
  93. package/dist/git-cli/providers/operations.js +172 -111
  94. package/dist/git-cli/providers/operations.js.map +1 -1
  95. package/dist/git-cli/providers/pausedOperations.d.ts +8 -0
  96. package/dist/git-cli/providers/pausedOperations.js +59 -39
  97. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  98. package/dist/git-cli/providers/refs.js +11 -8
  99. package/dist/git-cli/providers/refs.js.map +1 -1
  100. package/dist/git-cli/providers/remotes.js +19 -10
  101. package/dist/git-cli/providers/remotes.js.map +1 -1
  102. package/dist/git-cli/providers/revision.d.ts +6 -2
  103. package/dist/git-cli/providers/revision.js +38 -12
  104. package/dist/git-cli/providers/revision.js.map +1 -1
  105. package/dist/git-cli/providers/staging.js +39 -14
  106. package/dist/git-cli/providers/staging.js.map +1 -1
  107. package/dist/git-cli/providers/stash.d.ts +2 -0
  108. package/dist/git-cli/providers/stash.js +33 -18
  109. package/dist/git-cli/providers/stash.js.map +1 -1
  110. package/dist/git-cli/providers/status.d.ts +3 -1
  111. package/dist/git-cli/providers/status.js +40 -22
  112. package/dist/git-cli/providers/status.js.map +1 -1
  113. package/dist/git-cli/providers/tags.js +6 -4
  114. package/dist/git-cli/providers/tags.js.map +1 -1
  115. package/dist/git-cli/providers/worktrees.d.ts +1 -0
  116. package/dist/git-cli/providers/worktrees.js +60 -31
  117. package/dist/git-cli/providers/worktrees.js.map +1 -1
  118. package/dist/git-cli/service.d.ts +6 -0
  119. package/dist/git-cli/service.js +5 -2
  120. package/dist/git-cli/service.js.map +1 -1
  121. package/dist/plus/git-github/providers/github/revision.d.ts +6 -2
  122. package/dist/plus/git-github/providers/github/revision.js +15 -10
  123. package/dist/plus/git-github/providers/github/revision.js.map +1 -1
  124. package/dist/plus/git-github/providers/github/status.d.ts +3 -1
  125. package/dist/plus/git-github/providers/github/status.js +2 -2
  126. package/dist/plus/git-github/providers/github/status.js.map +1 -1
  127. package/dist/plus/integrations/collectionMetadata.d.ts +13 -2
  128. package/dist/plus/integrations/collectionMetadata.js +14 -2
  129. package/dist/plus/integrations/collectionMetadata.js.map +1 -1
  130. package/dist/plus/integrations/index.d.ts +2 -2
  131. package/dist/plus/integrations/index.js.map +1 -1
  132. package/dist/plus/integrations/integrationService.d.ts +1 -0
  133. package/dist/plus/integrations/integrationService.js +1 -1
  134. package/dist/plus/integrations/integrationService.js.map +1 -1
  135. package/dist/plus/integrations/manager.d.ts +1 -0
  136. package/dist/plus/integrations/models/gitHostIntegration.d.ts +41 -5
  137. package/dist/plus/integrations/models/gitHostIntegration.js +106 -29
  138. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  139. package/dist/plus/integrations/models/issueReads.d.ts +17 -4
  140. package/dist/plus/integrations/providers/apiClients.d.ts +2 -0
  141. package/dist/plus/integrations/providers/apiClients.js +7 -1
  142. package/dist/plus/integrations/providers/apiClients.js.map +1 -1
  143. package/dist/plus/integrations/providers/azure/azure.d.ts +5 -4
  144. package/dist/plus/integrations/providers/azure/azure.js +36 -76
  145. package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
  146. package/dist/plus/integrations/providers/azure/azure.utils.js +20 -17
  147. package/dist/plus/integrations/providers/azure/azure.utils.js.map +1 -1
  148. package/dist/plus/integrations/providers/azure/models.d.ts +2 -2
  149. package/dist/plus/integrations/providers/azure/models.js +4 -4
  150. package/dist/plus/integrations/providers/azure/models.js.map +1 -1
  151. package/dist/plus/integrations/providers/azure/workItemStateCategories.d.ts +21 -12
  152. package/dist/plus/integrations/providers/azure/workItemStateCategories.js +74 -17
  153. package/dist/plus/integrations/providers/azure/workItemStateCategories.js.map +1 -1
  154. package/dist/plus/integrations/providers/azureDevOps.d.ts +44 -0
  155. package/dist/plus/integrations/providers/azureDevOps.js +108 -17
  156. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  157. package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +45 -1
  158. package/dist/plus/integrations/providers/azureDevOpsServer.js +121 -6
  159. package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
  160. package/dist/plus/integrations/providers/jira-server.js +18 -14
  161. package/dist/plus/integrations/providers/jira-server.js.map +1 -1
  162. package/dist/plus/integrations/providers/jira.js +18 -14
  163. package/dist/plus/integrations/providers/jira.js.map +1 -1
  164. package/dist/plus/integrations/providers/models.d.ts +1 -2
  165. package/dist/plus/integrations/providers/models.js +9 -2
  166. package/dist/plus/integrations/providers/models.js.map +1 -1
  167. package/dist/plus/integrations/providers/providersApi.d.ts +7 -17
  168. package/dist/plus/integrations/providers/providersApi.js +85 -78
  169. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  170. package/dist/plus/integrations/providers/utils/jiraIssueDrains.d.ts +22 -0
  171. package/dist/plus/integrations/providers/utils/jiraIssueDrains.js +69 -9
  172. package/dist/plus/integrations/providers/utils/jiraIssueDrains.js.map +1 -1
  173. package/dist/plus/integrations/providers/utils/providerPaging.js +8 -2
  174. package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
  175. package/dist/plus/integrations/reads/filters.d.ts +3 -3
  176. package/dist/plus/integrations/reads/filters.js.map +1 -1
  177. package/dist/plus/integrations/reads/issueBatch.d.ts +2 -1
  178. package/dist/plus/integrations/reads/issueBatch.js +1 -1
  179. package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
  180. package/dist/plus/integrations/reads/issueTracker.js +23 -14
  181. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  182. package/dist/plus/integrations/reads/issues.d.ts +2 -1
  183. package/dist/plus/integrations/reads/issues.js +18 -3
  184. package/dist/plus/integrations/reads/issues.js.map +1 -1
  185. package/dist/plus/integrations/reads/pullRequestBatch.js +1 -1
  186. package/dist/plus/integrations/reads/resolveRepository.js +12 -3
  187. package/dist/plus/integrations/reads/resolveRepository.js.map +1 -1
  188. package/dist/plus/integrations/reads/warnings.d.ts +11 -4
  189. package/dist/plus/integrations/reads/warnings.js +15 -5
  190. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  191. package/dist/plus/integrations/results.d.ts +36 -2
  192. package/dist/plus/integrations/results.js +33 -13
  193. package/dist/plus/integrations/results.js.map +1 -1
  194. package/dist/utils/promiseCache.d.ts +10 -0
  195. package/dist/utils/promiseCache.js +17 -2
  196. package/dist/utils/promiseCache.js.map +1 -1
  197. package/docs/integrations.md +52 -20
  198. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"branch.utils.js","names":[],"sources":["../../../../git/src/utils/branch.utils.ts"],"sourcesContent":["import { getRemoteNameSlashIndex } from '@gitlens/utils/gitRefs.js';\nimport type { PageableResult } from '@gitlens/utils/paging.js';\nimport type { GitBranch, GitTrackingUpstream } from '../models/branch.js';\nimport type { GitBranchReference, GitReference } from '../models/reference.js';\nimport { shortenRevision } from './revision.utils.js';\n\n/**\n * The names git uses where a branch name would go when HEAD isn't on a branch — `(HEAD detached\n * at|from <rev>)`, `(no branch)`, `(no branch, rebasing <name>)`, `(no branch, bisect started on\n * <name>)`, and `git status --porcelain=v2`'s `branch.head` token `(detached)` — plus bare `HEAD`\n * and our own {@link formatDetachedHeadName} output (`(<rev>...)`).\n *\n * Deliberately NOT \"anything parenthesized\": parentheses are legal in ref names, so `(release)`,\n * `v1.0(rc)` and `feat/(wip)` are all real branches a user can be on. Matching those made\n * `GitBranch` rewrite a genuine branch's `name` to the synthesized `(sha…)` label and re-key its\n * `id` by SHA, which corrupts its identity for every downstream consumer.\n */\nconst detachedHEADRegex = /^(?:HEAD|\\(detached\\)|\\(HEAD detached (?:at|from) .+\\)|\\(no branch.*\\)|\\(.+\\.\\.\\.\\))$/;\n\nexport function formatDetachedHeadName(sha: string): string {\n\treturn `(${shortenRevision(sha)}...)`;\n}\n\nexport function getBranchNameAndRemote(ref: GitBranchReference): [name: string, remote: string | undefined] {\n\tif (ref.remote) {\n\t\tconst index = getRemoteNameSlashIndex(ref.name);\n\t\tif (index === -1) return [ref.name, undefined];\n\n\t\treturn [ref.name.substring(index + 1), ref.name.substring(0, index)];\n\t}\n\n\tif (ref.upstream?.name != null) {\n\t\tconst index = getRemoteNameSlashIndex(ref.upstream.name);\n\t\tif (index === -1) return [ref.name, undefined];\n\n\t\treturn [ref.name, ref.upstream.name.substring(0, index)];\n\t}\n\n\treturn [ref.name, undefined];\n}\n\nexport function getBranchTrackingWithoutRemote(ref: GitBranchReference): string | undefined {\n\treturn ref.upstream?.name.substring(getRemoteNameSlashIndex(ref.upstream.name) + 1);\n}\n\nexport function isDetachedHead(name: string): boolean {\n\t// If there is whitespace in the name assume this is not a valid branch name\n\t// Deals with detached HEAD states\n\tname = name.trim();\n\treturn name.length ? detachedHEADRegex.test(name) : true;\n}\n\nexport function isOfBranchRefType(branch: GitReference | undefined): branch is GitBranchReference {\n\treturn branch?.refType === 'branch';\n}\n\nconst localBranchesPrefixRegex = /^(refs\\/)?heads\\//i;\nconst remoteBranchesPrefixRegex = /^(refs\\/)?remotes\\//i;\nconst remoteHEADRegex = /^(refs\\/)?remotes\\/(.*\\/)HEAD$/i;\n\nexport function isRemoteBranch(refName: string): boolean {\n\treturn remoteBranchesPrefixRegex.test(refName);\n}\n\nexport function isRemoteHEAD(refName: string): boolean {\n\treturn remoteHEADRegex.test(refName);\n}\n\nexport function parseRefName(refName: string): { name: string; remote: boolean } {\n\tconst remote = isRemoteBranch(refName);\n\n\tlet name;\n\tif (remote) {\n\t\t// Strip off refs/remotes/\n\t\tname = refName.replace(remoteBranchesPrefixRegex, '');\n\t} else {\n\t\t// Strip off refs/heads/\n\t\tname = refName.replace(localBranchesPrefixRegex, '');\n\t}\n\n\treturn { name: name, remote: remote };\n}\n\nexport async function getLocalBranchByUpstream(\n\tremoteBranchName: string,\n\tbranches: PageableResult<GitBranch> | ReadonlyMap<unknown, GitBranch>,\n): Promise<GitBranch | undefined> {\n\tlet qualifiedRemoteBranchName;\n\tif (remoteBranchName.startsWith('remotes/')) {\n\t\tqualifiedRemoteBranchName = remoteBranchName;\n\t\tremoteBranchName = remoteBranchName.substring(8);\n\t} else {\n\t\tqualifiedRemoteBranchName = `remotes/${remoteBranchName}`;\n\t}\n\n\tfunction matches(branch: GitBranch): boolean {\n\t\treturn (\n\t\t\t!branch.remote &&\n\t\t\tbranch.upstream?.name != null &&\n\t\t\t(branch.upstream.name === remoteBranchName || branch.upstream.name === qualifiedRemoteBranchName!)\n\t\t);\n\t}\n\n\tconst values = branches.values();\n\tif (Symbol.asyncIterator in values) {\n\t\tfor await (const branch of values) {\n\t\t\tif (matches(branch)) return branch;\n\t\t}\n\t} else {\n\t\tfor (const branch of values) {\n\t\t\tif (matches(branch)) return branch;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nexport async function getLocalBranchUpstreamNames(branches: PageableResult<GitBranch>): Promise<Set<string>> {\n\tconst remoteBranches = new Set<string>();\n\n\tfor await (const branch of branches.values()) {\n\t\tif (!branch.remote && branch.upstream?.name != null) {\n\t\t\tremoteBranches.add(branch.upstream.name);\n\t\t}\n\t}\n\n\treturn remoteBranches;\n}\n\nconst trackingStateRegex = /(?:\\[(?:ahead ([0-9]+))?[,\\s]*(?:behind ([0-9]+))?]|\\[(gone)])/;\n\nexport function parseUpstream(upstream: string, tracking: string): GitTrackingUpstream | undefined {\n\tif (!upstream) return undefined;\n\n\tconst { name } = parseRefName(upstream);\n\n\tconst match = trackingStateRegex.exec(tracking);\n\tif (match == null) {\n\t\treturn { name: name, missing: false, state: { ahead: 0, behind: 0 } };\n\t}\n\n\tconst ahead = match[1] == null ? 0 : Number(match[1]);\n\tconst behind = match[2] == null ? 0 : Number(match[2]);\n\n\treturn {\n\t\tname: name,\n\t\tmissing: match[3] != null,\n\t\tstate: { ahead: isNaN(ahead) ? 0 : ahead, behind: isNaN(behind) ? 0 : behind },\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"branch.utils.js","names":[],"sources":["../../../../git/src/utils/branch.utils.ts"],"sourcesContent":["import { getRemoteNameSlashIndex } from '@gitlens/utils/gitRefs.js';\nimport type { PageableResult } from '@gitlens/utils/paging.js';\nimport type { BranchMetadata, BranchMetadataGkConfigKey, GitBranch, GitTrackingUpstream } from '../models/branch.js';\nimport type { GitBranchReference, GitReference } from '../models/reference.js';\nimport { shortenRevision } from './revision.utils.js';\n\n/**\n * The names git uses where a branch name would go when HEAD isn't on a branch — `(HEAD detached\n * at|from <rev>)`, `(no branch)`, `(no branch, rebasing <name>)`, `(no branch, bisect started on\n * <name>)`, and `git status --porcelain=v2`'s `branch.head` token `(detached)` — plus bare `HEAD`\n * and our own {@link formatDetachedHeadName} output (`(<rev>...)`).\n *\n * Deliberately NOT \"anything parenthesized\": parentheses are legal in ref names, so `(release)`,\n * `v1.0(rc)` and `feat/(wip)` are all real branches a user can be on. Matching those made\n * `GitBranch` rewrite a genuine branch's `name` to the synthesized `(sha…)` label and re-key its\n * `id` by SHA, which corrupts its identity for every downstream consumer.\n */\nconst detachedHEADRegex = /^(?:HEAD|\\(detached\\)|\\(HEAD detached (?:at|from) .+\\)|\\(no branch.*\\)|\\(.+\\.\\.\\.\\))$/;\n\nexport function formatDetachedHeadName(sha: string): string {\n\treturn `(${shortenRevision(sha)}...)`;\n}\n\nexport function getBranchNameAndRemote(ref: GitBranchReference): [name: string, remote: string | undefined] {\n\tif (ref.remote) {\n\t\tconst index = getRemoteNameSlashIndex(ref.name);\n\t\tif (index === -1) return [ref.name, undefined];\n\n\t\treturn [ref.name.substring(index + 1), ref.name.substring(0, index)];\n\t}\n\n\tif (ref.upstream?.remote) return [ref.name, ref.upstream.remote];\n\n\tif (ref.upstream?.name != null) {\n\t\tconst index = getRemoteNameSlashIndex(ref.upstream.name);\n\t\tif (index === -1) return [ref.name, undefined];\n\n\t\treturn [ref.name, ref.upstream.name.substring(0, index)];\n\t}\n\n\treturn [ref.name, undefined];\n}\n\nexport function getBranchTrackingWithoutRemote(ref: GitBranchReference): string | undefined {\n\tif (ref.upstream == null) return undefined;\n\n\tconst { name, remote } = ref.upstream;\n\tif (remote && name.startsWith(`${remote}/`)) return name.substring(remote.length + 1);\n\n\treturn name.substring(getRemoteNameSlashIndex(name) + 1);\n}\n\n/** Splits `name` at the longest of `remoteNames` that prefixes it, so a remote whose own name contains a `/` resolves whole */\nexport function splitRemoteBranchName(\n\tname: string,\n\tremoteNames: Iterable<string>,\n): [remote: string, branch: string] | undefined {\n\tif (name.startsWith('remotes/')) {\n\t\tname = name.substring(8);\n\t}\n\n\tlet match: string | undefined;\n\tfor (const remote of remoteNames) {\n\t\tif (\n\t\t\tname.length > remote.length + 1 &&\n\t\t\tname.charCodeAt(remote.length) === 47 /* '/' */ &&\n\t\t\tname.startsWith(remote) &&\n\t\t\t(match == null || remote.length > match.length)\n\t\t) {\n\t\t\tmatch = remote;\n\t\t}\n\t}\n\n\treturn match != null ? [match, name.substring(match.length + 1)] : undefined;\n}\n\nexport function isDetachedHead(name: string): boolean {\n\t// If there is whitespace in the name assume this is not a valid branch name\n\t// Deals with detached HEAD states\n\tname = name.trim();\n\treturn name.length ? detachedHEADRegex.test(name) : true;\n}\n\nexport function isOfBranchRefType(branch: GitReference | undefined): branch is GitBranchReference {\n\treturn branch?.refType === 'branch';\n}\n\nconst localBranchesPrefixRegex = /^(refs\\/)?heads\\//i;\nconst remoteBranchesPrefixRegex = /^(refs\\/)?remotes\\//i;\nconst remoteHEADRegex = /^(refs\\/)?remotes\\/(.*\\/)HEAD$/i;\n\nexport function isRemoteBranch(refName: string): boolean {\n\treturn remoteBranchesPrefixRegex.test(refName);\n}\n\nexport function isRemoteHEAD(refName: string): boolean {\n\treturn remoteHEADRegex.test(refName);\n}\n\nexport function parseRefName(refName: string): { name: string; remote: boolean } {\n\tconst remote = isRemoteBranch(refName);\n\n\tlet name;\n\tif (remote) {\n\t\t// Strip off refs/remotes/\n\t\tname = refName.replace(remoteBranchesPrefixRegex, '');\n\t} else {\n\t\t// Strip off refs/heads/\n\t\tname = refName.replace(localBranchesPrefixRegex, '');\n\t}\n\n\treturn { name: name, remote: remote };\n}\n\nexport async function getLocalBranchByUpstream(\n\tremoteBranchName: string,\n\tbranches: PageableResult<GitBranch> | ReadonlyMap<unknown, GitBranch>,\n): Promise<GitBranch | undefined> {\n\tlet qualifiedRemoteBranchName;\n\tif (remoteBranchName.startsWith('remotes/')) {\n\t\tqualifiedRemoteBranchName = remoteBranchName;\n\t\tremoteBranchName = remoteBranchName.substring(8);\n\t} else {\n\t\tqualifiedRemoteBranchName = `remotes/${remoteBranchName}`;\n\t}\n\n\tfunction matches(branch: GitBranch): boolean {\n\t\treturn (\n\t\t\t!branch.remote &&\n\t\t\tbranch.upstream?.name != null &&\n\t\t\t(branch.upstream.name === remoteBranchName || branch.upstream.name === qualifiedRemoteBranchName!)\n\t\t);\n\t}\n\n\tconst values = branches.values();\n\tif (Symbol.asyncIterator in values) {\n\t\tfor await (const branch of values) {\n\t\t\tif (matches(branch)) return branch;\n\t\t}\n\t} else {\n\t\tfor (const branch of values) {\n\t\t\tif (matches(branch)) return branch;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nexport async function getLocalBranchUpstreamNames(branches: PageableResult<GitBranch>): Promise<Set<string>> {\n\tconst remoteBranches = new Set<string>();\n\n\tfor await (const branch of branches.values()) {\n\t\tif (!branch.remote && branch.upstream?.name != null) {\n\t\t\tremoteBranches.add(branch.upstream.name);\n\t\t}\n\t}\n\n\treturn remoteBranches;\n}\n\nconst trackingStateRegex = /(?:\\[(?:ahead ([0-9]+))?[,\\s]*(?:behind ([0-9]+))?]|\\[(gone)])/;\n\n/** @param remote - `%(upstream:remotename)`; empty or `.` (a local upstream) is not a remote */\nexport function parseUpstream(upstream: string, tracking: string, remote?: string): GitTrackingUpstream | undefined {\n\tif (!upstream) return undefined;\n\n\tconst { name } = parseRefName(upstream);\n\tconst remoteProp = remote && remote !== '.' ? { remote: remote } : undefined;\n\n\tconst match = trackingStateRegex.exec(tracking);\n\tif (match == null) {\n\t\treturn { name: name, missing: false, state: { ahead: 0, behind: 0 }, ...remoteProp };\n\t}\n\n\tconst ahead = match[1] == null ? 0 : Number(match[1]);\n\tconst behind = match[2] == null ? 0 : Number(match[2]);\n\n\treturn {\n\t\tname: name,\n\t\tmissing: match[3] != null,\n\t\tstate: { ahead: isNaN(ahead) ? 0 : ahead, behind: isNaN(behind) ? 0 : behind },\n\t\t...remoteProp,\n\t};\n}\n\nconst branchMetadataGkConfigKeyRegex =\n\t/^branch\\.(.+)\\.(gk-(?:last-accessed|last-modified|agent-last-activity|disposition))$/;\n\n/** Splits a `branch.<name>.<key>` gk config key that a branch's {@link BranchMetadata} is read from, or `undefined` for any other key */\nexport function parseBranchMetadataGkConfigKey(\n\tkey: string,\n): { branch: string; key: BranchMetadataGkConfigKey } | undefined {\n\tconst match = branchMetadataGkConfigKeyRegex.exec(key);\n\tif (match == null) return undefined;\n\n\treturn { branch: match[1], key: match[2] as BranchMetadataGkConfigKey };\n}\n\n/** Sets the field `key` is read into to `value`, or removes it for `undefined`, exactly as a fresh read of the key would */\nexport function setBranchMetadataValue(\n\tmetadata: BranchMetadata,\n\tkey: BranchMetadataGkConfigKey,\n\tvalue: string | undefined,\n): void {\n\tswitch (key) {\n\t\tcase 'gk-last-accessed':\n\t\t\tif (value != null) {\n\t\t\t\tmetadata.lastAccessedAt = value;\n\t\t\t} else {\n\t\t\t\tdelete metadata.lastAccessedAt;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'gk-last-modified':\n\t\t\tif (value != null) {\n\t\t\t\tmetadata.lastModifiedAt = value;\n\t\t\t} else {\n\t\t\t\tdelete metadata.lastModifiedAt;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'gk-agent-last-activity':\n\t\t\tif (value != null) {\n\t\t\t\tmetadata.agentLastActivityAt = value;\n\t\t\t} else {\n\t\t\t\tdelete metadata.agentLastActivityAt;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'gk-disposition':\n\t\t\tif (value === 'starred' || value === 'archived') {\n\t\t\t\tmetadata.disposition = value;\n\t\t\t} else {\n\t\t\t\tdelete metadata.disposition;\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n"],"mappings":"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"}
@@ -9,6 +9,7 @@ interface GitBranchReferenceOptions {
9
9
  upstream?: {
10
10
  name: string;
11
11
  missing: boolean;
12
+ remote?: string;
12
13
  };
13
14
  worktree?: {
14
15
  path: string;
@@ -1 +1 @@
1
- {"version":3,"file":"reference.utils.js","names":[],"sources":["../../../../git/src/utils/reference.utils.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '@gitlens/utils/gitRefs.js';\nimport type {\n\tGitBranchReference,\n\tGitReference,\n\tGitRevisionReference,\n\tGitStashReference,\n\tGitTagReference,\n} from '../models/reference.js';\nimport { isRevisionRange, isShaWithParentSuffix, shortenRevision } from './revision.utils.js';\n\ninterface GitBranchReferenceOptions {\n\trefType: 'branch';\n\tid?: string;\n\tname: string;\n\tremote: boolean;\n\tsha?: string;\n\tupstream?: { name: string; missing: boolean };\n\tworktree?: { path: string; isDefault: boolean } | boolean;\n}\n\ninterface GitCommitReferenceOptions {\n\trefType: 'revision';\n\tname?: string;\n\tmessage?: string;\n}\n\ninterface GitStashReferenceOptions {\n\trefType: 'stash';\n\tname: string;\n\tnumber: string | undefined;\n\tmessage?: string;\n\tstashOnRef?: string;\n}\n\ninterface GitTagReferenceOptions {\n\trefType: 'tag';\n\tid?: string;\n\tname: string;\n\tsha?: string;\n}\n\nexport function createReference(ref: string, repoPath: string, options: GitBranchReferenceOptions): GitBranchReference;\nexport function createReference(ref: string, repoPath: string, options: GitStashReferenceOptions): GitStashReference;\nexport function createReference(ref: string, repoPath: string, options: GitTagReferenceOptions): GitTagReference;\nexport function createReference(\n\tref: string,\n\trepoPath: string,\n\toptions?: GitCommitReferenceOptions,\n): GitRevisionReference;\nexport function createReference(\n\tref: string,\n\trepoPath: string,\n\toptions:\n\t\t| GitBranchReferenceOptions\n\t\t| GitStashReferenceOptions\n\t\t| GitTagReferenceOptions\n\t\t| GitCommitReferenceOptions = { refType: 'revision' },\n): GitReference {\n\tswitch (options.refType) {\n\t\tcase 'branch':\n\t\t\treturn {\n\t\t\t\trefType: 'branch',\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tref: ref,\n\t\t\t\tname: options.name,\n\t\t\t\tid: options.id,\n\t\t\t\tremote: options.remote,\n\t\t\t\tsha: options.sha,\n\t\t\t\tupstream: options.upstream,\n\t\t\t\tworktree: options.worktree,\n\t\t\t};\n\t\tcase 'stash':\n\t\t\treturn {\n\t\t\t\trefType: 'stash',\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tref: ref,\n\t\t\t\tsha: ref,\n\t\t\t\tname: options.name,\n\t\t\t\tstashNumber: options.number,\n\t\t\t\tmessage: options.message,\n\t\t\t\tstashOnRef: options.stashOnRef,\n\t\t\t};\n\t\tcase 'tag':\n\t\t\treturn {\n\t\t\t\trefType: 'tag',\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tref: ref,\n\t\t\t\tname: options.name,\n\t\t\t\tid: options.id,\n\t\t\t\tsha: options.sha,\n\t\t\t};\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\trefType: 'revision',\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tref: ref,\n\t\t\t\tsha: ref,\n\t\t\t\tname:\n\t\t\t\t\toptions.name ??\n\t\t\t\t\tshortenRevision(ref, {\n\t\t\t\t\t\tstrings: {\n\t\t\t\t\t\t\tuncommitted: l10n.t('Working Tree'),\n\t\t\t\t\t\t\tuncommittedStaged: l10n.t('Index'),\n\t\t\t\t\t\t\tworking: l10n.t('Working Tree'),\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\tmessage: options.message,\n\t\t\t};\n\t}\n}\n\nexport function getReferenceNameWithoutRemote(ref: GitReference): string {\n\tif (ref.refType === 'branch') {\n\t\treturn ref.remote ? getBranchNameWithoutRemote(ref.name) : ref.name;\n\t}\n\treturn ref.name;\n}\n\nexport function getReferenceTypeLabel(ref: GitReference | undefined): string {\n\tswitch (ref?.refType) {\n\t\tcase 'branch':\n\t\t\treturn l10n.t('Branch');\n\t\tcase 'stash':\n\t\t\treturn l10n.t('Stash');\n\t\tcase 'tag':\n\t\t\treturn l10n.t('Tag');\n\t\tdefault:\n\t\t\treturn l10n.t('Commit');\n\t}\n}\n\nexport function isBranchReference(ref: GitReference | undefined): ref is GitBranchReference {\n\treturn ref?.refType === 'branch';\n}\n\nexport function isGitReference(ref: unknown): ref is GitReference {\n\tif (ref == null || typeof ref !== 'object') return false;\n\n\tconst r = ref as GitReference;\n\treturn (\n\t\ttypeof r.refType === 'string' &&\n\t\ttypeof r.repoPath === 'string' &&\n\t\ttypeof r.ref === 'string' &&\n\t\ttypeof r.name === 'string'\n\t);\n}\n\nexport function isRevisionReference(ref: GitReference | undefined): ref is GitRevisionReference {\n\treturn ref?.refType === 'revision';\n}\n\nexport function isRevisionRangeReference(ref: GitReference | undefined): ref is GitRevisionReference {\n\treturn ref?.refType === 'revision' && isRevisionRange(ref.ref);\n}\n\nexport function isStashReference(ref: GitReference | undefined): ref is GitStashReference {\n\treturn ref?.refType === 'stash' || (ref?.refType === 'revision' && Boolean('stashName' in ref && ref.stashName));\n}\n\nexport function isTagReference(ref: GitReference | undefined): ref is GitTagReference {\n\treturn ref?.refType === 'tag';\n}\n\nexport function getReferenceLabel(\n\trefs: GitReference | GitReference[] | undefined,\n\toptions?: { capitalize?: boolean; expand?: boolean; icon?: boolean; label?: boolean; quoted?: boolean } | false,\n): string {\n\tif (refs == null) return '';\n\n\toptions =\n\t\toptions === false\n\t\t\t? {}\n\t\t\t: { expand: true, icon: true, label: options?.label ?? options?.expand ?? true, ...options };\n\n\tlet result;\n\tif (!Array.isArray(refs) || refs.length === 1) {\n\t\tconst ref = Array.isArray(refs) ? refs[0] : refs;\n\t\tlet refName = options?.quoted ? `'${ref.name}'` : ref.name;\n\t\tswitch (ref.refType) {\n\t\t\tcase 'branch': {\n\t\t\t\tif (ref.remote) {\n\t\t\t\t\trefName = `${getRemoteNameFromBranchName(refName)}: ${getBranchNameWithoutRemote(refName)}`;\n\t\t\t\t\trefName = options?.quoted ? `'${refName}'` : refName;\n\t\t\t\t}\n\n\t\t\t\tif (options.label) {\n\t\t\t\t\tif (options.icon) {\n\t\t\t\t\t\tif (options.capitalize && options.expand) {\n\t\t\t\t\t\t\tresult = ref.remote\n\t\t\t\t\t\t\t\t? l10n.t('Remote Branch $(git-branch)\\u00a0{0}', refName)\n\t\t\t\t\t\t\t\t: l10n.t('Branch $(git-branch)\\u00a0{0}', refName);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresult = ref.remote\n\t\t\t\t\t\t\t\t? l10n.t('remote branch $(git-branch)\\u00a0{0}', refName)\n\t\t\t\t\t\t\t\t: l10n.t('branch $(git-branch)\\u00a0{0}', refName);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (options.capitalize && options.expand) {\n\t\t\t\t\t\tresult = ref.remote ? l10n.t('Remote Branch {0}', refName) : l10n.t('Branch {0}', refName);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = ref.remote ? l10n.t('remote branch {0}', refName) : l10n.t('branch {0}', refName);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresult = options.icon ? `$(git-branch)\\u00a0${refName}` : refName;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'tag':\n\t\t\t\tif (options.label) {\n\t\t\t\t\tif (options.icon) {\n\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t? l10n.t('Tag $(tag)\\u00a0{0}', refName)\n\t\t\t\t\t\t\t\t: l10n.t('tag $(tag)\\u00a0{0}', refName);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t? l10n.t('Tag {0}', refName)\n\t\t\t\t\t\t\t\t: l10n.t('tag {0}', refName);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresult = options.icon ? `$(tag)\\u00a0${refName}` : refName;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault: {\n\t\t\t\tif (isStashReference(ref)) {\n\t\t\t\t\tlet message;\n\t\t\t\t\tif (options.expand && ref.message) {\n\t\t\t\t\t\tmessage = `${ref.stashNumber != null ? `#${ref.stashNumber}: ` : ''}${\n\t\t\t\t\t\t\tref.message.length > 20 ? `${ref.message.substring(0, 20).trimEnd()}\\u2026` : ref.message\n\t\t\t\t\t\t}`;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst stashName = message ?? (ref.stashNumber ? `#${ref.stashNumber}` : ref.name);\n\t\t\t\t\tif (options.label) {\n\t\t\t\t\t\tif (options.icon) {\n\t\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t\t? l10n.t('Stash $(archive)\\u00a0{0}', message ?? ref.name)\n\t\t\t\t\t\t\t\t\t: l10n.t('stash $(archive)\\u00a0{0}', message ?? ref.name);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t\t? l10n.t('Stash {0}', stashName)\n\t\t\t\t\t\t\t\t\t: l10n.t('stash {0}', stashName);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = options.icon ? `$(archive)\\u00a0${message ?? ref.name}` : stashName;\n\t\t\t\t\t}\n\t\t\t\t} else if (isRevisionRange(ref.ref)) {\n\t\t\t\t\tresult = refName;\n\t\t\t\t} else {\n\t\t\t\t\tlet message;\n\t\t\t\t\tif (options.expand && ref.message) {\n\t\t\t\t\t\tmessage =\n\t\t\t\t\t\t\tref.message.length > 20\n\t\t\t\t\t\t\t\t? ` (${ref.message.substring(0, 20).trimEnd()}\\u2026)`\n\t\t\t\t\t\t\t\t: ` (${ref.message})`;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet before = false;\n\t\t\t\t\tif (options.expand && options.label && isShaWithParentSuffix(ref.ref)) {\n\t\t\t\t\t\trefName = ref.name.endsWith('^') ? ref.name.substring(0, ref.name.length - 1) : ref.name;\n\t\t\t\t\t\tif (options?.quoted) {\n\t\t\t\t\t\t\trefName = `'${refName}'`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbefore = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (options.label) {\n\t\t\t\t\t\tif (options.icon) {\n\t\t\t\t\t\t\tif (before) {\n\t\t\t\t\t\t\t\tresult = options.capitalize\n\t\t\t\t\t\t\t\t\t? l10n.t('Before commit $(git-commit)\\u00a0{0}{1}', refName, message ?? '')\n\t\t\t\t\t\t\t\t\t: l10n.t('before commit $(git-commit)\\u00a0{0}{1}', refName, message ?? '');\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t\t\t? l10n.t('Commit $(git-commit)\\u00a0{0}{1}', refName, message ?? '')\n\t\t\t\t\t\t\t\t\t\t: l10n.t('commit $(git-commit)\\u00a0{0}{1}', refName, message ?? '');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (before) {\n\t\t\t\t\t\t\tresult = options.capitalize\n\t\t\t\t\t\t\t\t? l10n.t('Before commit {0}{1}', refName, message ?? '')\n\t\t\t\t\t\t\t\t: l10n.t('before commit {0}{1}', refName, message ?? '');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t\t? l10n.t('Commit {0}{1}', refName, message ?? '')\n\t\t\t\t\t\t\t\t\t: l10n.t('commit {0}{1}', refName, message ?? '');\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = options.icon\n\t\t\t\t\t\t\t? `$(git-commit)\\u00a0${refName}${message ?? ''}`\n\t\t\t\t\t\t\t: `${refName}${message ?? ''}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tconst expanded = options.expand ? ` (${refs.map(r => r.name).join(', ')})` : '';\n\tswitch (refs[0].refType) {\n\t\tcase 'branch':\n\t\t\treturn l10n.t('{0} branches{1}', refs.length, expanded);\n\t\tcase 'tag':\n\t\t\treturn l10n.t('{0} tags{1}', refs.length, expanded);\n\t\tdefault:\n\t\t\treturn isStashReference(refs[0])\n\t\t\t\t? l10n.t('{0} stashes{1}', refs.length, expanded)\n\t\t\t\t: l10n.t('{0} commits{1}', refs.length, expanded);\n\t}\n}\n\nexport function getReferenceTypeIcon(ref: GitReference | undefined, webview?: boolean): string {\n\tswitch (ref?.refType) {\n\t\tcase 'branch':\n\t\t\tif (ref.remote) return 'cloud';\n\t\t\tif (ref.worktree) return webview ? 'gl-worktree' : 'gitlens-worktree';\n\t\t\treturn 'git-branch';\n\t\tcase 'tag':\n\t\t\treturn 'tag';\n\t\tcase 'stash':\n\t\t\treturn 'archive';\n\t\tdefault:\n\t\t\treturn 'git-commit';\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"reference.utils.js","names":[],"sources":["../../../../git/src/utils/reference.utils.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '@gitlens/utils/gitRefs.js';\nimport type {\n\tGitBranchReference,\n\tGitReference,\n\tGitRevisionReference,\n\tGitStashReference,\n\tGitTagReference,\n} from '../models/reference.js';\nimport { isRevisionRange, isShaWithParentSuffix, shortenRevision } from './revision.utils.js';\n\ninterface GitBranchReferenceOptions {\n\trefType: 'branch';\n\tid?: string;\n\tname: string;\n\tremote: boolean;\n\tsha?: string;\n\tupstream?: { name: string; missing: boolean; remote?: string };\n\tworktree?: { path: string; isDefault: boolean } | boolean;\n}\n\ninterface GitCommitReferenceOptions {\n\trefType: 'revision';\n\tname?: string;\n\tmessage?: string;\n}\n\ninterface GitStashReferenceOptions {\n\trefType: 'stash';\n\tname: string;\n\tnumber: string | undefined;\n\tmessage?: string;\n\tstashOnRef?: string;\n}\n\ninterface GitTagReferenceOptions {\n\trefType: 'tag';\n\tid?: string;\n\tname: string;\n\tsha?: string;\n}\n\nexport function createReference(ref: string, repoPath: string, options: GitBranchReferenceOptions): GitBranchReference;\nexport function createReference(ref: string, repoPath: string, options: GitStashReferenceOptions): GitStashReference;\nexport function createReference(ref: string, repoPath: string, options: GitTagReferenceOptions): GitTagReference;\nexport function createReference(\n\tref: string,\n\trepoPath: string,\n\toptions?: GitCommitReferenceOptions,\n): GitRevisionReference;\nexport function createReference(\n\tref: string,\n\trepoPath: string,\n\toptions:\n\t\t| GitBranchReferenceOptions\n\t\t| GitStashReferenceOptions\n\t\t| GitTagReferenceOptions\n\t\t| GitCommitReferenceOptions = { refType: 'revision' },\n): GitReference {\n\tswitch (options.refType) {\n\t\tcase 'branch':\n\t\t\treturn {\n\t\t\t\trefType: 'branch',\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tref: ref,\n\t\t\t\tname: options.name,\n\t\t\t\tid: options.id,\n\t\t\t\tremote: options.remote,\n\t\t\t\tsha: options.sha,\n\t\t\t\tupstream: options.upstream,\n\t\t\t\tworktree: options.worktree,\n\t\t\t};\n\t\tcase 'stash':\n\t\t\treturn {\n\t\t\t\trefType: 'stash',\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tref: ref,\n\t\t\t\tsha: ref,\n\t\t\t\tname: options.name,\n\t\t\t\tstashNumber: options.number,\n\t\t\t\tmessage: options.message,\n\t\t\t\tstashOnRef: options.stashOnRef,\n\t\t\t};\n\t\tcase 'tag':\n\t\t\treturn {\n\t\t\t\trefType: 'tag',\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tref: ref,\n\t\t\t\tname: options.name,\n\t\t\t\tid: options.id,\n\t\t\t\tsha: options.sha,\n\t\t\t};\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\trefType: 'revision',\n\t\t\t\trepoPath: repoPath,\n\t\t\t\tref: ref,\n\t\t\t\tsha: ref,\n\t\t\t\tname:\n\t\t\t\t\toptions.name ??\n\t\t\t\t\tshortenRevision(ref, {\n\t\t\t\t\t\tstrings: {\n\t\t\t\t\t\t\tuncommitted: l10n.t('Working Tree'),\n\t\t\t\t\t\t\tuncommittedStaged: l10n.t('Index'),\n\t\t\t\t\t\t\tworking: l10n.t('Working Tree'),\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\tmessage: options.message,\n\t\t\t};\n\t}\n}\n\nexport function getReferenceNameWithoutRemote(ref: GitReference): string {\n\tif (ref.refType === 'branch') {\n\t\treturn ref.remote ? getBranchNameWithoutRemote(ref.name) : ref.name;\n\t}\n\treturn ref.name;\n}\n\nexport function getReferenceTypeLabel(ref: GitReference | undefined): string {\n\tswitch (ref?.refType) {\n\t\tcase 'branch':\n\t\t\treturn l10n.t('Branch');\n\t\tcase 'stash':\n\t\t\treturn l10n.t('Stash');\n\t\tcase 'tag':\n\t\t\treturn l10n.t('Tag');\n\t\tdefault:\n\t\t\treturn l10n.t('Commit');\n\t}\n}\n\nexport function isBranchReference(ref: GitReference | undefined): ref is GitBranchReference {\n\treturn ref?.refType === 'branch';\n}\n\nexport function isGitReference(ref: unknown): ref is GitReference {\n\tif (ref == null || typeof ref !== 'object') return false;\n\n\tconst r = ref as GitReference;\n\treturn (\n\t\ttypeof r.refType === 'string' &&\n\t\ttypeof r.repoPath === 'string' &&\n\t\ttypeof r.ref === 'string' &&\n\t\ttypeof r.name === 'string'\n\t);\n}\n\nexport function isRevisionReference(ref: GitReference | undefined): ref is GitRevisionReference {\n\treturn ref?.refType === 'revision';\n}\n\nexport function isRevisionRangeReference(ref: GitReference | undefined): ref is GitRevisionReference {\n\treturn ref?.refType === 'revision' && isRevisionRange(ref.ref);\n}\n\nexport function isStashReference(ref: GitReference | undefined): ref is GitStashReference {\n\treturn ref?.refType === 'stash' || (ref?.refType === 'revision' && Boolean('stashName' in ref && ref.stashName));\n}\n\nexport function isTagReference(ref: GitReference | undefined): ref is GitTagReference {\n\treturn ref?.refType === 'tag';\n}\n\nexport function getReferenceLabel(\n\trefs: GitReference | GitReference[] | undefined,\n\toptions?: { capitalize?: boolean; expand?: boolean; icon?: boolean; label?: boolean; quoted?: boolean } | false,\n): string {\n\tif (refs == null) return '';\n\n\toptions =\n\t\toptions === false\n\t\t\t? {}\n\t\t\t: { expand: true, icon: true, label: options?.label ?? options?.expand ?? true, ...options };\n\n\tlet result;\n\tif (!Array.isArray(refs) || refs.length === 1) {\n\t\tconst ref = Array.isArray(refs) ? refs[0] : refs;\n\t\tlet refName = options?.quoted ? `'${ref.name}'` : ref.name;\n\t\tswitch (ref.refType) {\n\t\t\tcase 'branch': {\n\t\t\t\tif (ref.remote) {\n\t\t\t\t\trefName = `${getRemoteNameFromBranchName(refName)}: ${getBranchNameWithoutRemote(refName)}`;\n\t\t\t\t\trefName = options?.quoted ? `'${refName}'` : refName;\n\t\t\t\t}\n\n\t\t\t\tif (options.label) {\n\t\t\t\t\tif (options.icon) {\n\t\t\t\t\t\tif (options.capitalize && options.expand) {\n\t\t\t\t\t\t\tresult = ref.remote\n\t\t\t\t\t\t\t\t? l10n.t('Remote Branch $(git-branch)\\u00a0{0}', refName)\n\t\t\t\t\t\t\t\t: l10n.t('Branch $(git-branch)\\u00a0{0}', refName);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresult = ref.remote\n\t\t\t\t\t\t\t\t? l10n.t('remote branch $(git-branch)\\u00a0{0}', refName)\n\t\t\t\t\t\t\t\t: l10n.t('branch $(git-branch)\\u00a0{0}', refName);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (options.capitalize && options.expand) {\n\t\t\t\t\t\tresult = ref.remote ? l10n.t('Remote Branch {0}', refName) : l10n.t('Branch {0}', refName);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = ref.remote ? l10n.t('remote branch {0}', refName) : l10n.t('branch {0}', refName);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresult = options.icon ? `$(git-branch)\\u00a0${refName}` : refName;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'tag':\n\t\t\t\tif (options.label) {\n\t\t\t\t\tif (options.icon) {\n\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t? l10n.t('Tag $(tag)\\u00a0{0}', refName)\n\t\t\t\t\t\t\t\t: l10n.t('tag $(tag)\\u00a0{0}', refName);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t? l10n.t('Tag {0}', refName)\n\t\t\t\t\t\t\t\t: l10n.t('tag {0}', refName);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresult = options.icon ? `$(tag)\\u00a0${refName}` : refName;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault: {\n\t\t\t\tif (isStashReference(ref)) {\n\t\t\t\t\tlet message;\n\t\t\t\t\tif (options.expand && ref.message) {\n\t\t\t\t\t\tmessage = `${ref.stashNumber != null ? `#${ref.stashNumber}: ` : ''}${\n\t\t\t\t\t\t\tref.message.length > 20 ? `${ref.message.substring(0, 20).trimEnd()}\\u2026` : ref.message\n\t\t\t\t\t\t}`;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst stashName = message ?? (ref.stashNumber ? `#${ref.stashNumber}` : ref.name);\n\t\t\t\t\tif (options.label) {\n\t\t\t\t\t\tif (options.icon) {\n\t\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t\t? l10n.t('Stash $(archive)\\u00a0{0}', message ?? ref.name)\n\t\t\t\t\t\t\t\t\t: l10n.t('stash $(archive)\\u00a0{0}', message ?? ref.name);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t\t? l10n.t('Stash {0}', stashName)\n\t\t\t\t\t\t\t\t\t: l10n.t('stash {0}', stashName);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = options.icon ? `$(archive)\\u00a0${message ?? ref.name}` : stashName;\n\t\t\t\t\t}\n\t\t\t\t} else if (isRevisionRange(ref.ref)) {\n\t\t\t\t\tresult = refName;\n\t\t\t\t} else {\n\t\t\t\t\tlet message;\n\t\t\t\t\tif (options.expand && ref.message) {\n\t\t\t\t\t\tmessage =\n\t\t\t\t\t\t\tref.message.length > 20\n\t\t\t\t\t\t\t\t? ` (${ref.message.substring(0, 20).trimEnd()}\\u2026)`\n\t\t\t\t\t\t\t\t: ` (${ref.message})`;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet before = false;\n\t\t\t\t\tif (options.expand && options.label && isShaWithParentSuffix(ref.ref)) {\n\t\t\t\t\t\trefName = ref.name.endsWith('^') ? ref.name.substring(0, ref.name.length - 1) : ref.name;\n\t\t\t\t\t\tif (options?.quoted) {\n\t\t\t\t\t\t\trefName = `'${refName}'`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbefore = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (options.label) {\n\t\t\t\t\t\tif (options.icon) {\n\t\t\t\t\t\t\tif (before) {\n\t\t\t\t\t\t\t\tresult = options.capitalize\n\t\t\t\t\t\t\t\t\t? l10n.t('Before commit $(git-commit)\\u00a0{0}{1}', refName, message ?? '')\n\t\t\t\t\t\t\t\t\t: l10n.t('before commit $(git-commit)\\u00a0{0}{1}', refName, message ?? '');\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t\t\t? l10n.t('Commit $(git-commit)\\u00a0{0}{1}', refName, message ?? '')\n\t\t\t\t\t\t\t\t\t\t: l10n.t('commit $(git-commit)\\u00a0{0}{1}', refName, message ?? '');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (before) {\n\t\t\t\t\t\t\tresult = options.capitalize\n\t\t\t\t\t\t\t\t? l10n.t('Before commit {0}{1}', refName, message ?? '')\n\t\t\t\t\t\t\t\t: l10n.t('before commit {0}{1}', refName, message ?? '');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresult =\n\t\t\t\t\t\t\t\toptions.capitalize && options.expand\n\t\t\t\t\t\t\t\t\t? l10n.t('Commit {0}{1}', refName, message ?? '')\n\t\t\t\t\t\t\t\t\t: l10n.t('commit {0}{1}', refName, message ?? '');\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = options.icon\n\t\t\t\t\t\t\t? `$(git-commit)\\u00a0${refName}${message ?? ''}`\n\t\t\t\t\t\t\t: `${refName}${message ?? ''}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tconst expanded = options.expand ? ` (${refs.map(r => r.name).join(', ')})` : '';\n\tswitch (refs[0].refType) {\n\t\tcase 'branch':\n\t\t\treturn l10n.t('{0} branches{1}', refs.length, expanded);\n\t\tcase 'tag':\n\t\t\treturn l10n.t('{0} tags{1}', refs.length, expanded);\n\t\tdefault:\n\t\t\treturn isStashReference(refs[0])\n\t\t\t\t? l10n.t('{0} stashes{1}', refs.length, expanded)\n\t\t\t\t: l10n.t('{0} commits{1}', refs.length, expanded);\n\t}\n}\n\nexport function getReferenceTypeIcon(ref: GitReference | undefined, webview?: boolean): string {\n\tswitch (ref?.refType) {\n\t\tcase 'branch':\n\t\t\tif (ref.remote) return 'cloud';\n\t\t\tif (ref.worktree) return webview ? 'gl-worktree' : 'gitlens-worktree';\n\t\t\treturn 'git-branch';\n\t\tcase 'tag':\n\t\t\treturn 'tag';\n\t\tcase 'stash':\n\t\t\treturn 'archive';\n\t\tdefault:\n\t\t\treturn 'git-commit';\n\t}\n}\n"],"mappings":"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"}
@@ -27,12 +27,23 @@ export declare class WatcherRepoChangeEvent {
27
27
  protected readonly _changes: Set<RepositoryChange>;
28
28
  private readonly _refs;
29
29
  private readonly _unnamedRefKinds;
30
+ private readonly _announced;
30
31
  constructor(
31
32
  /** The repository path this event is for */
32
33
  repoPath: string, changes: RepositoryChange[],
33
34
  /** Which refs changed; when omitted, every ref kind in `changes` is unnamed (any ref of that kind may have moved) */
34
- refs?: WatcherRefChanges);
35
+ refs?: WatcherRefChanges,
36
+ /** The kinds of `changes` that come only from core's own announced writes (see {@link announced}) */
37
+ announced?: Iterable<RepositoryChange>);
35
38
  get changes(): ReadonlySet<RepositoryChange>;
39
+ /**
40
+ * The kinds in {@link changes} that come only from core's own writes, which core already announced through
41
+ * `hooks.repository.onChanged` after evicting their caches. A host that handled that announcement can skip them;
42
+ * a kind the watcher or an injected change also reported is not among them.
43
+ */
44
+ get announced(): ReadonlySet<RepositoryChange>;
45
+ /** The kinds in {@link changes} that aren't {@link announced}: what a cache that core already evicted for its write still has to clear */
46
+ getUnannouncedChanges(): RepositoryChange[];
36
47
  /** Full ref names (or ref directories, or pseudo-refs) known to have changed. See {@link WatcherRefChanges.names}. */
37
48
  get refs(): ReadonlySet<string>;
38
49
  /** Ref kinds that changed without a name — any ref of these kinds may have moved */
@@ -66,7 +77,7 @@ export declare class WatcherRepoChangeEvent {
66
77
  changedExclusive(...affected: RepositoryChange[]): boolean;
67
78
  /**
68
79
  * Coalesce: return a new event with all changes and refs from both this and the given set. When `refs` is omitted,
69
- * every ref kind in `changes` counts as unnamed.
80
+ * every ref kind in `changes` counts as unnamed. A kind in `changes` is no longer {@link announced}.
70
81
  */
71
82
  with(changes: RepositoryChange[], refs?: WatcherRefChanges): WatcherRepoChangeEvent;
72
83
  }
@@ -26,7 +26,8 @@ var WatcherRepoChangeEvent = class WatcherRepoChangeEvent {
26
26
  _changes;
27
27
  _refs;
28
28
  _unnamedRefKinds;
29
- constructor(repoPath, changes, refs) {
29
+ _announced;
30
+ constructor(repoPath, changes, refs, announced) {
30
31
  this.repoPath = repoPath;
31
32
  this._changes = new Set(changes);
32
33
  if (refs == null) {
@@ -36,10 +37,23 @@ var WatcherRepoChangeEvent = class WatcherRepoChangeEvent {
36
37
  this._refs = new Set(refs.names);
37
38
  this._unnamedRefKinds = new Set(refs.unnamed);
38
39
  }
40
+ this._announced = announced != null ? new Set(filter(announced, (c) => this._changes.has(c))) : /* @__PURE__ */ new Set();
39
41
  }
40
42
  get changes() {
41
43
  return this._changes;
42
44
  }
45
+ /**
46
+ * The kinds in {@link changes} that come only from core's own writes, which core already announced through
47
+ * `hooks.repository.onChanged` after evicting their caches. A host that handled that announcement can skip them;
48
+ * a kind the watcher or an injected change also reported is not among them.
49
+ */
50
+ get announced() {
51
+ return this._announced;
52
+ }
53
+ /** The kinds in {@link changes} that aren't {@link announced}: what a cache that core already evicted for its write still has to clear */
54
+ getUnannouncedChanges() {
55
+ return this._announced.size ? [...filter(this._changes, (c) => !this._announced.has(c))] : [...this._changes];
56
+ }
43
57
  /** Full ref names (or ref directories, or pseudo-refs) known to have changed. See {@link WatcherRefChanges.names}. */
44
58
  get refs() {
45
59
  return this._refs;
@@ -101,7 +115,7 @@ var WatcherRepoChangeEvent = class WatcherRepoChangeEvent {
101
115
  }
102
116
  /**
103
117
  * Coalesce: return a new event with all changes and refs from both this and the given set. When `refs` is omitted,
104
- * every ref kind in `changes` counts as unnamed.
118
+ * every ref kind in `changes` counts as unnamed. A kind in `changes` is no longer {@link announced}.
105
119
  */
106
120
  with(changes, refs) {
107
121
  const names = [...this._refs];
@@ -114,7 +128,7 @@ var WatcherRepoChangeEvent = class WatcherRepoChangeEvent {
114
128
  return new WatcherRepoChangeEvent(this.repoPath, [...this._changes, ...changes], {
115
129
  names,
116
130
  unnamed
117
- });
131
+ }, filter(this._announced, (c) => !changes.includes(c)));
118
132
  }
119
133
  };
120
134
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"changeEvent.js","names":[],"sources":["../../../../git/src/watching/changeEvent.ts"],"sourcesContent":["import { filter, some } from '@gitlens/utils/iterable.js';\nimport type { RepositoryChange } from '../models/repository.js';\n\n/** The {@link RepositoryChange} kinds that describe ref movement, which an event can attribute to named refs */\nexport type RefChangeKind = 'heads' | 'remotes' | 'tags' | 'stash';\n\nexport interface WatcherRefChanges {\n\t/** Full ref names whose files changed (`refs/heads/main`), plus per-worktree pseudo-refs (`HEAD`, `ORIG_HEAD`). A name may be a ref directory and then covers every ref beneath it. */\n\treadonly names?: Iterable<string>;\n\t/** Ref kinds that changed without a name (packed-refs rewrite, config, shallow/replace, an injected change): any ref of that kind may have moved. */\n\treadonly unnamed?: Iterable<RefChangeKind>;\n}\n\nexport function isRefChangeKind(change: RepositoryChange): change is RefChangeKind {\n\treturn change === 'heads' || change === 'remotes' || change === 'tags' || change === 'stash';\n}\n\n/**\n * The kind of ref a full ref name (or ref directory) belongs to. A pseudo-ref (no `refs/` prefix, e.g. `HEAD`,\n * `ORIG_HEAD`) counts as `heads`; a ref outside the watched namespaces (e.g. `refs/notes/x`) has no kind.\n */\nexport function getRefChangeKind(ref: string): RefChangeKind | undefined {\n\tif (!ref.startsWith('refs/')) return 'heads';\n\tif (ref.startsWith('refs/heads/')) return 'heads';\n\tif (ref.startsWith('refs/remotes/')) return 'remotes';\n\tif (ref.startsWith('refs/tags/')) return 'tags';\n\tif (ref === 'refs/stash') return 'stash';\n\n\treturn undefined;\n}\n\n/**\n * An event describing changes to a repository, produced by the watching pipeline.\n *\n * Changes are coalesced within a debounce window — a single event may represent\n * multiple filesystem changes. Use {@link changed} to test for specific change types,\n * and {@link mayHaveChangedRef} to test whether a specific ref may have moved.\n */\nexport class WatcherRepoChangeEvent {\n\tprotected readonly _changes: Set<RepositoryChange>;\n\tprivate readonly _refs: Set<string>;\n\tprivate readonly _unnamedRefKinds: Set<RefChangeKind>;\n\n\tconstructor(\n\t\t/** The repository path this event is for */\n\t\tpublic readonly repoPath: string,\n\t\tchanges: RepositoryChange[],\n\t\t/** Which refs changed; when omitted, every ref kind in `changes` is unnamed (any ref of that kind may have moved) */\n\t\trefs?: WatcherRefChanges,\n\t) {\n\t\tthis._changes = new Set(changes);\n\t\tif (refs == null) {\n\t\t\tthis._refs = new Set();\n\t\t\tthis._unnamedRefKinds = new Set(filter(changes, isRefChangeKind));\n\t\t} else {\n\t\t\tthis._refs = new Set(refs.names);\n\t\t\tthis._unnamedRefKinds = new Set(refs.unnamed);\n\t\t}\n\t}\n\n\tget changes(): ReadonlySet<RepositoryChange> {\n\t\treturn this._changes;\n\t}\n\n\t/** Full ref names (or ref directories, or pseudo-refs) known to have changed. See {@link WatcherRefChanges.names}. */\n\tget refs(): ReadonlySet<string> {\n\t\treturn this._refs;\n\t}\n\n\t/** Ref kinds that changed without a name — any ref of these kinds may have moved */\n\tget unnamedRefKinds(): ReadonlySet<RefChangeKind> {\n\t\treturn this._unnamedRefKinds;\n\t}\n\n\ttoString(changesOnly: boolean = false): string {\n\t\tconst changeList = [...this._changes].join(', ');\n\t\tconst refCount = this._refs.size;\n\t\tif (changesOnly) return refCount ? `changes=${changeList}, refs=${refCount}` : `changes=${changeList}`;\n\n\t\treturn refCount\n\t\t\t? `{ repoPath: ${this.repoPath}, changes: ${changeList}, refs: ${refCount} }`\n\t\t\t: `{ repoPath: ${this.repoPath}, changes: ${changeList} }`;\n\t}\n\n\t/**\n\t * Test whether the given ref may have moved in this event.\n\t *\n\t * @param ref - A full ref name (`refs/heads/main`) or a pseudo-ref (`HEAD`).\n\t * @returns `false` when the ref's kind didn't change (or the ref is outside the watched kinds); `true` when its kind\n\t * changed without a name, or when the ref itself or a ref directory above it changed. `HEAD` is usually a symref\n\t * to the checked-out branch, so it may have moved whenever any `heads` ref did.\n\t */\n\tmayHaveChangedRef(ref: string): boolean {\n\t\tconst kind = getRefChangeKind(ref);\n\t\tif (kind == null || !this._changes.has(kind)) return false;\n\t\tif (this._unnamedRefKinds.has(kind) || ref === 'HEAD') return true;\n\n\t\treturn findCoveringRefName(this._refs, ref) != null;\n\t}\n\n\t/**\n\t * Test whether any of the specified change types are present in the event.\n\t *\n\t * @param affected - Change types to test for.\n\t * @returns `true` if any of the specified changes are present.\n\t */\n\tchanged(...affected: RepositoryChange[]): boolean {\n\t\treturn some(this._changes, c => affected.includes(c));\n\t}\n\n\t/**\n\t * Test whether the event contains ONLY the specified change types.\n\t *\n\t * `pausedOp` is treated as a union of `cherryPick`, `merge`, `rebase`,\n\t * and `revert` for convenience.\n\t *\n\t * @param affected - Change types to test for.\n\t * @returns `true` if the event contains only the specified changes.\n\t */\n\tchangedExclusive(...affected: RepositoryChange[]): boolean {\n\t\tlet changes = this._changes;\n\n\t\t// When checking for specific paused operation types, also accept the union type\n\t\tif (\n\t\t\taffected.includes('cherryPick') ||\n\t\t\taffected.includes('merge') ||\n\t\t\taffected.includes('rebase') ||\n\t\t\taffected.includes('revert')\n\t\t) {\n\t\t\tif (!affected.includes('pausedOp')) {\n\t\t\t\taffected = [...affected, 'pausedOp'];\n\t\t\t}\n\t\t} else if (affected.includes('pausedOp')) {\n\t\t\t// When checking for the union type exclusively, ignore specific subtypes\n\t\t\tchanges = new Set(changes);\n\t\t\tchanges.delete('cherryPick');\n\t\t\tchanges.delete('merge');\n\t\t\tchanges.delete('rebase');\n\t\t\tchanges.delete('revert');\n\t\t}\n\n\t\tconst intersection = [...filter(changes, c => affected.includes(c))];\n\t\treturn intersection.length === changes.size;\n\t}\n\n\t/**\n\t * Coalesce: return a new event with all changes and refs from both this and the given set. When `refs` is omitted,\n\t * every ref kind in `changes` counts as unnamed.\n\t */\n\twith(changes: RepositoryChange[], refs?: WatcherRefChanges): WatcherRepoChangeEvent {\n\t\tconst names = [...this._refs];\n\t\tconst unnamed = [...this._unnamedRefKinds];\n\t\tif (refs == null) {\n\t\t\tunnamed.push(...filter(changes, isRefChangeKind));\n\t\t} else {\n\t\t\tif (refs.names != null) {\n\t\t\t\tnames.push(...refs.names);\n\t\t\t}\n\t\t\tif (refs.unnamed != null) {\n\t\t\t\tunnamed.push(...refs.unnamed);\n\t\t\t}\n\t\t}\n\n\t\treturn new WatcherRepoChangeEvent(this.repoPath, [...this._changes, ...changes], {\n\t\t\tnames: names,\n\t\t\tunnamed: unnamed,\n\t\t});\n\t}\n}\n\n/**\n * Returns the name in `names` that covers `ref` — `ref` itself, or a ref directory above it (compared on `/`\n * boundaries, so `refs/heads/fe` doesn't cover `refs/heads/feature`) — or `undefined` if none does.\n */\nexport function findCoveringRefName(names: ReadonlySet<string>, ref: string): string | undefined {\n\tif (names.size === 0) return undefined;\n\tif (names.has(ref)) return ref;\n\n\tlet index = ref.lastIndexOf('/');\n\twhile (index > 0) {\n\t\tconst dir = ref.substring(0, index);\n\t\tif (names.has(dir)) return dir;\n\n\t\tindex = ref.lastIndexOf('/', index - 1);\n\t}\n\treturn undefined;\n}\n\n/**\n * An event describing working tree file changes, produced by the working tree pipeline.\n *\n * Paths have already been filtered through the gitignore filter and noise filter.\n */\nexport interface WorkingTreeChangeEvent {\n\treadonly repoPath: string;\n\t/**\n\t * Absolute paths of changed files or directories (post-gitignore filtering). A directory stands for everything\n\t * beneath it. Partial when {@link incomplete}.\n\t */\n\treadonly paths: ReadonlySet<string>;\n\t/**\n\t * `true` when more paths changed than the accumulator retains, so {@link paths} is a partial set and a\n\t * miss does NOT mean the file is unchanged. Consumers testing membership must treat this as a match.\n\t */\n\treadonly incomplete: boolean;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"changeEvent.js","names":[],"sources":["../../../../git/src/watching/changeEvent.ts"],"sourcesContent":["import { filter, some } from '@gitlens/utils/iterable.js';\nimport type { RepositoryChange } from '../models/repository.js';\n\n/** The {@link RepositoryChange} kinds that describe ref movement, which an event can attribute to named refs */\nexport type RefChangeKind = 'heads' | 'remotes' | 'tags' | 'stash';\n\nexport interface WatcherRefChanges {\n\t/** Full ref names whose files changed (`refs/heads/main`), plus per-worktree pseudo-refs (`HEAD`, `ORIG_HEAD`). A name may be a ref directory and then covers every ref beneath it. */\n\treadonly names?: Iterable<string>;\n\t/** Ref kinds that changed without a name (packed-refs rewrite, config, shallow/replace, an injected change): any ref of that kind may have moved. */\n\treadonly unnamed?: Iterable<RefChangeKind>;\n}\n\nexport function isRefChangeKind(change: RepositoryChange): change is RefChangeKind {\n\treturn change === 'heads' || change === 'remotes' || change === 'tags' || change === 'stash';\n}\n\n/**\n * The kind of ref a full ref name (or ref directory) belongs to. A pseudo-ref (no `refs/` prefix, e.g. `HEAD`,\n * `ORIG_HEAD`) counts as `heads`; a ref outside the watched namespaces (e.g. `refs/notes/x`) has no kind.\n */\nexport function getRefChangeKind(ref: string): RefChangeKind | undefined {\n\tif (!ref.startsWith('refs/')) return 'heads';\n\tif (ref.startsWith('refs/heads/')) return 'heads';\n\tif (ref.startsWith('refs/remotes/')) return 'remotes';\n\tif (ref.startsWith('refs/tags/')) return 'tags';\n\tif (ref === 'refs/stash') return 'stash';\n\n\treturn undefined;\n}\n\n/**\n * An event describing changes to a repository, produced by the watching pipeline.\n *\n * Changes are coalesced within a debounce window — a single event may represent\n * multiple filesystem changes. Use {@link changed} to test for specific change types,\n * and {@link mayHaveChangedRef} to test whether a specific ref may have moved.\n */\nexport class WatcherRepoChangeEvent {\n\tprotected readonly _changes: Set<RepositoryChange>;\n\tprivate readonly _refs: Set<string>;\n\tprivate readonly _unnamedRefKinds: Set<RefChangeKind>;\n\tprivate readonly _announced: Set<RepositoryChange>;\n\n\tconstructor(\n\t\t/** The repository path this event is for */\n\t\tpublic readonly repoPath: string,\n\t\tchanges: RepositoryChange[],\n\t\t/** Which refs changed; when omitted, every ref kind in `changes` is unnamed (any ref of that kind may have moved) */\n\t\trefs?: WatcherRefChanges,\n\t\t/** The kinds of `changes` that come only from core's own announced writes (see {@link announced}) */\n\t\tannounced?: Iterable<RepositoryChange>,\n\t) {\n\t\tthis._changes = new Set(changes);\n\t\tif (refs == null) {\n\t\t\tthis._refs = new Set();\n\t\t\tthis._unnamedRefKinds = new Set(filter(changes, isRefChangeKind));\n\t\t} else {\n\t\t\tthis._refs = new Set(refs.names);\n\t\t\tthis._unnamedRefKinds = new Set(refs.unnamed);\n\t\t}\n\t\tthis._announced = announced != null ? new Set(filter(announced, c => this._changes.has(c))) : new Set();\n\t}\n\n\tget changes(): ReadonlySet<RepositoryChange> {\n\t\treturn this._changes;\n\t}\n\n\t/**\n\t * The kinds in {@link changes} that come only from core's own writes, which core already announced through\n\t * `hooks.repository.onChanged` after evicting their caches. A host that handled that announcement can skip them;\n\t * a kind the watcher or an injected change also reported is not among them.\n\t */\n\tget announced(): ReadonlySet<RepositoryChange> {\n\t\treturn this._announced;\n\t}\n\n\t/** The kinds in {@link changes} that aren't {@link announced}: what a cache that core already evicted for its write still has to clear */\n\tgetUnannouncedChanges(): RepositoryChange[] {\n\t\treturn this._announced.size ? [...filter(this._changes, c => !this._announced.has(c))] : [...this._changes];\n\t}\n\n\t/** Full ref names (or ref directories, or pseudo-refs) known to have changed. See {@link WatcherRefChanges.names}. */\n\tget refs(): ReadonlySet<string> {\n\t\treturn this._refs;\n\t}\n\n\t/** Ref kinds that changed without a name — any ref of these kinds may have moved */\n\tget unnamedRefKinds(): ReadonlySet<RefChangeKind> {\n\t\treturn this._unnamedRefKinds;\n\t}\n\n\ttoString(changesOnly: boolean = false): string {\n\t\tconst changeList = [...this._changes].join(', ');\n\t\tconst refCount = this._refs.size;\n\t\tif (changesOnly) return refCount ? `changes=${changeList}, refs=${refCount}` : `changes=${changeList}`;\n\n\t\treturn refCount\n\t\t\t? `{ repoPath: ${this.repoPath}, changes: ${changeList}, refs: ${refCount} }`\n\t\t\t: `{ repoPath: ${this.repoPath}, changes: ${changeList} }`;\n\t}\n\n\t/**\n\t * Test whether the given ref may have moved in this event.\n\t *\n\t * @param ref - A full ref name (`refs/heads/main`) or a pseudo-ref (`HEAD`).\n\t * @returns `false` when the ref's kind didn't change (or the ref is outside the watched kinds); `true` when its kind\n\t * changed without a name, or when the ref itself or a ref directory above it changed. `HEAD` is usually a symref\n\t * to the checked-out branch, so it may have moved whenever any `heads` ref did.\n\t */\n\tmayHaveChangedRef(ref: string): boolean {\n\t\tconst kind = getRefChangeKind(ref);\n\t\tif (kind == null || !this._changes.has(kind)) return false;\n\t\tif (this._unnamedRefKinds.has(kind) || ref === 'HEAD') return true;\n\n\t\treturn findCoveringRefName(this._refs, ref) != null;\n\t}\n\n\t/**\n\t * Test whether any of the specified change types are present in the event.\n\t *\n\t * @param affected - Change types to test for.\n\t * @returns `true` if any of the specified changes are present.\n\t */\n\tchanged(...affected: RepositoryChange[]): boolean {\n\t\treturn some(this._changes, c => affected.includes(c));\n\t}\n\n\t/**\n\t * Test whether the event contains ONLY the specified change types.\n\t *\n\t * `pausedOp` is treated as a union of `cherryPick`, `merge`, `rebase`,\n\t * and `revert` for convenience.\n\t *\n\t * @param affected - Change types to test for.\n\t * @returns `true` if the event contains only the specified changes.\n\t */\n\tchangedExclusive(...affected: RepositoryChange[]): boolean {\n\t\tlet changes = this._changes;\n\n\t\t// When checking for specific paused operation types, also accept the union type\n\t\tif (\n\t\t\taffected.includes('cherryPick') ||\n\t\t\taffected.includes('merge') ||\n\t\t\taffected.includes('rebase') ||\n\t\t\taffected.includes('revert')\n\t\t) {\n\t\t\tif (!affected.includes('pausedOp')) {\n\t\t\t\taffected = [...affected, 'pausedOp'];\n\t\t\t}\n\t\t} else if (affected.includes('pausedOp')) {\n\t\t\t// When checking for the union type exclusively, ignore specific subtypes\n\t\t\tchanges = new Set(changes);\n\t\t\tchanges.delete('cherryPick');\n\t\t\tchanges.delete('merge');\n\t\t\tchanges.delete('rebase');\n\t\t\tchanges.delete('revert');\n\t\t}\n\n\t\tconst intersection = [...filter(changes, c => affected.includes(c))];\n\t\treturn intersection.length === changes.size;\n\t}\n\n\t/**\n\t * Coalesce: return a new event with all changes and refs from both this and the given set. When `refs` is omitted,\n\t * every ref kind in `changes` counts as unnamed. A kind in `changes` is no longer {@link announced}.\n\t */\n\twith(changes: RepositoryChange[], refs?: WatcherRefChanges): WatcherRepoChangeEvent {\n\t\tconst names = [...this._refs];\n\t\tconst unnamed = [...this._unnamedRefKinds];\n\t\tif (refs == null) {\n\t\t\tunnamed.push(...filter(changes, isRefChangeKind));\n\t\t} else {\n\t\t\tif (refs.names != null) {\n\t\t\t\tnames.push(...refs.names);\n\t\t\t}\n\t\t\tif (refs.unnamed != null) {\n\t\t\t\tunnamed.push(...refs.unnamed);\n\t\t\t}\n\t\t}\n\n\t\treturn new WatcherRepoChangeEvent(\n\t\t\tthis.repoPath,\n\t\t\t[...this._changes, ...changes],\n\t\t\t{ names: names, unnamed: unnamed },\n\t\t\tfilter(this._announced, c => !changes.includes(c)),\n\t\t);\n\t}\n}\n\n/**\n * Returns the name in `names` that covers `ref` — `ref` itself, or a ref directory above it (compared on `/`\n * boundaries, so `refs/heads/fe` doesn't cover `refs/heads/feature`) — or `undefined` if none does.\n */\nexport function findCoveringRefName(names: ReadonlySet<string>, ref: string): string | undefined {\n\tif (names.size === 0) return undefined;\n\tif (names.has(ref)) return ref;\n\n\tlet index = ref.lastIndexOf('/');\n\twhile (index > 0) {\n\t\tconst dir = ref.substring(0, index);\n\t\tif (names.has(dir)) return dir;\n\n\t\tindex = ref.lastIndexOf('/', index - 1);\n\t}\n\treturn undefined;\n}\n\n/**\n * An event describing working tree file changes, produced by the working tree pipeline.\n *\n * Paths have already been filtered through the gitignore filter and noise filter.\n */\nexport interface WorkingTreeChangeEvent {\n\treadonly repoPath: string;\n\t/**\n\t * Absolute paths of changed files or directories (post-gitignore filtering). A directory stands for everything\n\t * beneath it. Partial when {@link incomplete}.\n\t */\n\treadonly paths: ReadonlySet<string>;\n\t/**\n\t * `true` when more paths changed than the accumulator retains, so {@link paths} is a partial set and a\n\t * miss does NOT mean the file is unchanged. Consumers testing membership must treat this as a match.\n\t */\n\treadonly incomplete: boolean;\n}\n"],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ import { UnifiedDisposable } from "../../utils/disposable.js";
2
+ import { FileWatchEvent } from "./provider.js";
3
+ import { WatchPollingOptions } from "./watchService.js";
4
+ //#region ../git/src/watching/gitDirPoller.d.ts
5
+ type GitDirStat = Awaited<ReturnType<WatchPollingOptions['stat']>>;
6
+ /** Something the {@link GitDirPoller} reads once per pass */
7
+ export interface PollTarget {
8
+ poll(): Promise<void>;
9
+ }
10
+ /** A file or directory a poll stats, relative to the directory it watches in place of a watcher */
11
+ export interface GitDirProbe {
12
+ /** `/`-separated, relative to the target's base path */
13
+ readonly path: string;
14
+ /** The relative paths a move is reported as, in place of `path` */
15
+ readonly emitAs?: readonly string[];
16
+ }
17
+ /**
18
+ * Runs passes over the poll targets of every watcher that can't be trusted, reading at most 4 targets at once across
19
+ * passes and first readings. A target is read once soon after it is added, so its baseline doesn't wait for the next
20
+ * pass; targets added together are read together.
21
+ *
22
+ * With the default gate (no `isActive`), one timer runs a pass every `intervalMs`, stopped by {@link suspend} and
23
+ * restarted by {@link resume}, which runs a pass at once. With a host's `isActive`, whose changes core can't see, one
24
+ * timer looks at it every `activeCheckMs`: a pass is due once `intervalMs` has gone by since the last one, or at the
25
+ * first look after the gate opens (or after {@link nudge}), so a window that comes back between passes doesn't wait out
26
+ * the rest of one.
27
+ */
28
+ export declare class GitDirPoller implements UnifiedDisposable {
29
+ readonly options: WatchPollingOptions;
30
+ private readonly targets;
31
+ /** Targets added since the last pass and not yet read */
32
+ private readonly unread;
33
+ /** Each target's last read asked for; a target is never read twice at once, so the next waits for it */
34
+ private readonly reading;
35
+ /** Reads waiting for one of the {@link defaultPollConcurrency} slots, which a finished read hands over */
36
+ private readonly waiting;
37
+ /**
38
+ * The stats of the batches (a pass, or first readings) in flight, shared by every target that probes the same path,
39
+ * as the main checkout's root and its common dir do
40
+ */
41
+ private readonly stats;
42
+ private readonly intervalMs;
43
+ private readonly activeCheckMs;
44
+ private timer;
45
+ private running;
46
+ private batches;
47
+ private slotsInUse;
48
+ /** The next look runs a pass whatever the interval says */
49
+ private due;
50
+ private lastPassAt;
51
+ private suspended;
52
+ private disposed;
53
+ constructor(options: WatchPollingOptions);
54
+ [Symbol.dispose](): void;
55
+ dispose(): void;
56
+ get size(): number;
57
+ add(target: PollTarget): void;
58
+ delete(target: PollTarget): void;
59
+ /** Makes the next look a pass, and looks now */
60
+ nudge(): void;
61
+ /** Under the default gate, stops passes (and the timer) until {@link resume}; a host's `isActive` ignores it */
62
+ suspend(): void;
63
+ /** Lifts {@link suspend}, and runs a pass now, so what moved meanwhile is polled rather than at the next look */
64
+ resume(): void;
65
+ /** One look at the gate: runs a pass when one is due, the gate is open and none is in flight */
66
+ tick(): Promise<void>;
67
+ /** Stats `path` once for every target that probes it in the batches in flight */
68
+ stat(path: string): Promise<GitDirStat>;
69
+ /** `path` changed since it was statted, so the next target to probe it in a batch in flight stats it again */
70
+ invalidate(path: string): void;
71
+ private pass;
72
+ private readUnread;
73
+ private readAll;
74
+ /** Reads `target` once any read of it in flight ends, so the reading is fresh and its probes current */
75
+ private read;
76
+ private acquireSlot;
77
+ private releaseSlot;
78
+ private startTimer;
79
+ private stopTimer;
80
+ }
81
+ /**
82
+ * Stands in for a watcher on `basePath`: stats each probe and reports one whose `mtime:size` moved as a `change` of
83
+ * the paths it is emitted as, through the same handler the watcher's own events take. A probe's first read (and a
84
+ * probe new to the set, as after a branch switch) only records; one that was missing and is now present moved. A stat
85
+ * that throws keeps the last reading, so it never counts as a move.
86
+ */
87
+ export declare class GitDirProbeTarget implements PollTarget {
88
+ private readonly basePath;
89
+ private readonly stats;
90
+ private readonly getProbes;
91
+ /** For each path a probe may be emitted as, the paths of the probes emitted as it */
92
+ private readonly probesByEmittedPath;
93
+ private readonly onMoved;
94
+ private readonly signatures;
95
+ /** For each poll whose stats are in flight, the paths {@link forget} cleared meanwhile, which it must not record */
96
+ private readonly forgottenDuringPolls;
97
+ constructor(basePath: string, stats: Pick<GitDirPoller, 'stat' | 'invalidate'>, getProbes: () => Iterable<GitDirProbe>,
98
+ /** For each path a probe may be emitted as, the paths of the probes emitted as it */
99
+ probesByEmittedPath: ReadonlyMap<string, readonly string[]>, onMoved: (event: FileWatchEvent, probe: GitDirProbe) => void);
100
+ poll(): Promise<void>;
101
+ /**
102
+ * The watcher reported `path` itself, so the next poll records the probes it touched (the path, a ref's lock file
103
+ * standing for the ref, the directories above it, and the probes emitted as it, like `logs/HEAD` as `HEAD`, which
104
+ * the watcher never sees) without reporting them again.
105
+ */
106
+ forget(path: string): void;
107
+ private clearSignature;
108
+ private read;
109
+ }
110
+ //#endregion
111
+ //# sourceMappingURL=gitDirPoller.d.ts.map