@gitkraken/core-gitlens 0.24.0 → 0.26.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 (176) hide show
  1. package/CHANGELOG.md +40 -1
  2. package/README.md +23 -15
  3. package/dist/git/errors.d.ts +6 -5
  4. package/dist/git/errors.js +7 -6
  5. package/dist/git/errors.js.map +1 -1
  6. package/dist/git/features.d.ts +1 -1
  7. package/dist/git/features.js +1 -1
  8. package/dist/git/features.js.map +1 -1
  9. package/dist/git/models/remoteProvider.d.ts +4 -1
  10. package/dist/git/models/remoteProvider.js.map +1 -1
  11. package/dist/git/providers/operations.d.ts +15 -0
  12. package/dist/git/providers/provider.d.ts +4 -2
  13. package/dist/git/utils/branch.utils.d.ts +4 -1
  14. package/dist/git/utils/branch.utils.js +5 -2
  15. package/dist/git/utils/branch.utils.js.map +1 -1
  16. package/dist/git/utils/mergeConflicts.utils.js +2 -2
  17. package/dist/git/utils/mergeConflicts.utils.js.map +1 -1
  18. package/dist/git/watching/worktreeSummary.d.ts +15 -3
  19. package/dist/git/watching/worktreeSummary.js +179 -31
  20. package/dist/git/watching/worktreeSummary.js.map +1 -1
  21. package/dist/git-cli/cliGitProvider.d.ts +30 -3
  22. package/dist/git-cli/cliGitProvider.js +102 -40
  23. package/dist/git-cli/cliGitProvider.js.map +1 -1
  24. package/dist/git-cli/exec/git.d.ts +9 -1
  25. package/dist/git-cli/exec/git.js +23 -4
  26. package/dist/git-cli/exec/git.js.map +1 -1
  27. package/dist/git-cli/exec/gitDirResolver.d.ts +26 -0
  28. package/dist/git-cli/exec/gitDirResolver.js +181 -0
  29. package/dist/git-cli/exec/gitDirResolver.js.map +1 -0
  30. package/dist/git-cli/exec/headState.js +3 -3
  31. package/dist/git-cli/exec/headState.js.map +1 -1
  32. package/dist/git-cli/exec/indexRefresh.d.ts +78 -0
  33. package/dist/git-cli/exec/indexRefresh.js +159 -0
  34. package/dist/git-cli/exec/indexRefresh.js.map +1 -0
  35. package/dist/git-cli/providers/branchRemote.js +2 -5
  36. package/dist/git-cli/providers/branchRemote.js.map +1 -1
  37. package/dist/git-cli/providers/branches.js +4 -4
  38. package/dist/git-cli/providers/branches.js.map +1 -1
  39. package/dist/git-cli/providers/config.d.ts +2 -0
  40. package/dist/git-cli/providers/config.js +26 -4
  41. package/dist/git-cli/providers/config.js.map +1 -1
  42. package/dist/git-cli/providers/maintenance.js +1 -1
  43. package/dist/git-cli/providers/operations.d.ts +4 -1
  44. package/dist/git-cli/providers/operations.js +33 -25
  45. package/dist/git-cli/providers/operations.js.map +1 -1
  46. package/dist/git-cli/providers/pausedOperations.d.ts +3 -1
  47. package/dist/git-cli/providers/pausedOperations.js +10 -7
  48. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  49. package/dist/git-cli/providers/refs.js +25 -1
  50. package/dist/git-cli/providers/refs.js.map +1 -1
  51. package/dist/git-cli/providers/staging.js +1 -1
  52. package/dist/git-cli/providers/stash.d.ts +3 -1
  53. package/dist/git-cli/providers/stash.js +8 -5
  54. package/dist/git-cli/providers/stash.js.map +1 -1
  55. package/dist/git-cli/providers/worktrees.d.ts +6 -1
  56. package/dist/git-cli/providers/worktrees.js +6 -2
  57. package/dist/git-cli/providers/worktrees.js.map +1 -1
  58. package/dist/git-cli/service.d.ts +2 -0
  59. package/dist/git-cli/service.js +2 -1
  60. package/dist/git-cli/service.js.map +1 -1
  61. package/dist/ipc/discovery.js +1 -1
  62. package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
  63. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
  64. package/dist/plus/ai/errors.d.ts +4 -1
  65. package/dist/plus/ai/errors.js +4 -0
  66. package/dist/plus/ai/errors.js.map +1 -1
  67. package/dist/plus/ai/providers/mistralProvider.js +1 -1
  68. package/dist/plus/ai/providers/mistralProvider.js.map +1 -1
  69. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +2 -1
  70. package/dist/plus/ai/providers/openAICompatibleProviderBase.js.map +1 -1
  71. package/dist/plus/git-github/api/github.js +12 -13
  72. package/dist/plus/git-github/api/github.js.map +1 -1
  73. package/dist/plus/git-github/api/token.d.ts +2 -0
  74. package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts +1 -1
  75. package/dist/plus/integrations/authentication/cloudIntegrationService.js +6 -1
  76. package/dist/plus/integrations/authentication/cloudIntegrationService.js.map +1 -1
  77. package/dist/plus/integrations/authentication/configuredIntegrationService.js +2 -2
  78. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +18 -5
  79. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js.map +1 -1
  80. package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts +3 -1
  81. package/dist/plus/integrations/authentication/integrationAuthenticationService.js +4 -0
  82. package/dist/plus/integrations/authentication/integrationAuthenticationService.js.map +1 -1
  83. package/dist/plus/integrations/authentication/models.d.ts +2 -0
  84. package/dist/plus/integrations/authentication/models.js +2 -1
  85. package/dist/plus/integrations/authentication/models.js.map +1 -1
  86. package/dist/plus/integrations/authentication/observedAuthenticationProvider.js +1 -1
  87. package/dist/plus/integrations/authentication/rejectedTokenTracker.d.ts +5 -4
  88. package/dist/plus/integrations/authentication/rejectedTokenTracker.js +5 -4
  89. package/dist/plus/integrations/authentication/rejectedTokenTracker.js.map +1 -1
  90. package/dist/plus/integrations/index.d.ts +2 -2
  91. package/dist/plus/integrations/index.js +1 -1
  92. package/dist/plus/integrations/index.js.map +1 -1
  93. package/dist/plus/integrations/integrationService.d.ts +6 -0
  94. package/dist/plus/integrations/integrationService.js +3 -3
  95. package/dist/plus/integrations/integrationService.js.map +1 -1
  96. package/dist/plus/integrations/lite.js +1 -1
  97. package/dist/plus/integrations/manager.d.ts +51 -3
  98. package/dist/plus/integrations/models/gitHostIntegration.d.ts +14 -0
  99. package/dist/plus/integrations/models/gitHostIntegration.js +50 -41
  100. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  101. package/dist/plus/integrations/models/integration.d.ts +27 -5
  102. package/dist/plus/integrations/models/integration.js +57 -15
  103. package/dist/plus/integrations/models/integration.js.map +1 -1
  104. package/dist/plus/integrations/models/issueReads.d.ts +6 -0
  105. package/dist/plus/integrations/models/issuesIntegration.js +11 -11
  106. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
  107. package/dist/plus/integrations/providers/azure/azure.js +2 -2
  108. package/dist/plus/integrations/providers/azureDevOps.js +1 -1
  109. package/dist/plus/integrations/providers/azureDevOpsServer.js +1 -1
  110. package/dist/plus/integrations/providers/bitbucket/bitbucket.js +1 -1
  111. package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -1
  112. package/dist/plus/integrations/providers/bitbucket-server.js +1 -1
  113. package/dist/plus/integrations/providers/bitbucket.js +1 -1
  114. package/dist/plus/integrations/providers/github.js +1 -1
  115. package/dist/plus/integrations/providers/gitlab/gitlab.js +2 -2
  116. package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -1
  117. package/dist/plus/integrations/providers/gitlab.js +1 -1
  118. package/dist/plus/integrations/providers/jira-server.js +2 -2
  119. package/dist/plus/integrations/providers/jira.js +1 -1
  120. package/dist/plus/integrations/providers/linear.js +2 -2
  121. package/dist/plus/integrations/providers/linear.js.map +1 -1
  122. package/dist/plus/integrations/providers/models.js +2 -1
  123. package/dist/plus/integrations/providers/models.js.map +1 -1
  124. package/dist/plus/integrations/providers/providerErrors.js +9 -0
  125. package/dist/plus/integrations/providers/providerErrors.js.map +1 -1
  126. package/dist/plus/integrations/providers/providersApi.js +1 -1
  127. package/dist/plus/integrations/providers/trello.js +1 -1
  128. package/dist/plus/integrations/providers/utils.js +1 -1
  129. package/dist/plus/integrations/reads/counts.js +1 -1
  130. package/dist/plus/integrations/reads/cursors.js +1 -1
  131. package/dist/plus/integrations/reads/drains.d.ts +5 -4
  132. package/dist/plus/integrations/reads/drains.js +28 -8
  133. package/dist/plus/integrations/reads/drains.js.map +1 -1
  134. package/dist/plus/integrations/reads/hierarchy.js +1 -1
  135. package/dist/plus/integrations/reads/issueBatch.d.ts +1 -1
  136. package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
  137. package/dist/plus/integrations/reads/issueTracker.js +1 -1
  138. package/dist/plus/integrations/reads/issues.d.ts +2 -0
  139. package/dist/plus/integrations/reads/issues.js +5 -3
  140. package/dist/plus/integrations/reads/issues.js.map +1 -1
  141. package/dist/plus/integrations/reads/paging.d.ts +5 -6
  142. package/dist/plus/integrations/reads/paging.js +5 -6
  143. package/dist/plus/integrations/reads/paging.js.map +1 -1
  144. package/dist/plus/integrations/reads/pullRequests.d.ts +4 -0
  145. package/dist/plus/integrations/reads/pullRequests.js +4 -2
  146. package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
  147. package/dist/plus/integrations/reads/resolveRepository.js +1 -1
  148. package/dist/plus/integrations/reads/sweeps.js +42 -10
  149. package/dist/plus/integrations/reads/sweeps.js.map +1 -1
  150. package/dist/plus/integrations/results.d.ts +23 -3
  151. package/dist/plus/integrations/results.js.map +1 -1
  152. package/dist/plus/notifications/api.d.ts +20 -0
  153. package/dist/plus/notifications/api.js +89 -0
  154. package/dist/plus/notifications/api.js.map +1 -0
  155. package/dist/plus/notifications/context.d.ts +28 -0
  156. package/dist/plus/notifications/context.js +0 -0
  157. package/dist/plus/notifications/errors.d.ts +13 -0
  158. package/dist/plus/notifications/errors.js +22 -0
  159. package/dist/plus/notifications/errors.js.map +1 -0
  160. package/dist/plus/notifications/models.d.ts +94 -0
  161. package/dist/plus/notifications/models.js +0 -0
  162. package/dist/plus/notifications/notificationsService.d.ts +115 -0
  163. package/dist/plus/notifications/notificationsService.js +381 -0
  164. package/dist/plus/notifications/notificationsService.js.map +1 -0
  165. package/dist/plus/notifications/parse.d.ts +12 -0
  166. package/dist/plus/notifications/parse.js +152 -0
  167. package/dist/plus/notifications/parse.js.map +1 -0
  168. package/dist/plus/notifications/presentation.d.ts +28 -0
  169. package/dist/plus/notifications/presentation.js +55 -0
  170. package/dist/plus/notifications/presentation.js.map +1 -0
  171. package/dist/utils/env/node/exec.d.ts +10 -1
  172. package/dist/utils/env/node/exec.js +41 -4
  173. package/dist/utils/env/node/exec.js.map +1 -1
  174. package/docs/integrations.md +21 -2
  175. package/docs/notifications.md +239 -0
  176. package/package.json +21 -1
@@ -1,5 +1,5 @@
1
1
  //#region ../git/src/features.d.ts
2
- export type GitFeatures = 'git:checkout:pathspec-from-file' | 'git:commit-graph' | 'git:commit-graph:changed-paths' | 'git:fetch:all-config' | 'git:fetch:follow-remote-head' | 'git:fetch:no-write-fetch-head' | 'git:for-each-ref:ahead-behind' | 'git:for-each-ref:worktreePath' | 'git:fsmonitor' | 'git:fsmonitor:linux' | 'git:ignoreRevsFile' | 'git:index:skipHash' | 'git:maintenance' | 'git:maintenance:pack-refs' | 'git:maintenance:start' | 'git:maintenance:start:systemd' | 'git:manyFiles' | 'git:merge-tree:merge-base' | 'git:merge-tree:write-tree' | 'git:patch-id:binary-oids' | 'git:patch-id:verbatim' | 'git:push:force-if-includes' | 'git:rebase:autosquash' | 'git:rev-parse:end-of-options' | 'git:rev-parse:reflog-oldest-old-value' | 'git:signing:ssh' | 'git:signing:x509' | 'git:sparse-index' | 'git:stash:push:pathspecs' | 'git:stash:push:staged' | 'git:stash:push:stdin' | 'git:status:find-renames' | 'git:status:ignored-matching' | 'git:status:porcelain-v2' | 'git:untrackedCache' | 'git:worktree:list:lock-reason' | 'git:worktrees';
2
+ export type GitFeatures = 'git:checkout:pathspec-from-file' | 'git:commit-graph' | 'git:commit-graph:changed-paths' | 'git:fetch:all-config' | 'git:fetch:follow-remote-head' | 'git:fetch:no-write-fetch-head' | 'git:for-each-ref:ahead-behind' | 'git:for-each-ref:worktreePath' | 'git:fsmonitor' | 'git:fsmonitor:linux' | 'git:ignoreRevsFile' | 'git:index:skipHash' | 'git:maintenance' | 'git:maintenance:pack-refs' | 'git:maintenance:start' | 'git:maintenance:start:systemd' | 'git:manyFiles' | 'git:merge-tree:trees' | 'git:merge-tree:write-tree' | 'git:patch-id:binary-oids' | 'git:patch-id:verbatim' | 'git:push:force-if-includes' | 'git:rebase:autosquash' | 'git:rev-parse:end-of-options' | 'git:rev-parse:reflog-oldest-old-value' | 'git:signing:ssh' | 'git:signing:x509' | 'git:sparse-index' | 'git:stash:push:pathspecs' | 'git:stash:push:staged' | 'git:stash:push:stdin' | 'git:status:find-renames' | 'git:status:ignored-matching' | 'git:status:porcelain-v2' | 'git:untrackedCache' | 'git:worktree:list:lock-reason' | 'git:worktrees';
3
3
  type ExtractPrefix<T> = T extends `${infer Prefix}:${infer Rest}` ? Rest extends `${infer SubPrefix}:${string}` ? T | `${Prefix}:${SubPrefix}` | Prefix : T | Prefix : never;
4
4
  export type GitFeatureOrPrefix = ExtractPrefix<GitFeatures>;
5
5
  export type FilteredGitFeatures<T extends GitFeatureOrPrefix> = T extends GitFeatures ? T : Extract<GitFeatures, T | `${T}:${string}`>;
@@ -18,7 +18,7 @@ const gitFeaturesByVersion = /* @__PURE__ */ new Map([
18
18
  ["git:maintenance:start", "2.31"],
19
19
  ["git:maintenance:start:systemd", "2.34"],
20
20
  ["git:manyFiles", "2.24"],
21
- ["git:merge-tree:merge-base", "2.40"],
21
+ ["git:merge-tree:trees", "2.45"],
22
22
  ["git:merge-tree:write-tree", "2.38"],
23
23
  ["git:patch-id:binary-oids", "2.39"],
24
24
  ["git:patch-id:verbatim", "2.39"],
@@ -1 +1 @@
1
- {"version":3,"file":"features.js","names":[],"sources":["../../../git/src/features.ts"],"sourcesContent":["// GitFeature's must start with `git:` to be recognized in all usages\nexport type GitFeatures =\n\t| 'git:checkout:pathspec-from-file'\n\t| 'git:commit-graph'\n\t| 'git:commit-graph:changed-paths'\n\t| 'git:fetch:all-config'\n\t| 'git:fetch:follow-remote-head'\n\t| 'git:fetch:no-write-fetch-head'\n\t| 'git:for-each-ref:ahead-behind'\n\t| 'git:for-each-ref:worktreePath'\n\t| 'git:fsmonitor'\n\t| 'git:fsmonitor:linux'\n\t| 'git:ignoreRevsFile'\n\t| 'git:index:skipHash'\n\t| 'git:maintenance'\n\t| 'git:maintenance:pack-refs'\n\t| 'git:maintenance:start'\n\t| 'git:maintenance:start:systemd'\n\t| 'git:manyFiles'\n\t| 'git:merge-tree:merge-base'\n\t| 'git:merge-tree:write-tree'\n\t| 'git:patch-id:binary-oids'\n\t| 'git:patch-id:verbatim'\n\t| 'git:push:force-if-includes'\n\t| 'git:rebase:autosquash'\n\t| 'git:rev-parse:end-of-options'\n\t| 'git:rev-parse:reflog-oldest-old-value'\n\t| 'git:signing:ssh'\n\t| 'git:signing:x509'\n\t| 'git:sparse-index'\n\t| 'git:stash:push:pathspecs'\n\t| 'git:stash:push:staged'\n\t| 'git:stash:push:stdin'\n\t| 'git:status:find-renames'\n\t| 'git:status:ignored-matching'\n\t| 'git:status:porcelain-v2'\n\t| 'git:untrackedCache'\n\t| 'git:worktree:list:lock-reason'\n\t| 'git:worktrees';\n\ntype ExtractPrefix<T> = T extends `${infer Prefix}:${infer Rest}`\n\t? Rest extends `${infer SubPrefix}:${string}`\n\t\t? T | `${Prefix}:${SubPrefix}` | Prefix\n\t\t: T | Prefix\n\t: never;\n\nexport type GitFeatureOrPrefix = ExtractPrefix<GitFeatures>;\nexport type FilteredGitFeatures<T extends GitFeatureOrPrefix> = T extends GitFeatures\n\t? T\n\t: Extract<GitFeatures, T | `${T}:${string}`>;\n\nexport const gitMinimumVersion = '2.7.2';\nexport const gitFeaturesByVersion = new Map<GitFeatures, string>([\n\t['git:checkout:pathspec-from-file', '2.26'],\n\t// 2.24 is when git READS the commit-graph file by default (core.commitGraph on); writing it for\n\t// older gits would be dead weight.\n\t['git:commit-graph', '2.24'],\n\t// Changed-path Bloom filters (`--changed-paths`), the v2 filter format — pre-2.31 shipped Bloom filters\n\t// with real correctness bugs (bad results for merge commits), so 2.31 is the safe floor to write them.\n\t['git:commit-graph:changed-paths', '2.31'],\n\t// A bare `fetch` reads every remote when `fetch.all` is set\n\t['git:fetch:all-config', '2.44'],\n\t// A fetch using a remote's configured refspecs creates its missing `refs/remotes/<remote>/HEAD`\n\t// (`remote.<name>.followRemoteHEAD`, default `create`)\n\t['git:fetch:follow-remote-head', '2.48'],\n\t['git:fetch:no-write-fetch-head', '2.29'],\n\t// `%(ahead-behind:<commit>)` in for-each-ref formats\n\t['git:for-each-ref:ahead-behind', '2.41'],\n\t['git:for-each-ref:worktreePath', '2.23'],\n\t// `core.fsmonitor=true` selects the built-in FSMonitor daemon (accepting a bool rather than only a\n\t// hook path). This 2.37 floor is the Windows + macOS one.\n\t['git:fsmonitor', '2.37'],\n\t// Linux got its own FSMonitor backend (inotify) only in 2.55, hence a separate floor. Note the backend\n\t// places a watch on EVERY directory, so a large repo can exhaust `fs.inotify.max_user_watches` and the\n\t// daemon fails at runtime even on a new enough git — the apply path must still probe, not just gate.\n\t['git:fsmonitor:linux', '2.55'],\n\t['git:ignoreRevsFile', '2.23'],\n\t// `index.skipHash` (skip the trailing index checksum for faster writes); part of `feature.manyFiles`.\n\t['git:index:skipHash', '2.40'],\n\t// `git maintenance run --task=…`. The `maintenance` builtin + `commit-graph`/`gc` tasks are 2.29, but\n\t// the loose-objects + incremental-repack tasks the auto tier uses landed in 2.30 (and `core.multiPackIndex`\n\t// is default-on from 2.30, so no separate midx config write is needed) — 2.30 is the safe floor.\n\t['git:maintenance', '2.30'],\n\t// The pack-refs maintenance task landed one release after the maintenance builtin.\n\t['git:maintenance:pack-refs', '2.31'],\n\t// `git maintenance start` — the subcommands exist from 2.30 (cron only); launchctl (macOS) + schtasks\n\t// (Windows) scheduling arrived in 2.31, so 2.31 is the cross-platform-safe floor.\n\t['git:maintenance:start', '2.31'],\n\t// `git maintenance start` systemd-timer scheduling. On Linux, 2.31–2.33 is cron-only and modern distros\n\t// often ship without cron (scheduling then silently fails); the systemd fallback arrived in 2.34.\n\t['git:maintenance:start:systemd', '2.34'],\n\t// `feature.manyFiles` umbrella (index v4 + untracked cache + skipHash where available).\n\t['git:manyFiles', '2.24'],\n\t['git:merge-tree:merge-base', '2.40'],\n\t// `merge-tree --write-tree` mode with `-z`/`--name-only`/`--no-messages`; the older trivial mode can't check conflicts\n\t['git:merge-tree:write-tree', '2.38'],\n\t// `patch-id` hashes a binary change through its blob ids; older ones hash the diff's text, so need `--binary` data\n\t['git:patch-id:binary-oids', '2.39'],\n\t// `patch-id --verbatim`: hashes whitespace and file-mode header lines instead of normalizing them away\n\t['git:patch-id:verbatim', '2.39'],\n\t['git:push:force-if-includes', '2.30.0'],\n\t// `--autosquash` WITHOUT `-i` (folding `fixup!`/`squash!` commits into a plain/automatic rebase).\n\t// Interactive rebases support autosquash on every git version GitLens supports, so this floor only\n\t// gates the non-interactive path.\n\t['git:rebase:autosquash', '2.44'],\n\t['git:rev-parse:end-of-options', '2.30'],\n\t// `<ref>@{<n>}` for a reflog of exactly n entries names the value before the oldest one, refusing only a null one\n\t// (the entry that created the ref); older ones refuse it either way\n\t['git:rev-parse:reflog-oldest-old-value', '2.31'],\n\t['git:signing:ssh', '2.34.0'],\n\t['git:signing:x509', '2.19.0'],\n\t// Sparse-index support debuted earlier, but 2.33 shipped a corruption fix and 2.34 broadened command\n\t// support. Use 2.34 as the conservative floor before offering a repository mutation.\n\t['git:sparse-index', '2.34'],\n\t['git:stash:push:pathspecs', '2.13.2'],\n\t['git:stash:push:staged', '2.35.0'],\n\t['git:stash:push:stdin', '2.30.0'],\n\t['git:status:find-renames', '2.18'],\n\t// `status --ignored=matching`: an ignored folder is one entry, without a walk of what is inside it\n\t['git:status:ignored-matching', '2.16'],\n\t['git:status:porcelain-v2', '2.11'],\n\t// `core.untrackedCache=true` (repo-local cache of untracked-file scans — the auto-tier config lever).\n\t['git:untrackedCache', '2.8'],\n\t// `worktree list --porcelain` prints a lock's reason (`locked <reason>`); older ones print a bare `locked`\n\t['git:worktree:list:lock-reason', '2.31'],\n\t['git:worktrees', '2.17.0'],\n]);\n"],"mappings":";AAmDA,MAAa,oBAAoB;AACjC,MAAa,uCAAuB,IAAI,IAAyB;CAChE,CAAC,mCAAmC,MAAM;CAG1C,CAAC,oBAAoB,MAAM;CAG3B,CAAC,kCAAkC,MAAM;CAEzC,CAAC,wBAAwB,MAAM;CAG/B,CAAC,gCAAgC,MAAM;CACvC,CAAC,iCAAiC,MAAM;CAExC,CAAC,iCAAiC,MAAM;CACxC,CAAC,iCAAiC,MAAM;CAGxC,CAAC,iBAAiB,MAAM;CAIxB,CAAC,uBAAuB,MAAM;CAC9B,CAAC,sBAAsB,MAAM;CAE7B,CAAC,sBAAsB,MAAM;CAI7B,CAAC,mBAAmB,MAAM;CAE1B,CAAC,6BAA6B,MAAM;CAGpC,CAAC,yBAAyB,MAAM;CAGhC,CAAC,iCAAiC,MAAM;CAExC,CAAC,iBAAiB,MAAM;CACxB,CAAC,6BAA6B,MAAM;CAEpC,CAAC,6BAA6B,MAAM;CAEpC,CAAC,4BAA4B,MAAM;CAEnC,CAAC,yBAAyB,MAAM;CAChC,CAAC,8BAA8B,QAAQ;CAIvC,CAAC,yBAAyB,MAAM;CAChC,CAAC,gCAAgC,MAAM;CAGvC,CAAC,yCAAyC,MAAM;CAChD,CAAC,mBAAmB,QAAQ;CAC5B,CAAC,oBAAoB,QAAQ;CAG7B,CAAC,oBAAoB,MAAM;CAC3B,CAAC,4BAA4B,QAAQ;CACrC,CAAC,yBAAyB,QAAQ;CAClC,CAAC,wBAAwB,QAAQ;CACjC,CAAC,2BAA2B,MAAM;CAElC,CAAC,+BAA+B,MAAM;CACtC,CAAC,2BAA2B,MAAM;CAElC,CAAC,sBAAsB,KAAK;CAE5B,CAAC,iCAAiC,MAAM;CACxC,CAAC,iBAAiB,QAAQ;AAC3B,CAAC"}
1
+ {"version":3,"file":"features.js","names":[],"sources":["../../../git/src/features.ts"],"sourcesContent":["// GitFeature's must start with `git:` to be recognized in all usages\nexport type GitFeatures =\n\t| 'git:checkout:pathspec-from-file'\n\t| 'git:commit-graph'\n\t| 'git:commit-graph:changed-paths'\n\t| 'git:fetch:all-config'\n\t| 'git:fetch:follow-remote-head'\n\t| 'git:fetch:no-write-fetch-head'\n\t| 'git:for-each-ref:ahead-behind'\n\t| 'git:for-each-ref:worktreePath'\n\t| 'git:fsmonitor'\n\t| 'git:fsmonitor:linux'\n\t| 'git:ignoreRevsFile'\n\t| 'git:index:skipHash'\n\t| 'git:maintenance'\n\t| 'git:maintenance:pack-refs'\n\t| 'git:maintenance:start'\n\t| 'git:maintenance:start:systemd'\n\t| 'git:manyFiles'\n\t| 'git:merge-tree:trees'\n\t| 'git:merge-tree:write-tree'\n\t| 'git:patch-id:binary-oids'\n\t| 'git:patch-id:verbatim'\n\t| 'git:push:force-if-includes'\n\t| 'git:rebase:autosquash'\n\t| 'git:rev-parse:end-of-options'\n\t| 'git:rev-parse:reflog-oldest-old-value'\n\t| 'git:signing:ssh'\n\t| 'git:signing:x509'\n\t| 'git:sparse-index'\n\t| 'git:stash:push:pathspecs'\n\t| 'git:stash:push:staged'\n\t| 'git:stash:push:stdin'\n\t| 'git:status:find-renames'\n\t| 'git:status:ignored-matching'\n\t| 'git:status:porcelain-v2'\n\t| 'git:untrackedCache'\n\t| 'git:worktree:list:lock-reason'\n\t| 'git:worktrees';\n\ntype ExtractPrefix<T> = T extends `${infer Prefix}:${infer Rest}`\n\t? Rest extends `${infer SubPrefix}:${string}`\n\t\t? T | `${Prefix}:${SubPrefix}` | Prefix\n\t\t: T | Prefix\n\t: never;\n\nexport type GitFeatureOrPrefix = ExtractPrefix<GitFeatures>;\nexport type FilteredGitFeatures<T extends GitFeatureOrPrefix> = T extends GitFeatures\n\t? T\n\t: Extract<GitFeatures, T | `${T}:${string}`>;\n\nexport const gitMinimumVersion = '2.7.2';\nexport const gitFeaturesByVersion = new Map<GitFeatures, string>([\n\t['git:checkout:pathspec-from-file', '2.26'],\n\t// 2.24 is when git READS the commit-graph file by default (core.commitGraph on); writing it for\n\t// older gits would be dead weight.\n\t['git:commit-graph', '2.24'],\n\t// Changed-path Bloom filters (`--changed-paths`), the v2 filter format — pre-2.31 shipped Bloom filters\n\t// with real correctness bugs (bad results for merge commits), so 2.31 is the safe floor to write them.\n\t['git:commit-graph:changed-paths', '2.31'],\n\t// A bare `fetch` reads every remote when `fetch.all` is set\n\t['git:fetch:all-config', '2.44'],\n\t// A fetch using a remote's configured refspecs creates its missing `refs/remotes/<remote>/HEAD`\n\t// (`remote.<name>.followRemoteHEAD`, default `create`)\n\t['git:fetch:follow-remote-head', '2.48'],\n\t['git:fetch:no-write-fetch-head', '2.29'],\n\t// `%(ahead-behind:<commit>)` in for-each-ref formats\n\t['git:for-each-ref:ahead-behind', '2.41'],\n\t['git:for-each-ref:worktreePath', '2.23'],\n\t// `core.fsmonitor=true` selects the built-in FSMonitor daemon (accepting a bool rather than only a\n\t// hook path). This 2.37 floor is the Windows + macOS one.\n\t['git:fsmonitor', '2.37'],\n\t// Linux got its own FSMonitor backend (inotify) only in 2.55, hence a separate floor. Note the backend\n\t// places a watch on EVERY directory, so a large repo can exhaust `fs.inotify.max_user_watches` and the\n\t// daemon fails at runtime even on a new enough git — the apply path must still probe, not just gate.\n\t['git:fsmonitor:linux', '2.55'],\n\t['git:ignoreRevsFile', '2.23'],\n\t// `index.skipHash` (skip the trailing index checksum for faster writes); part of `feature.manyFiles`.\n\t['git:index:skipHash', '2.40'],\n\t// `git maintenance run --task=…`. The `maintenance` builtin + `commit-graph`/`gc` tasks are 2.29, but\n\t// the loose-objects + incremental-repack tasks the auto tier uses landed in 2.30 (and `core.multiPackIndex`\n\t// is default-on from 2.30, so no separate midx config write is needed) — 2.30 is the safe floor.\n\t['git:maintenance', '2.30'],\n\t// The pack-refs maintenance task landed one release after the maintenance builtin.\n\t['git:maintenance:pack-refs', '2.31'],\n\t// `git maintenance start` — the subcommands exist from 2.30 (cron only); launchctl (macOS) + schtasks\n\t// (Windows) scheduling arrived in 2.31, so 2.31 is the cross-platform-safe floor.\n\t['git:maintenance:start', '2.31'],\n\t// `git maintenance start` systemd-timer scheduling. On Linux, 2.31–2.33 is cron-only and modern distros\n\t// often ship without cron (scheduling then silently fails); the systemd fallback arrived in 2.34.\n\t['git:maintenance:start:systemd', '2.34'],\n\t// `feature.manyFiles` umbrella (index v4 + untracked cache + skipHash where available).\n\t['git:manyFiles', '2.24'],\n\t// `merge-tree --write-tree --merge-base=<base> <tree> <commit>`: `--merge-base` arrived in 2.40, but plain trees as merge\n\t// inputs only in 2.45 — older git rejects a tree with \"expected commit type\"\n\t['git:merge-tree:trees', '2.45'],\n\t// `merge-tree --write-tree` mode with `-z`/`--name-only`/`--no-messages`; the older trivial mode can't check conflicts\n\t['git:merge-tree:write-tree', '2.38'],\n\t// `patch-id` hashes a binary change through its blob ids; older ones hash the diff's text, so need `--binary` data\n\t['git:patch-id:binary-oids', '2.39'],\n\t// `patch-id --verbatim`: hashes whitespace and file-mode header lines instead of normalizing them away\n\t['git:patch-id:verbatim', '2.39'],\n\t['git:push:force-if-includes', '2.30.0'],\n\t// `--autosquash` WITHOUT `-i` (folding `fixup!`/`squash!` commits into a plain/automatic rebase).\n\t// Interactive rebases support autosquash on every git version GitLens supports, so this floor only\n\t// gates the non-interactive path.\n\t['git:rebase:autosquash', '2.44'],\n\t['git:rev-parse:end-of-options', '2.30'],\n\t// `<ref>@{<n>}` for a reflog of exactly n entries names the value before the oldest one, refusing only a null one\n\t// (the entry that created the ref); older ones refuse it either way\n\t['git:rev-parse:reflog-oldest-old-value', '2.31'],\n\t['git:signing:ssh', '2.34.0'],\n\t['git:signing:x509', '2.19.0'],\n\t// Sparse-index support debuted earlier, but 2.33 shipped a corruption fix and 2.34 broadened command\n\t// support. Use 2.34 as the conservative floor before offering a repository mutation.\n\t['git:sparse-index', '2.34'],\n\t['git:stash:push:pathspecs', '2.13.2'],\n\t['git:stash:push:staged', '2.35.0'],\n\t['git:stash:push:stdin', '2.30.0'],\n\t['git:status:find-renames', '2.18'],\n\t// `status --ignored=matching`: an ignored folder is one entry, without a walk of what is inside it\n\t['git:status:ignored-matching', '2.16'],\n\t['git:status:porcelain-v2', '2.11'],\n\t// `core.untrackedCache=true` (repo-local cache of untracked-file scans — the auto-tier config lever).\n\t['git:untrackedCache', '2.8'],\n\t// `worktree list --porcelain` prints a lock's reason (`locked <reason>`); older ones print a bare `locked`\n\t['git:worktree:list:lock-reason', '2.31'],\n\t['git:worktrees', '2.17.0'],\n]);\n"],"mappings":";AAmDA,MAAa,oBAAoB;AACjC,MAAa,uCAAuB,IAAI,IAAyB;CAChE,CAAC,mCAAmC,MAAM;CAG1C,CAAC,oBAAoB,MAAM;CAG3B,CAAC,kCAAkC,MAAM;CAEzC,CAAC,wBAAwB,MAAM;CAG/B,CAAC,gCAAgC,MAAM;CACvC,CAAC,iCAAiC,MAAM;CAExC,CAAC,iCAAiC,MAAM;CACxC,CAAC,iCAAiC,MAAM;CAGxC,CAAC,iBAAiB,MAAM;CAIxB,CAAC,uBAAuB,MAAM;CAC9B,CAAC,sBAAsB,MAAM;CAE7B,CAAC,sBAAsB,MAAM;CAI7B,CAAC,mBAAmB,MAAM;CAE1B,CAAC,6BAA6B,MAAM;CAGpC,CAAC,yBAAyB,MAAM;CAGhC,CAAC,iCAAiC,MAAM;CAExC,CAAC,iBAAiB,MAAM;CAGxB,CAAC,wBAAwB,MAAM;CAE/B,CAAC,6BAA6B,MAAM;CAEpC,CAAC,4BAA4B,MAAM;CAEnC,CAAC,yBAAyB,MAAM;CAChC,CAAC,8BAA8B,QAAQ;CAIvC,CAAC,yBAAyB,MAAM;CAChC,CAAC,gCAAgC,MAAM;CAGvC,CAAC,yCAAyC,MAAM;CAChD,CAAC,mBAAmB,QAAQ;CAC5B,CAAC,oBAAoB,QAAQ;CAG7B,CAAC,oBAAoB,MAAM;CAC3B,CAAC,4BAA4B,QAAQ;CACrC,CAAC,yBAAyB,QAAQ;CAClC,CAAC,wBAAwB,QAAQ;CACjC,CAAC,2BAA2B,MAAM;CAElC,CAAC,+BAA+B,MAAM;CACtC,CAAC,2BAA2B,MAAM;CAElC,CAAC,sBAAsB,KAAK;CAE5B,CAAC,iCAAiC,MAAM;CACxC,CAAC,iBAAiB,QAAQ;AAC3B,CAAC"}
@@ -16,7 +16,10 @@ export interface ProviderReference {
16
16
  export interface Provider extends ProviderReference {
17
17
  getIgnoreSSLErrors(): boolean | 'force';
18
18
  reauthenticate(): Promise<void>;
19
- trackRequestException(): void;
19
+ /** Spends a strike toward disconnecting the connection `connectionId` names, or the primary when omitted. */
20
+ trackRequestException(options?: {
21
+ connectionId?: string;
22
+ }): void;
20
23
  }
21
24
  export type RemoteProviderId = 'azure-devops' | 'bitbucket' | 'bitbucket-server' | 'custom' | 'gerrit' | 'gitea' | 'github' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab' | 'google-source';
22
25
  export interface RemoteProviderSupportedFeatures {
@@ -1 +1 @@
1
- {"version":3,"file":"remoteProvider.js","names":[],"sources":["../../../../git/src/models/remoteProvider.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport { memoize } from '@gitlens/utils/decorators/memoize.js';\nimport { encodeUrl } from '@gitlens/utils/encoding.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport type { RemoteProviderContext } from '../context.js';\nimport { isSha } from '../utils/revision.utils.js';\nimport type { AutolinkReference, DynamicAutolinkReference } from './autolink.js';\nimport type { LineRange } from './lineRange.js';\nimport type { CreatePullRequestRemoteResource, RemoteResource } from './remoteResource.js';\nimport { RemoteResourceType } from './remoteResource.js';\nimport type { GkProviderId } from './repositoryIdentities.js';\nimport type { ResourceDescriptor } from './resourceDescriptor.js';\nimport type { GitRevisionRangeNotation } from './revision.js';\n\nexport interface ProviderReference {\n\treadonly id: string;\n\treadonly name: string;\n\treadonly domain: string;\n\treadonly icon: string;\n}\n\nexport interface Provider extends ProviderReference {\n\tgetIgnoreSSLErrors(): boolean | 'force';\n\treauthenticate(): Promise<void>;\n\ttrackRequestException(): void;\n}\n\nexport type RemoteProviderId =\n\t| 'azure-devops'\n\t| 'bitbucket'\n\t| 'bitbucket-server'\n\t| 'custom'\n\t| 'gerrit'\n\t| 'gitea'\n\t| 'github'\n\t| 'cloud-github-enterprise' // TODO@eamodio this shouldn't really be here, since it's not a valid remote provider id\n\t| 'cloud-gitlab-self-hosted' // TODO@eamodio this shouldn't really be here, since it's not a valid remote provider id\n\t| 'gitlab'\n\t| 'google-source';\n\nexport interface RemoteProviderSupportedFeatures {\n\tcreatePullRequestWithDetails?: boolean;\n}\n\n/** A function that matches a remote URL to a remote provider instance */\nexport type RemoteProviderMatcher = (\n\turl: string,\n\tdomain: string,\n\tpath: string,\n\tscheme: string | undefined,\n) => RemoteProvider | undefined;\n\nexport interface ParsedRemoteFileUri {\n\tstartLine?: number;\n\tendLine?: number;\n\tcandidates: ParsedRemoteFileCandidate[];\n}\n\nexport type ParsedRemoteFileCandidate =\n\t| { readonly type: 'sha'; readonly filePath: string; readonly rev: string }\n\t| { readonly type: 'shortSha'; readonly filePath: string; readonly rev: string }\n\t| { readonly type: 'branches'; readonly possibleBranches: ReadonlyMap<string, string> }\n\t| { readonly type: 'tags'; readonly possibleTags: ReadonlyMap<string, string> }\n\t| { readonly type: 'pathOnly'; readonly filePath: string };\n\nexport interface RemotesUrlsConfig {\n\treadonly repository: string;\n\treadonly branches: string;\n\treadonly branch: string;\n\treadonly commit: string;\n\treadonly comparison?: string;\n\treadonly createPullRequest?: string;\n\treadonly file: string;\n\treadonly fileInBranch: string;\n\treadonly fileInCommit: string;\n\treadonly fileLine: string;\n\treadonly fileRange: string;\n\treadonly avatar?: string;\n}\n\nexport abstract class RemoteProvider<T extends ResourceDescriptor = ResourceDescriptor> implements ProviderReference {\n\tprotected readonly _name: string | undefined;\n\n\tprotected readonly context: RemoteProviderContext | undefined;\n\n\tconstructor(\n\t\tpublic readonly domain: string,\n\t\tpublic readonly path: string,\n\t\tpublic readonly protocol: string = 'https',\n\t\tname?: string,\n\t\tpublic readonly custom: boolean = false,\n\t\tcontext?: RemoteProviderContext,\n\t) {\n\t\tthis._name = name;\n\t\tthis.context = context;\n\t}\n\n\tprotected abstract get issueLinkPattern(): string;\n\n\tget autolinks(): (AutolinkReference | DynamicAutolinkReference)[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\turl: this.issueLinkPattern,\n\t\t\t\tprefix: '',\n\t\t\t\ttitle: l10n.t('Open Issue #{number} on {provider}', { number: '<num>', provider: this.name }),\n\t\t\t\treferenceType: 'branch',\n\t\t\t\talphanumeric: false,\n\t\t\t\tignoreCase: true,\n\t\t\t},\n\t\t];\n\t}\n\n\tget avatarUri(): Uri | undefined {\n\t\treturn undefined;\n\t}\n\n\tget displayPath(): string {\n\t\treturn this.path;\n\t}\n\n\tget icon(): string {\n\t\treturn 'remote';\n\t}\n\n\tget owner(): string | undefined {\n\t\treturn this.splitPath(this.path)[0];\n\t}\n\n\t@memoize()\n\tget remoteKey(): string {\n\t\treturn this.domain ? `${this.domain}/${this.path}` : this.path;\n\t}\n\n\tget repoDesc(): T {\n\t\treturn { owner: this.owner, name: this.repoName } as unknown as T;\n\t}\n\n\tget providerDesc():\n\t\t| {\n\t\t\t\tid: GkProviderId;\n\t\t\t\trepoDomain: string;\n\t\t\t\trepoName: string;\n\t\t\t\trepoOwnerDomain?: string;\n\t\t }\n\t\t| undefined {\n\t\tif (this.gkProviderId == null || this.owner == null || this.repoName == null) return undefined;\n\n\t\treturn { id: this.gkProviderId, repoDomain: this.owner, repoName: this.repoName };\n\t}\n\n\tget repoName(): string | undefined {\n\t\treturn this.splitPath(this.path)[1];\n\t}\n\n\tabstract get id(): RemoteProviderId;\n\tabstract get gkProviderId(): GkProviderId | undefined;\n\tabstract get name(): string;\n\tget supportedFeatures(): RemoteProviderSupportedFeatures {\n\t\treturn {};\n\t}\n\n\turl(resource: RemoteResource): Promise<string | undefined> | string | undefined {\n\t\tswitch (resource.type) {\n\t\t\tcase RemoteResourceType.Branch:\n\t\t\t\treturn this.getUrlForBranch(resource.branch);\n\t\t\tcase RemoteResourceType.Branches:\n\t\t\t\treturn this.getUrlForBranches();\n\t\t\tcase RemoteResourceType.Commit:\n\t\t\t\treturn this.getUrlForCommit(resource.sha);\n\t\t\tcase RemoteResourceType.Comparison:\n\t\t\t\treturn this.getUrlForComparison(resource.base, resource.head, resource.notation ?? '...');\n\t\t\tcase RemoteResourceType.CreatePullRequest:\n\t\t\t\treturn this.getUrlForCreatePullRequest(resource);\n\t\t\tcase RemoteResourceType.File:\n\t\t\t\treturn this.getUrlForFile(\n\t\t\t\t\tresource.fileName,\n\t\t\t\t\tresource.branchOrTag ?? undefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\tresource.range,\n\t\t\t\t);\n\t\t\tcase RemoteResourceType.Repo:\n\t\t\t\treturn this.getUrlForRepository();\n\t\t\tcase RemoteResourceType.Revision:\n\t\t\t\treturn this.getUrlForFile(\n\t\t\t\t\tresource.fileName,\n\t\t\t\t\tresource.branchOrTag ?? undefined,\n\t\t\t\t\tresource.sha ?? undefined,\n\t\t\t\t\tresource.range,\n\t\t\t\t);\n\t\t\t// TODO@axosoft-ramint needs to be implemented to support remote urls for tags\n\t\t\t// case RemoteResourceType.Tag:\n\t\t\t// \treturn this.getUrlForTag(resource.tag);\n\t\t\tdefault:\n\t\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tparseRemoteFileUri?(_uri: Uri): ParsedRemoteFileUri | undefined;\n\n\tprotected get baseUrl(): string {\n\t\treturn this.getRepoBaseUrl(this.path);\n\t}\n\n\tprotected getRepoBaseUrl(path: string): string {\n\t\treturn `${this.protocol}://${this.domain}/${path}`;\n\t}\n\n\tprotected formatName(name: string): string {\n\t\tif (this._name != null) {\n\t\t\treturn this._name;\n\t\t}\n\t\treturn `${name}${this.custom ? ` (${this.domain})` : ''}`;\n\t}\n\n\tprotected splitPath(path: string): [string, string] {\n\t\tconst index = path.indexOf('/');\n\t\treturn [path.substring(0, index), path.substring(index + 1)];\n\t}\n\n\tprotected abstract getUrlForBranch(branch: string): string;\n\n\tprotected abstract getUrlForBranches(): string;\n\n\tprotected abstract getUrlForCommit(sha: string): string;\n\n\tprotected abstract getUrlForComparison(\n\t\tbase: string,\n\t\thead: string,\n\t\tnotation: GitRevisionRangeNotation,\n\t): string | undefined;\n\n\tprotected abstract getUrlForCreatePullRequest(\n\t\tresource: CreatePullRequestRemoteResource,\n\t): string | undefined | Promise<string | undefined>;\n\n\tprotected abstract getUrlForFile(fileName: string, branch?: string, sha?: string, range?: LineRange): string;\n\n\tprotected getUrlForRepository(): string {\n\t\treturn this.baseUrl;\n\t}\n\n\tprotected encodeUrl(url: string): string;\n\tprotected encodeUrl(url: string | undefined): string | undefined;\n\tprotected encodeUrl(url: string | undefined): string | undefined {\n\t\treturn encodeUrl(url)?.replace(/#/g, '%23');\n\t}\n}\n\n/**\n * Parses a URL path segment like `/{ref}/{filePath}` into candidate ref interpretations\n * (SHA, short SHA, or possible branch names). Used by GitHub, GitLab, Bitbucket, and\n * Bitbucket Server where the URL structure is `/{owner}/{repo}/{type}/{ref}/{filePath}`\n * and the ref can be a SHA or branch name (which may contain `/`).\n */\nexport function parseRefCandidates(\n\tpath: string,\n\tstartLine?: number,\n\tendLine?: number,\n): ParsedRemoteFileUri | undefined {\n\tconst candidates: ParsedRemoteFileCandidate[] = [];\n\n\tconst index = path.indexOf('/', 1);\n\tif (index !== -1) {\n\t\tconst ref = path.substring(1, index);\n\t\tconst filePath = path.substring(index);\n\n\t\tif (isSha(ref)) {\n\t\t\tcandidates.push({ type: 'sha', filePath: filePath, rev: ref });\n\t\t} else if (isSha(ref, true)) {\n\t\t\tcandidates.push({ type: 'shortSha', filePath: filePath, rev: ref });\n\t\t}\n\t}\n\n\t// Enumerate possible branches (handle branch names with /)\n\tconst possibleBranches = new Map<string, string>();\n\tlet branchIndex = path.length;\n\twhile (true) {\n\t\tbranchIndex = path.lastIndexOf('/', branchIndex - 1);\n\t\tif (branchIndex <= 0) break;\n\n\t\tconst branch = path.substring(1, branchIndex);\n\t\tpossibleBranches.set(branch, path.substring(branchIndex));\n\t}\n\n\tif (possibleBranches.size) {\n\t\tcandidates.push({ type: 'branches', possibleBranches: possibleBranches });\n\t}\n\n\tif (candidates.length === 0) return undefined;\n\n\treturn { startLine: startLine, endLine: endLine, candidates: candidates };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"remoteProvider.js","names":[],"sources":["../../../../git/src/models/remoteProvider.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport { memoize } from '@gitlens/utils/decorators/memoize.js';\nimport { encodeUrl } from '@gitlens/utils/encoding.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport type { RemoteProviderContext } from '../context.js';\nimport { isSha } from '../utils/revision.utils.js';\nimport type { AutolinkReference, DynamicAutolinkReference } from './autolink.js';\nimport type { LineRange } from './lineRange.js';\nimport type { CreatePullRequestRemoteResource, RemoteResource } from './remoteResource.js';\nimport { RemoteResourceType } from './remoteResource.js';\nimport type { GkProviderId } from './repositoryIdentities.js';\nimport type { ResourceDescriptor } from './resourceDescriptor.js';\nimport type { GitRevisionRangeNotation } from './revision.js';\n\nexport interface ProviderReference {\n\treadonly id: string;\n\treadonly name: string;\n\treadonly domain: string;\n\treadonly icon: string;\n}\n\nexport interface Provider extends ProviderReference {\n\tgetIgnoreSSLErrors(): boolean | 'force';\n\treauthenticate(): Promise<void>;\n\t/** Spends a strike toward disconnecting the connection `connectionId` names, or the primary when omitted. */\n\ttrackRequestException(options?: { connectionId?: string }): void;\n}\n\nexport type RemoteProviderId =\n\t| 'azure-devops'\n\t| 'bitbucket'\n\t| 'bitbucket-server'\n\t| 'custom'\n\t| 'gerrit'\n\t| 'gitea'\n\t| 'github'\n\t| 'cloud-github-enterprise' // TODO@eamodio this shouldn't really be here, since it's not a valid remote provider id\n\t| 'cloud-gitlab-self-hosted' // TODO@eamodio this shouldn't really be here, since it's not a valid remote provider id\n\t| 'gitlab'\n\t| 'google-source';\n\nexport interface RemoteProviderSupportedFeatures {\n\tcreatePullRequestWithDetails?: boolean;\n}\n\n/** A function that matches a remote URL to a remote provider instance */\nexport type RemoteProviderMatcher = (\n\turl: string,\n\tdomain: string,\n\tpath: string,\n\tscheme: string | undefined,\n) => RemoteProvider | undefined;\n\nexport interface ParsedRemoteFileUri {\n\tstartLine?: number;\n\tendLine?: number;\n\tcandidates: ParsedRemoteFileCandidate[];\n}\n\nexport type ParsedRemoteFileCandidate =\n\t| { readonly type: 'sha'; readonly filePath: string; readonly rev: string }\n\t| { readonly type: 'shortSha'; readonly filePath: string; readonly rev: string }\n\t| { readonly type: 'branches'; readonly possibleBranches: ReadonlyMap<string, string> }\n\t| { readonly type: 'tags'; readonly possibleTags: ReadonlyMap<string, string> }\n\t| { readonly type: 'pathOnly'; readonly filePath: string };\n\nexport interface RemotesUrlsConfig {\n\treadonly repository: string;\n\treadonly branches: string;\n\treadonly branch: string;\n\treadonly commit: string;\n\treadonly comparison?: string;\n\treadonly createPullRequest?: string;\n\treadonly file: string;\n\treadonly fileInBranch: string;\n\treadonly fileInCommit: string;\n\treadonly fileLine: string;\n\treadonly fileRange: string;\n\treadonly avatar?: string;\n}\n\nexport abstract class RemoteProvider<T extends ResourceDescriptor = ResourceDescriptor> implements ProviderReference {\n\tprotected readonly _name: string | undefined;\n\n\tprotected readonly context: RemoteProviderContext | undefined;\n\n\tconstructor(\n\t\tpublic readonly domain: string,\n\t\tpublic readonly path: string,\n\t\tpublic readonly protocol: string = 'https',\n\t\tname?: string,\n\t\tpublic readonly custom: boolean = false,\n\t\tcontext?: RemoteProviderContext,\n\t) {\n\t\tthis._name = name;\n\t\tthis.context = context;\n\t}\n\n\tprotected abstract get issueLinkPattern(): string;\n\n\tget autolinks(): (AutolinkReference | DynamicAutolinkReference)[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\turl: this.issueLinkPattern,\n\t\t\t\tprefix: '',\n\t\t\t\ttitle: l10n.t('Open Issue #{number} on {provider}', { number: '<num>', provider: this.name }),\n\t\t\t\treferenceType: 'branch',\n\t\t\t\talphanumeric: false,\n\t\t\t\tignoreCase: true,\n\t\t\t},\n\t\t];\n\t}\n\n\tget avatarUri(): Uri | undefined {\n\t\treturn undefined;\n\t}\n\n\tget displayPath(): string {\n\t\treturn this.path;\n\t}\n\n\tget icon(): string {\n\t\treturn 'remote';\n\t}\n\n\tget owner(): string | undefined {\n\t\treturn this.splitPath(this.path)[0];\n\t}\n\n\t@memoize()\n\tget remoteKey(): string {\n\t\treturn this.domain ? `${this.domain}/${this.path}` : this.path;\n\t}\n\n\tget repoDesc(): T {\n\t\treturn { owner: this.owner, name: this.repoName } as unknown as T;\n\t}\n\n\tget providerDesc():\n\t\t| {\n\t\t\t\tid: GkProviderId;\n\t\t\t\trepoDomain: string;\n\t\t\t\trepoName: string;\n\t\t\t\trepoOwnerDomain?: string;\n\t\t }\n\t\t| undefined {\n\t\tif (this.gkProviderId == null || this.owner == null || this.repoName == null) return undefined;\n\n\t\treturn { id: this.gkProviderId, repoDomain: this.owner, repoName: this.repoName };\n\t}\n\n\tget repoName(): string | undefined {\n\t\treturn this.splitPath(this.path)[1];\n\t}\n\n\tabstract get id(): RemoteProviderId;\n\tabstract get gkProviderId(): GkProviderId | undefined;\n\tabstract get name(): string;\n\tget supportedFeatures(): RemoteProviderSupportedFeatures {\n\t\treturn {};\n\t}\n\n\turl(resource: RemoteResource): Promise<string | undefined> | string | undefined {\n\t\tswitch (resource.type) {\n\t\t\tcase RemoteResourceType.Branch:\n\t\t\t\treturn this.getUrlForBranch(resource.branch);\n\t\t\tcase RemoteResourceType.Branches:\n\t\t\t\treturn this.getUrlForBranches();\n\t\t\tcase RemoteResourceType.Commit:\n\t\t\t\treturn this.getUrlForCommit(resource.sha);\n\t\t\tcase RemoteResourceType.Comparison:\n\t\t\t\treturn this.getUrlForComparison(resource.base, resource.head, resource.notation ?? '...');\n\t\t\tcase RemoteResourceType.CreatePullRequest:\n\t\t\t\treturn this.getUrlForCreatePullRequest(resource);\n\t\t\tcase RemoteResourceType.File:\n\t\t\t\treturn this.getUrlForFile(\n\t\t\t\t\tresource.fileName,\n\t\t\t\t\tresource.branchOrTag ?? undefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\tresource.range,\n\t\t\t\t);\n\t\t\tcase RemoteResourceType.Repo:\n\t\t\t\treturn this.getUrlForRepository();\n\t\t\tcase RemoteResourceType.Revision:\n\t\t\t\treturn this.getUrlForFile(\n\t\t\t\t\tresource.fileName,\n\t\t\t\t\tresource.branchOrTag ?? undefined,\n\t\t\t\t\tresource.sha ?? undefined,\n\t\t\t\t\tresource.range,\n\t\t\t\t);\n\t\t\t// TODO@axosoft-ramint needs to be implemented to support remote urls for tags\n\t\t\t// case RemoteResourceType.Tag:\n\t\t\t// \treturn this.getUrlForTag(resource.tag);\n\t\t\tdefault:\n\t\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tparseRemoteFileUri?(_uri: Uri): ParsedRemoteFileUri | undefined;\n\n\tprotected get baseUrl(): string {\n\t\treturn this.getRepoBaseUrl(this.path);\n\t}\n\n\tprotected getRepoBaseUrl(path: string): string {\n\t\treturn `${this.protocol}://${this.domain}/${path}`;\n\t}\n\n\tprotected formatName(name: string): string {\n\t\tif (this._name != null) {\n\t\t\treturn this._name;\n\t\t}\n\t\treturn `${name}${this.custom ? ` (${this.domain})` : ''}`;\n\t}\n\n\tprotected splitPath(path: string): [string, string] {\n\t\tconst index = path.indexOf('/');\n\t\treturn [path.substring(0, index), path.substring(index + 1)];\n\t}\n\n\tprotected abstract getUrlForBranch(branch: string): string;\n\n\tprotected abstract getUrlForBranches(): string;\n\n\tprotected abstract getUrlForCommit(sha: string): string;\n\n\tprotected abstract getUrlForComparison(\n\t\tbase: string,\n\t\thead: string,\n\t\tnotation: GitRevisionRangeNotation,\n\t): string | undefined;\n\n\tprotected abstract getUrlForCreatePullRequest(\n\t\tresource: CreatePullRequestRemoteResource,\n\t): string | undefined | Promise<string | undefined>;\n\n\tprotected abstract getUrlForFile(fileName: string, branch?: string, sha?: string, range?: LineRange): string;\n\n\tprotected getUrlForRepository(): string {\n\t\treturn this.baseUrl;\n\t}\n\n\tprotected encodeUrl(url: string): string;\n\tprotected encodeUrl(url: string | undefined): string | undefined;\n\tprotected encodeUrl(url: string | undefined): string | undefined {\n\t\treturn encodeUrl(url)?.replace(/#/g, '%23');\n\t}\n}\n\n/**\n * Parses a URL path segment like `/{ref}/{filePath}` into candidate ref interpretations\n * (SHA, short SHA, or possible branch names). Used by GitHub, GitLab, Bitbucket, and\n * Bitbucket Server where the URL structure is `/{owner}/{repo}/{type}/{ref}/{filePath}`\n * and the ref can be a SHA or branch name (which may contain `/`).\n */\nexport function parseRefCandidates(\n\tpath: string,\n\tstartLine?: number,\n\tendLine?: number,\n): ParsedRemoteFileUri | undefined {\n\tconst candidates: ParsedRemoteFileCandidate[] = [];\n\n\tconst index = path.indexOf('/', 1);\n\tif (index !== -1) {\n\t\tconst ref = path.substring(1, index);\n\t\tconst filePath = path.substring(index);\n\n\t\tif (isSha(ref)) {\n\t\t\tcandidates.push({ type: 'sha', filePath: filePath, rev: ref });\n\t\t} else if (isSha(ref, true)) {\n\t\t\tcandidates.push({ type: 'shortSha', filePath: filePath, rev: ref });\n\t\t}\n\t}\n\n\t// Enumerate possible branches (handle branch names with /)\n\tconst possibleBranches = new Map<string, string>();\n\tlet branchIndex = path.length;\n\twhile (true) {\n\t\tbranchIndex = path.lastIndexOf('/', branchIndex - 1);\n\t\tif (branchIndex <= 0) break;\n\n\t\tconst branch = path.substring(1, branchIndex);\n\t\tpossibleBranches.set(branch, path.substring(branchIndex));\n\t}\n\n\tif (possibleBranches.size) {\n\t\tcandidates.push({ type: 'branches', possibleBranches: possibleBranches });\n\t}\n\n\tif (candidates.length === 0) return undefined;\n\n\treturn { startLine: startLine, endLine: endLine, candidates: candidates };\n}\n"],"mappings":"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"}
@@ -149,6 +149,21 @@ export interface GitOperationsSubProvider {
149
149
  editMessage?: boolean;
150
150
  source?: unknown;
151
151
  }, runOptions?: GitOperationRunOptions): Promise<GitOperationResult>;
152
+ /**
153
+ * Refreshes, in the background, the index of the checkout at `repoPath` once the clock has moved past the second it
154
+ * was written in, so that git trusts the timestamps of the files written alongside it. A write that rewrites many
155
+ * files (a clone, a worktree add, a branch switch, a fast-forward) leaves them all "racily clean", and every later
156
+ * status or diff re-hashes them until something rewrites the index, which core's own status reads (run with
157
+ * `GIT_OPTIONAL_LOCKS=0`) never do.
158
+ *
159
+ * With the git-cli provider's `refreshIndexAfterWrites` on, core's own `checkout`, `restore`, `merge`, `pull`,
160
+ * `reset`, `cherryPick`, `revert` and `rebase`, stash apply, pop and push, abort and continue of a paused operation,
161
+ * and worktree and clone writes do this themselves, including one that stops on conflicts, so only a host that
162
+ * rewrote the checkout through a raw git command needs to call it; it runs whether or not that option is on. Calls
163
+ * share one queue per checkout: one made while a refresh is waiting joins it, and one made while its status runs
164
+ * causes one more after it. Never throws.
165
+ */
166
+ scheduleIndexRefresh?(repoPath: string): void;
152
167
  }
153
168
  //#endregion
154
169
  //# sourceMappingURL=operations.d.ts.map
@@ -81,8 +81,10 @@ export interface GitProvider {
81
81
  * An exact check of which of `paths` (repo-relative) git's ignore rules match — the subset that is ignored, as
82
82
  * given. A tracked file isn't reported as ignored, even when a rule matches it. This is git's answer, where the
83
83
  * in-memory `GitIgnoreFilter` errs toward not-ignored. Each path is checked as that exact file, never as pathspec
84
- * magic (a file named `:secret` is not `secret`), and comes back in the caller's spelling. Pass
85
- * `options.priority` (e.g. `'interactive'` when opening a file) for a caller waiting on the answer.
84
+ * magic (a file named `:secret` is not `secret`), and comes back in the caller's spelling. A path git can't answer
85
+ * (inside a submodule, beyond a symlink, outside the repository, or empty) isn't ignored, and doesn't cost the
86
+ * others their answer; it rejects only when git fails for any other reason. Pass `options.priority` (e.g.
87
+ * `'interactive'` when opening a file) for a caller waiting on the answer.
86
88
  */
87
89
  getIgnoredPaths?(repoPath: string, paths: readonly string[], options?: {
88
90
  priority?: GitCommandPriority;
@@ -6,7 +6,10 @@ export declare function formatDetachedHeadName(sha: string): string;
6
6
  export declare function getBranchNameAndRemote(ref: GitBranchReference): [name: string, remote: string | undefined];
7
7
  /**
8
8
  * The upstream's branch name on its remote. The name git reports (`branch.<name>.merge`) wins over stripping the local
9
- * remote-tracking name, which a custom fetch refspec makes differ (`origin` fetching into `refs/remotes/mirror/*`)
9
+ * remote-tracking name, which a custom fetch refspec makes differ (`origin` fetching into `refs/remotes/mirror/*`).
10
+ *
11
+ * A remote-tracking branch tracks nothing. The Graph's remote refs carry the remote's own name in `upstream`, which
12
+ * read as a tracking name would fetch a branch named after the remote (`git fetch upstream upstream`)
10
13
  */
11
14
  export declare function getBranchTrackingWithoutRemote(ref: GitBranchReference): string | undefined;
12
15
  /**
@@ -33,10 +33,13 @@ function getBranchNameAndRemote(ref) {
33
33
  }
34
34
  /**
35
35
  * The upstream's branch name on its remote. The name git reports (`branch.<name>.merge`) wins over stripping the local
36
- * remote-tracking name, which a custom fetch refspec makes differ (`origin` fetching into `refs/remotes/mirror/*`)
36
+ * remote-tracking name, which a custom fetch refspec makes differ (`origin` fetching into `refs/remotes/mirror/*`).
37
+ *
38
+ * A remote-tracking branch tracks nothing. The Graph's remote refs carry the remote's own name in `upstream`, which
39
+ * read as a tracking name would fetch a branch named after the remote (`git fetch upstream upstream`)
37
40
  */
38
41
  function getBranchTrackingWithoutRemote(ref) {
39
- if (ref.upstream == null) return void 0;
42
+ if (ref.remote || ref.upstream == null) return void 0;
40
43
  const { name, remote, remoteBranch, local } = ref.upstream;
41
44
  if (local) return name;
42
45
  if (remoteBranch) return remoteBranch;
@@ -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 { 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?.local) return [ref.name, undefined];\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\n/**\n * The upstream's branch name on its remote. The name git reports (`branch.<name>.merge`) wins over stripping the local\n * remote-tracking name, which a custom fetch refspec makes differ (`origin` fetching into `refs/remotes/mirror/*`)\n */\nexport function getBranchTrackingWithoutRemote(ref: GitBranchReference): string | undefined {\n\tif (ref.upstream == null) return undefined;\n\n\tconst { name, remote, remoteBranch, local } = ref.upstream;\n\tif (local) return name;\n\tif (remoteBranch) return remoteBranch;\n\tif (remote && name.startsWith(`${remote}/`)) return name.substring(remote.length + 1);\n\n\treturn name.substring(getRemoteNameSlashIndex(name) + 1);\n}\n\n/**\n * Splits `name` at the longest of `remoteNames` that prefixes it, so a remote whose own name contains a `/` resolves\n * whole. A leading `remotes/` is stripped only when no remote matches the name as given\n */\nexport function splitRemoteBranchName(\n\tname: string,\n\tremoteNames: Iterable<string>,\n): [remote: string, branch: string] | undefined {\n\tconst names = Array.isArray(remoteNames) ? remoteNames : [...remoteNames];\n\n\tconst split = splitAtLongestRemote(name, names);\n\tif (split != null || !name.startsWith('remotes/')) return split;\n\n\treturn splitAtLongestRemote(name.substring(8), names);\n}\n\nfunction splitAtLongestRemote(\n\tname: string,\n\tremoteNames: Iterable<string>,\n): [remote: string, branch: string] | undefined {\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/**\n * @param remote - `%(upstream:remotename)`; `.` is a local upstream, and empty means git reported none. A reported\n * remote always wins, even when a custom fetch refspec puts its branches under `refs/heads/`; only when none was\n * reported (git < 2.23) is an upstream under `refs/heads/` taken as local\n * @param remoteRef - `%(upstream:remoteref)`; the upstream's ref on `remote`, read as its branch name\n */\nexport function parseUpstream(\n\tupstream: string,\n\ttracking: string,\n\tremote?: string,\n\tremoteRef?: string,\n): GitTrackingUpstream | undefined {\n\tif (!upstream) return undefined;\n\n\tconst { name } = parseRefName(upstream);\n\tconst local = remote ? remote === '.' : upstream.startsWith('refs/heads/');\n\tconst localProp = local ? { local: true } : undefined;\n\tconst remoteProp =\n\t\tremote && remote !== '.'\n\t\t\t? { remote: remote, ...(remoteRef ? { remoteBranch: remoteRef.replace(/^refs\\/heads\\//, '') } : undefined) }\n\t\t\t: 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, ...localProp };\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\t...localProp,\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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"}
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?.local) return [ref.name, undefined];\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\n/**\n * The upstream's branch name on its remote. The name git reports (`branch.<name>.merge`) wins over stripping the local\n * remote-tracking name, which a custom fetch refspec makes differ (`origin` fetching into `refs/remotes/mirror/*`).\n *\n * A remote-tracking branch tracks nothing. The Graph's remote refs carry the remote's own name in `upstream`, which\n * read as a tracking name would fetch a branch named after the remote (`git fetch upstream upstream`)\n */\nexport function getBranchTrackingWithoutRemote(ref: GitBranchReference): string | undefined {\n\tif (ref.remote || ref.upstream == null) return undefined;\n\n\tconst { name, remote, remoteBranch, local } = ref.upstream;\n\tif (local) return name;\n\tif (remoteBranch) return remoteBranch;\n\tif (remote && name.startsWith(`${remote}/`)) return name.substring(remote.length + 1);\n\n\treturn name.substring(getRemoteNameSlashIndex(name) + 1);\n}\n\n/**\n * Splits `name` at the longest of `remoteNames` that prefixes it, so a remote whose own name contains a `/` resolves\n * whole. A leading `remotes/` is stripped only when no remote matches the name as given\n */\nexport function splitRemoteBranchName(\n\tname: string,\n\tremoteNames: Iterable<string>,\n): [remote: string, branch: string] | undefined {\n\tconst names = Array.isArray(remoteNames) ? remoteNames : [...remoteNames];\n\n\tconst split = splitAtLongestRemote(name, names);\n\tif (split != null || !name.startsWith('remotes/')) return split;\n\n\treturn splitAtLongestRemote(name.substring(8), names);\n}\n\nfunction splitAtLongestRemote(\n\tname: string,\n\tremoteNames: Iterable<string>,\n): [remote: string, branch: string] | undefined {\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/**\n * @param remote - `%(upstream:remotename)`; `.` is a local upstream, and empty means git reported none. A reported\n * remote always wins, even when a custom fetch refspec puts its branches under `refs/heads/`; only when none was\n * reported (git < 2.23) is an upstream under `refs/heads/` taken as local\n * @param remoteRef - `%(upstream:remoteref)`; the upstream's ref on `remote`, read as its branch name\n */\nexport function parseUpstream(\n\tupstream: string,\n\ttracking: string,\n\tremote?: string,\n\tremoteRef?: string,\n): GitTrackingUpstream | undefined {\n\tif (!upstream) return undefined;\n\n\tconst { name } = parseRefName(upstream);\n\tconst local = remote ? remote === '.' : upstream.startsWith('refs/heads/');\n\tconst localProp = local ? { local: true } : undefined;\n\tconst remoteProp =\n\t\tremote && remote !== '.'\n\t\t\t? { remote: remote, ...(remoteRef ? { remoteBranch: remoteRef.replace(/^refs\\/heads\\//, '') } : undefined) }\n\t\t\t: 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, ...localProp };\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\t...localProp,\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,7 +9,7 @@ function createConflictDetectionError(reason) {
9
9
  }
10
10
  function getConflictDetectionErrorMessage(reason) {
11
11
  switch (reason) {
12
- case "unsupported": return "Unable to detect conflicts because Git 2.38 or later is required";
12
+ case "unsupported": return "Unable to detect conflicts because Git 2.45 or later is required";
13
13
  case "noParent": return "Unable to detect conflicts because the selection includes the initial commit";
14
14
  case "noMergeBase": return "Unable to detect conflicts because the branches don't share a common history";
15
15
  case "refNotFound": return "Unable to detect conflicts because the branch or commit doesn't exist";
@@ -18,7 +18,7 @@ function getConflictDetectionErrorMessage(reason) {
18
18
  }
19
19
  function getConflictDetectionErrorDisplayMessage(reason, fallback) {
20
20
  switch (reason) {
21
- case "unsupported": return l10n.t("Unable to detect conflicts because Git 2.38 or later is required");
21
+ case "unsupported": return l10n.t("Unable to detect conflicts because Git 2.45 or later is required");
22
22
  case "noParent": return l10n.t("Unable to detect conflicts because the selection includes the initial commit");
23
23
  case "noMergeBase": return l10n.t("Unable to detect conflicts because the branches don't share a common history");
24
24
  case "refNotFound": return l10n.t("Unable to detect conflicts because the branch or commit doesn't exist");
@@ -1 +1 @@
1
- {"version":3,"file":"mergeConflicts.utils.js","names":[],"sources":["../../../../git/src/utils/mergeConflicts.utils.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport type { ConflictDetectionErrorReason, ConflictDetectionResult } from '../models/mergeConflicts.js';\n\nexport function createConflictDetectionError(reason: ConflictDetectionErrorReason): ConflictDetectionResult {\n\treturn { status: 'error', reason: reason, message: getConflictDetectionErrorMessage(reason) };\n}\n\nfunction getConflictDetectionErrorMessage(reason: ConflictDetectionErrorReason): string {\n\tswitch (reason) {\n\t\tcase 'unsupported':\n\t\t\treturn 'Unable to detect conflicts because Git 2.38 or later is required';\n\t\tcase 'noParent':\n\t\t\treturn 'Unable to detect conflicts because the selection includes the initial commit';\n\t\tcase 'noMergeBase':\n\t\t\treturn \"Unable to detect conflicts because the branches don't share a common history\";\n\t\tcase 'refNotFound':\n\t\t\treturn \"Unable to detect conflicts because the branch or commit doesn't exist\";\n\t\tcase 'other':\n\t\tdefault:\n\t\t\treturn 'Unable to detect conflicts';\n\t}\n}\n\nexport function getConflictDetectionErrorDisplayMessage(\n\treason: ConflictDetectionErrorReason,\n\tfallback?: string,\n): string {\n\tswitch (reason) {\n\t\tcase 'unsupported':\n\t\t\treturn l10n.t('Unable to detect conflicts because Git 2.38 or later is required');\n\t\tcase 'noParent':\n\t\t\treturn l10n.t('Unable to detect conflicts because the selection includes the initial commit');\n\t\tcase 'noMergeBase':\n\t\t\treturn l10n.t(\"Unable to detect conflicts because the branches don't share a common history\");\n\t\tcase 'refNotFound':\n\t\t\treturn l10n.t(\"Unable to detect conflicts because the branch or commit doesn't exist\");\n\t\tcase 'other':\n\t\t\treturn l10n.t('Unable to detect conflicts');\n\t\tdefault:\n\t\t\treturn fallback ?? l10n.t('Unable to detect conflicts');\n\t}\n}\n"],"mappings":";;AAGA,SAAgB,6BAA6B,QAA+D;CAC3G,OAAO;EAAE,QAAQ;EAAiB;EAAQ,SAAS,iCAAiC,MAAM;CAAE;AAC7F;AAEA,SAAS,iCAAiC,QAA8C;CACvF,QAAQ,QAAR;EACC,KAAK,eACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,eACJ,OAAO;EACR,KAAK,eACJ,OAAO;EAER,SACC,OAAO;CACT;AACD;AAEA,SAAgB,wCACf,QACA,UACS;CACT,QAAQ,QAAR;EACC,KAAK,eACJ,OAAO,KAAK,EAAE,kEAAkE;EACjF,KAAK,YACJ,OAAO,KAAK,EAAE,8EAA8E;EAC7F,KAAK,eACJ,OAAO,KAAK,EAAE,8EAA8E;EAC7F,KAAK,eACJ,OAAO,KAAK,EAAE,uEAAuE;EACtF,KAAK,SACJ,OAAO,KAAK,EAAE,4BAA4B;EAC3C,SACC,OAAO,YAAY,KAAK,EAAE,4BAA4B;CACxD;AACD"}
1
+ {"version":3,"file":"mergeConflicts.utils.js","names":[],"sources":["../../../../git/src/utils/mergeConflicts.utils.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport type { ConflictDetectionErrorReason, ConflictDetectionResult } from '../models/mergeConflicts.js';\n\nexport function createConflictDetectionError(reason: ConflictDetectionErrorReason): ConflictDetectionResult {\n\treturn { status: 'error', reason: reason, message: getConflictDetectionErrorMessage(reason) };\n}\n\nfunction getConflictDetectionErrorMessage(reason: ConflictDetectionErrorReason): string {\n\tswitch (reason) {\n\t\tcase 'unsupported':\n\t\t\treturn 'Unable to detect conflicts because Git 2.45 or later is required';\n\t\tcase 'noParent':\n\t\t\treturn 'Unable to detect conflicts because the selection includes the initial commit';\n\t\tcase 'noMergeBase':\n\t\t\treturn \"Unable to detect conflicts because the branches don't share a common history\";\n\t\tcase 'refNotFound':\n\t\t\treturn \"Unable to detect conflicts because the branch or commit doesn't exist\";\n\t\tcase 'other':\n\t\tdefault:\n\t\t\treturn 'Unable to detect conflicts';\n\t}\n}\n\nexport function getConflictDetectionErrorDisplayMessage(\n\treason: ConflictDetectionErrorReason,\n\tfallback?: string,\n): string {\n\tswitch (reason) {\n\t\tcase 'unsupported':\n\t\t\treturn l10n.t('Unable to detect conflicts because Git 2.45 or later is required');\n\t\tcase 'noParent':\n\t\t\treturn l10n.t('Unable to detect conflicts because the selection includes the initial commit');\n\t\tcase 'noMergeBase':\n\t\t\treturn l10n.t(\"Unable to detect conflicts because the branches don't share a common history\");\n\t\tcase 'refNotFound':\n\t\t\treturn l10n.t(\"Unable to detect conflicts because the branch or commit doesn't exist\");\n\t\tcase 'other':\n\t\t\treturn l10n.t('Unable to detect conflicts');\n\t\tdefault:\n\t\t\treturn fallback ?? l10n.t('Unable to detect conflicts');\n\t}\n}\n"],"mappings":";;AAGA,SAAgB,6BAA6B,QAA+D;CAC3G,OAAO;EAAE,QAAQ;EAAiB;EAAQ,SAAS,iCAAiC,MAAM;CAAE;AAC7F;AAEA,SAAS,iCAAiC,QAA8C;CACvF,QAAQ,QAAR;EACC,KAAK,eACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,eACJ,OAAO;EACR,KAAK,eACJ,OAAO;EAER,SACC,OAAO;CACT;AACD;AAEA,SAAgB,wCACf,QACA,UACS;CACT,QAAQ,QAAR;EACC,KAAK,eACJ,OAAO,KAAK,EAAE,kEAAkE;EACjF,KAAK,YACJ,OAAO,KAAK,EAAE,8EAA8E;EAC7F,KAAK,eACJ,OAAO,KAAK,EAAE,8EAA8E;EAC7F,KAAK,eACJ,OAAO,KAAK,EAAE,uEAAuE;EACtF,KAAK,SACJ,OAAO,KAAK,EAAE,4BAA4B;EAC3C,SACC,OAAO,YAAY,KAAK,EAAE,4BAA4B;CACxD;AACD"}
@@ -159,9 +159,13 @@ export interface WorktreeSummaryServiceOptions {
159
159
  * inputs its last base read consulted (every branch's tracking but those of branches it didn't depend on), the stored
160
160
  * values, HEAD's commit or the upstream changed, unless it was confined to the
161
161
  * `branch.<name>` sections of branches the summary neither is on, tracks nor bases on (its `configBranches`), which
162
- * reads nothing; the checked-out branch moving, or a HEAD change, reads all of them. Stash, unrelated tags and
163
- * branches, and the like read nothing. One run is in flight per worktree at a time, at most four per repository (the
164
- * worktrees sharing a common git directory), and at most eight across the service. Runs take turns first come, first
162
+ * reads nothing; the checked-out branch moving, or a HEAD change, reads all of them. A change that may have moved one
163
+ * of those refs without naming it (a packed-refs rewrite, as deleting a packed branch makes, a ref directory, an
164
+ * overflow or a poll) first checks HEAD, the upstream and the counts against it as core's cached `getBranch` answers
165
+ * them, and the tips the base was read from against core's cached ref list, both shared by the repository's
166
+ * checkouts, and reads only the groups that moved, by the same rules — nothing when none did.
167
+ * Stash, unrelated tags and branches, and the like read nothing. One run is in flight per worktree at a time, at most
168
+ * four per repository (the worktrees sharing a common git directory), and at most eight across the service. Runs take turns first come, first
165
169
  * served, except that one whose repository is at its cap lets later runs of other repositories go first, so a burst in
166
170
  * one repository never delays another's reads: events while a run waits for its turn join it, and events during a run
167
171
  * are merged into a single follow-up run.
@@ -251,6 +255,14 @@ export declare class WorktreeSummaryService implements UnifiedDisposable {
251
255
  * the `HEAD` symrefs of `remotes` (every remote's when `undefined`); without `statIndex`, the index is unknown
252
256
  */
253
257
  private probeUnwatched;
258
+ /**
259
+ * A subscribed run's {@link ReadProbe}, from cached answers: HEAD when the branch is due or a tip check is, the ref
260
+ * tips (kept in `probed`), and the `HEAD` symrefs of the remotes the base depends on when the base may be read or a
261
+ * tip check is due — every remote's for a first read, which can come to depend on any. A tip check widens `fields` as
262
+ * {@link getTipCheckFields} finds, and is read in full when the probe fails; any other probe that fails leaves
263
+ * the tips its groups read unknown.
264
+ */
265
+ private probeRead;
254
266
  getResourceUsage(): ResourceUsage;
255
267
  private start;
256
268
  /**