@gitkraken/core-gitlens 0.16.2 → 0.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CHANGELOG.md +33 -1
  2. package/dist/git/cache.d.ts +64 -5
  3. package/dist/git/cache.js +75 -5
  4. package/dist/git/cache.js.map +1 -1
  5. package/dist/git/models/branch.d.ts +0 -6
  6. package/dist/git/models/branch.js.map +1 -1
  7. package/dist/git/providers/branches.d.ts +65 -1
  8. package/dist/git/providers/refs.d.ts +3 -2
  9. package/dist/git/providers/shared/remotes.js +5 -5
  10. package/dist/git/providers/shared/remotes.js.map +1 -1
  11. package/dist/git/watching/classifyChange.js +5 -2
  12. package/dist/git/watching/classifyChange.js.map +1 -1
  13. package/dist/git/watching/watchGroup.js +2 -1
  14. package/dist/git/watching/watchGroup.js.map +1 -1
  15. package/dist/git-cli/providers/branches.d.ts +151 -31
  16. package/dist/git-cli/providers/branches.js +918 -253
  17. package/dist/git-cli/providers/branches.js.map +1 -1
  18. package/dist/git-cli/providers/commits.js +37 -20
  19. package/dist/git-cli/providers/commits.js.map +1 -1
  20. package/dist/git-cli/providers/config.js +16 -10
  21. package/dist/git-cli/providers/config.js.map +1 -1
  22. package/dist/git-cli/providers/contributors.js +3 -3
  23. package/dist/git-cli/providers/contributors.js.map +1 -1
  24. package/dist/git-cli/providers/diff.js +15 -12
  25. package/dist/git-cli/providers/diff.js.map +1 -1
  26. package/dist/git-cli/providers/graph.js +17 -14
  27. package/dist/git-cli/providers/graph.js.map +1 -1
  28. package/dist/git-cli/providers/maintenance.js +3 -3
  29. package/dist/git-cli/providers/maintenance.js.map +1 -1
  30. package/dist/git-cli/providers/patch.js +4 -1
  31. package/dist/git-cli/providers/patch.js.map +1 -1
  32. package/dist/git-cli/providers/pausedOperations.js +2 -2
  33. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  34. package/dist/git-cli/providers/refs.js +16 -13
  35. package/dist/git-cli/providers/refs.js.map +1 -1
  36. package/dist/git-cli/providers/remotes.js +4 -1
  37. package/dist/git-cli/providers/remotes.js.map +1 -1
  38. package/dist/git-cli/providers/revision.js +14 -11
  39. package/dist/git-cli/providers/revision.js.map +1 -1
  40. package/dist/git-cli/providers/stash.js +2 -2
  41. package/dist/git-cli/providers/stash.js.map +1 -1
  42. package/dist/git-cli/providers/status.js +7 -7
  43. package/dist/git-cli/providers/status.js.map +1 -1
  44. package/dist/git-cli/providers/tags.js +6 -3
  45. package/dist/git-cli/providers/tags.js.map +1 -1
  46. package/dist/git-cli/providers/worktrees.js +3 -3
  47. package/dist/git-cli/providers/worktrees.js.map +1 -1
  48. package/dist/plus/git-github/providers/github/branches.d.ts +9 -1
  49. package/dist/plus/git-github/providers/github/branches.js +54 -8
  50. package/dist/plus/git-github/providers/github/branches.js.map +1 -1
  51. package/dist/plus/integrations/providers/issueSorts.d.ts +1 -0
  52. package/dist/plus/integrations/reads/drains.d.ts +1 -0
  53. package/dist/utils/decorators/log.d.ts +3 -1
  54. package/dist/utils/decorators/log.js +61 -45
  55. package/dist/utils/decorators/log.js.map +1 -1
  56. package/dist/utils/logger.d.ts +15 -1
  57. package/dist/utils/logger.js +30 -1
  58. package/dist/utils/logger.js.map +1 -1
  59. package/dist/utils/logger.scoped.d.ts +12 -1
  60. package/dist/utils/logger.scoped.js +38 -4
  61. package/dist/utils/logger.scoped.js.map +1 -1
  62. package/package.json +1 -1
@@ -5,7 +5,7 @@ import { ConflictDetectionResult } from "../../git/models/mergeConflicts.js";
5
5
  import { GitServiceContext } from "../../git/context.js";
6
6
  import { GitCommandPriority } from "../../git/run.types.js";
7
7
  import { BranchSortOptions } from "../../git/utils/sorting.js";
8
- import { AheadOfBase, BranchContributionsOverview, GitBranchMergedStatus, GitBranchesSubProvider, GitPushTarget } from "../../git/providers/branches.js";
8
+ import { AheadOfBase, BranchContributionsOverview, GitBranchMergedStatus, GitBranchesSubProvider, GitPushTarget, MergeTarget, MergeTargetOptions } from "../../git/providers/branches.js";
9
9
  import { Cache, GkConfigInvalidationTarget } from "../../git/cache.js";
10
10
  import { Git } from "../exec/git.js";
11
11
  import { CliGitProviderInternal } from "../cliGitProvider.js";
@@ -18,12 +18,22 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
18
18
  /** Ahead/behind counts by `<baseSha>...<tipSha>` range, from the per-tip fallback; a pair of commits always counts the same */
19
19
  private readonly aheadBehindBySha;
20
20
  /**
21
- * For a base that moved only forward, the commits its reflog reaches off the new tip's history (else `false`), by
22
- * `<ref>\0<oldSha>\0<newSha>`, for each cached ref list it was read against: a ref write replaces that list, along
23
- * with the reflog the answer came from. `undefined` when git couldn't say, which isn't kept. A fetch moves one base
24
- * under every worktree at once, so they share the one check, joining it while it runs
21
+ * For a base that moved only forward, what its reflog reaches (else `false`), by `<commonPath>\0<ref>`, then by the
22
+ * tip it moved from. A fetch moves one base under every worktree at once, so they share the one check, joining it
23
+ * while it runs. The reads hold for the tip the ref moved to, the reflog they read, stamped by its file's size and
24
+ * mtime (else by the cached ref list, through what it derives so the list itself isn't held, when there's no file
25
+ * to stamp), and the replace refs, which change what's reachable; a change to any of them starts the ref over. Every
26
+ * move appends to the reflog, so a ref moved away and back to the same tip between reads doesn't find the answer
27
+ * taken before
25
28
  */
26
29
  private readonly baseMovedForward;
30
+ /**
31
+ * For a base that moved, the count of the commits its new tip lacks for each local branch a worktree has checked
32
+ * out, by tip sha, by `<commonPath>\0<newTip>`, with the replace refs it was counted under and the tips it counted.
33
+ * The counts don't depend on the ref or where it moved from, so each worktree the move reached finds its HEAD's
34
+ * count in the one read, even one whose previous answer was taken at another old tip
35
+ */
36
+ private readonly aheadOfMovedBase;
27
37
  /**
28
38
  * When each `commonPath\0branch\0key` was last stamped by this process. Bounded: a dropped entry only costs a
29
39
  * read of the stored stamp, which still holds off a write under 5 minutes old
@@ -37,6 +47,11 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
37
47
  * it once
38
48
  */
39
49
  private readonly _branchCreatedFrom;
50
+ /**
51
+ * The branch HEAD was on when each `commonPath\0branch` was first checked out, as git wrote it, for a branch
52
+ * created from `HEAD`; only found ones, since a later checkout can write one
53
+ */
54
+ private readonly _branchCheckedOutFrom;
40
55
  /** Bumped each time a key's created-from is forgotten, so a reflog read in flight across that doesn't store it */
41
56
  private readonly _branchCreatedFromGenerations;
42
57
  /**
@@ -67,6 +82,7 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
67
82
  position: number;
68
83
  };
69
84
  } | undefined>;
85
+ getFallbackDefaultBranch?: () => Promise<string | undefined>;
70
86
  priority?: GitCommandPriority;
71
87
  }, cancellation?: AbortSignal): Promise<BranchContributionsOverview | undefined>;
72
88
  getBranchesWithCommits(repoPath: string, commits: string[], branch?: string, options?: {
@@ -132,8 +148,9 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
132
148
  priority?: GitCommandPriority;
133
149
  }, cancellation?: AbortSignal): Promise<string | undefined>;
134
150
  /**
135
- * `failed` separates "the reflog ran and had no answer" from "the read never happened" — the caller
136
- * caches the former forever and must not cache the latter.
151
+ * The branch `ref` was created from, else the branch HEAD was on when it was first checked out, each as its
152
+ * upstream when it has one. `failed` separates "the reflog ran and had no answer" from "the read never happened" —
153
+ * the caller caches the former forever and must not cache the latter.
137
154
  */
138
155
  private getBaseBranchFromReflog;
139
156
  /**
@@ -143,12 +160,37 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
143
160
  */
144
161
  private getReflogCreatedFrom;
145
162
  /**
146
- * The branch `branch` was created from, as a base for {@link getAheadOfBaseInOrder}: the name its own reflog
147
- * gives, when that is a local or remote-tracking branch in the cached ref list and not `branch` itself or its
148
- * copy on a remote (`git switch <branch>` creates it from `<remote>/<branch>`). Never the checkout history in
149
- * HEAD's reflog, which on a long-lived checkout names whatever was checked out last.
163
+ * The worktree `branch` is checked out in, whose HEAD reflog holds its checkouts; else the main worktree, never the
164
+ * caller's, since every worktree of the repository shares the answer
165
+ */
166
+ private getCheckoutPath;
167
+ /**
168
+ * The branch HEAD was on when `branch` was first checked out at `repoPath` (the oldest `checkout: moving from
169
+ * <name> to <branch>` in its HEAD reflog), as git wrote it. `undefined` when there is no such entry. Rejects when the
170
+ * reflog can't be read.
171
+ */
172
+ private getCheckoutSource;
173
+ /**
174
+ * The branch `branch` was created from, as a base for {@link resolveBase}: the name its own reflog gives, when that
175
+ * is a local or remote-tracking branch in the cached ref list and not `branch` itself or its copy on a remote
176
+ * (`git switch <branch>` creates it from `<remote>/<branch>`). Never the checkout history in HEAD's reflog, which
177
+ * on a long-lived checkout names whatever was checked out last. `fromHead` when the reflog says it was created
178
+ * from `HEAD`.
150
179
  */
151
180
  private getCreatedFromTarget;
181
+ /**
182
+ * For a branch its reflog says was created from `HEAD`, the branch HEAD was on when it was first checked out (see
183
+ * {@link getCheckoutSource}), read in the worktree it is checked out in, else the main worktree, and kept as a base
184
+ * like {@link getCreatedFromTarget}'s. Remembered once found, as the created-from name is; a reflog with no such
185
+ * entry yet marks the answer for eviction on the next checkout, which may write one.
186
+ */
187
+ private getInferredCreatedFrom;
188
+ /**
189
+ * `name` as a base for `branch`: only a local or remote-tracking branch in the cached ref list — a sha, a tag or a
190
+ * revision expression (`main~2`) names no `refs/heads/` or `refs/remotes/` ref — and not `branch` itself or its
191
+ * copy on a remote.
192
+ */
193
+ private getListedBaseName;
152
194
  getAheadOfBaseConfigKey(repoPath: string, cancellation?: AbortSignal): Promise<string | undefined>;
153
195
  getAheadOfBaseConfigEntries(repoPath: string, cancellation?: AbortSignal): Promise<readonly (readonly [key: string, value: string | undefined])[] | undefined>;
154
196
  /**
@@ -177,13 +219,24 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
177
219
  private isRemoteHeadOf;
178
220
  /**
179
221
  * For `ref` (a full name in `records`, the cached ref list) moving from `oldTip` to `newTip`, the commits its reflog
180
- * reaches off `newTip`'s history when it moved only forward: `oldTip` and every value its reflog took after it are in
181
- * `newTip`'s history. `--fork-point` reads every reflog entry, so one in between that shares more of HEAD's history
182
- * than `newTip` does (a branch's commit that landed and was force-pushed away) moves the fork point while the count
183
- * stands; an older one off `newTip`'s history may hold such a commit too, which each worktree's count checks for.
184
- * Without a reflog it reads only the tip. `undefined` when it didn't move only forward, or git can't say.
222
+ * holds and those it reaches off `newTip`'s history, when it moved only forward: `oldTip` and every value its reflog
223
+ * took after it are in `newTip`'s history. `--fork-point` reads every reflog entry, so one in between that shares
224
+ * more of HEAD's history than `newTip` does (a branch's commit that landed and was force-pushed away) moves the fork
225
+ * point while the count stands; an older one off `newTip`'s history may hold such a commit too, which each
226
+ * worktree's count checks for. Without a reflog it reads only the tip. `undefined` when it didn't move only forward,
227
+ * or git can't say.
185
228
  */
186
229
  private getMovedForward;
230
+ /**
231
+ * A stamp of `ref`'s reflog file in the common git directory, by its size and mtime; `undefined` when there's no
232
+ * file to stat (a reftable repository, or a ref without a reflog)
233
+ */
234
+ private getReflogStamp;
235
+ /**
236
+ * A stamp of the common git directory's `shallow` file, by its size and mtime; `null` when the repository isn't
237
+ * shallow, `undefined` when that can't be read
238
+ */
239
+ private getShallowStamp;
187
240
  /**
188
241
  * Reads {@link getMovedForward} from git, in `commonPath`, which holds the refs, their reflogs and the objects for
189
242
  * every worktree. Not bound to one caller's cancellation, since every worktree the move reached rides this one
@@ -192,10 +245,72 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
192
245
  */
193
246
  private readMovedForward;
194
247
  /**
195
- * Resolves the base from the recorded candidates, then the branch it was created from or the default branch, for
196
- * {@link getAheadOfBase}
248
+ * For a base moved to `newTip`, the count of the commits `newTip` lacks for `head`, from one count of each local
249
+ * branch a worktree has checked out in `records` (the cached ref list), by tip sha, so a detached HEAD at one of
250
+ * those tips finds its count too. Only those branches are counted: the one walk runs until every counted branch
251
+ * meets `newTip`, so an unrelated old or orphan branch would make it deeper than any worktree's own count. Which
252
+ * branches it counts only bounds that walk, since a commit's count past `newTip` doesn't depend on what else is
253
+ * counted, so a read that counted `head` answers it for a later list (one with a branch created at `newTip` since,
254
+ * say) while the replace refs match; a `head` it didn't count starts a read over the current list's checked-out
255
+ * branches. `undefined` when no checked-out branch is at `head` or `records` can't tell which are checked out, git
256
+ * can't count them in one pass (before 2.41), or git couldn't say.
257
+ */
258
+ private getAheadOfMovedBase;
259
+ /**
260
+ * Reads {@link getAheadOfMovedBase} for the `checkedOut` branches from git, in `commonPath`, which holds every
261
+ * worktree's branches. Not bound to one caller's cancellation, since every worktree the move reached rides this one
262
+ * read.
263
+ */
264
+ private readAheadOfMovedBase;
265
+ getMergeTarget(repoPath: string, branch: string, options?: MergeTargetOptions, cancellation?: AbortSignal): Promise<MergeTarget | undefined>;
266
+ /**
267
+ * Where {@link getMergeTarget} measures `branch` from: its local branch's ref, or — for a remote-tracking branch given
268
+ * by its short name (`origin/feature`) — that ref, with `selfName` its name on the remote
269
+ */
270
+ private getMergeTargetSource;
271
+ /** Resolves {@link getMergeTarget}'s answer with what it was read from; `pinnable` is false when it can't be confirmed later */
272
+ private resolveMergeTarget;
273
+ /** Whether everything `entry` was read from still reads the same; while nothing changed, every read here is cached */
274
+ private isMergeTargetCurrent;
275
+ /**
276
+ * The base `branch` is measured against from `reads.from`, in {@link getMergeTarget}'s order; `getAheadOfBase`'s
277
+ * options never reach the pull request, the reflog guess or the remote. `selfName` is the name a self check
278
+ * compares with: `branch`, or a remote-tracking branch's name on its remote, which has no stored targets, reflog or
279
+ * upstream of its own. A `'preferred'` target is already known not to be the branch itself at `from`'s commit; any
280
+ * other target isn't checked here.
281
+ */
282
+ private resolveBase;
283
+ /**
284
+ * The first usable stored candidate, most trusted first: the user's merge target (unless `skipUserTarget`), the
285
+ * detected one, the pull request's base (`getAssociatedPullRequest`, read only when neither is usable), then the
286
+ * recorded base — only its stored value (and with `inferBase`, VS Code's), never `getBaseBranchName`'s reflog
287
+ * guess, which on a long-lived checkout names whatever branch was last checked out from. A remote-tracking branch
288
+ * has no stored keys of its own, so only its pull request's base is tried, and never recorded.
289
+ */
290
+ private getStoredBaseTarget;
291
+ /**
292
+ * The branch's stored merge keys as read, in {@link storedMergeKeys} order, then VS Code's recorded base when
293
+ * `inferBase`. A failed read is absent, and leaves `reads`' answer unpinned.
197
294
  */
198
- private getAheadOfBaseInOrder;
295
+ private readStoredMergeKeys;
296
+ /**
297
+ * The pull request's base as a candidate on the branch's remote; `undefined` when there is none, the branch has no
298
+ * remote, or either can't be read (which leaves `reads`' answer unpinned)
299
+ */
300
+ private getPullRequestBaseCandidate;
301
+ /**
302
+ * The default branch for {@link resolveBase}: {@link getLocalDefaultBranchName}; when that names none, with
303
+ * `defaultBranch: 'remote'`, the default the first of those remotes reports; then `getFallbackDefaultBranch`. A
304
+ * remote-qualified answer is taken as its local branch when there is one
305
+ */
306
+ private getDefaultBranchForBase;
307
+ /** `local` when the cached ref list names that branch (depended on either way), else `remoteName` */
308
+ private preferListedLocalBranch;
309
+ /**
310
+ * The branch `branch` was created from (tier `'created'`); with `inferBase`, for one created from `HEAD`, the
311
+ * branch HEAD was on when it was first checked out (tier `'inferred'`)
312
+ */
313
+ private getCreatedFromSource;
199
314
  /**
200
315
  * The base for a branch created from `createdFrom`: that branch, unless the default branch forked strictly nearer
201
316
  * HEAD, as it does once `createdFrom` merged into it and the branch was rebased onto it. A stacked branch's
@@ -233,14 +348,13 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
233
348
  private isSelfRef;
234
349
  /** The repo's remote names from the cached remote list; empty when it can't be read */
235
350
  private getRemoteNames;
236
- /** Whether `ref` names `branch` itself (see {@link isSelfRef}) and sits at HEAD's commit; tips are read only after the name matched */
237
- private isSelfAtHead;
238
351
  /**
239
- * The bases recorded against a branch, most trusted first: the user's merge target, the detected one, then the
240
- * base a launch recorded. Only the stored value of the latter — `getBaseBranchName` would fall back to a reflog
241
- * guess, which on a long-lived checkout names whatever branch was last checked out from. A failed read is absent.
352
+ * Whether `ref` names `selfName` itself (see {@link isSelfRef}) and sits at `reads.from`'s commit; tips are read
353
+ * only after the name matched. HEAD's commit is asked of git, a branch's read from the cached ref list
242
354
  */
243
- private getRecordedBaseCandidates;
355
+ private isSelfAtTip;
356
+ /** The remotes a default branch is read from, in order: `upstream`, `origin`, then the first remote */
357
+ private getPreferredRemotes;
244
358
  /**
245
359
  * The repo's default branch from local refs only, never the network: the `HEAD` symref of the `upstream` remote,
246
360
  * else of `origin`, else of the first remote, as its local branch or else as the remote ref; then, in the same
@@ -259,16 +373,17 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
259
373
  /** {@link getNearestForkTarget} with the `upstream` remote's copy of `candidate` as its contender */
260
374
  private getUpstreamNearestForkTarget;
261
375
  /**
262
- * A candidate base as the ref HEAD is measured against: the candidate or its tracking ref, whichever forked
263
- * nearer HEAD, so a stale local base defers to its upstream while one carrying unpushed work wins over it. A
376
+ * A candidate base as the ref `reads.from` is measured against: the candidate or its tracking ref, whichever forked
377
+ * nearer, so a stale local base defers to its upstream while one carrying unpushed work wins over it. A
264
378
  * `contender` other than the tracking ref is taken only when it forked strictly nearer than both, so a tie keeps
265
- * the candidate's own pick. A candidate none forks from is used as-is if it names a commit. `undefined` when the
266
- * candidate is unusable.
379
+ * the candidate's own pick. A candidate none forks from is used as-is unless git confirms it names no ref: one the
380
+ * cached ref list names is kept, and so is one whose check fails. `undefined` when the candidate is unusable.
267
381
  */
268
382
  private getNearestForkTarget;
269
383
  /**
270
384
  * `<name>@{u}`, without asking git when the cached ref list shows `name` can't have one: a failed lookup isn't
271
- * cached, so asking it of a remote-tracking ref (`origin/main`, the usual default) re-spawns on every read.
385
+ * cached, so asking it of a remote-tracking ref (`origin/main`, the usual default) re-spawns on every read. The
386
+ * list's own upstream isn't used: a config-only change (`git branch -u`) doesn't refresh it.
272
387
  */
273
388
  private getUpstreamName;
274
389
  /**
@@ -282,8 +397,13 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
282
397
  * so an empty one is asked of git instead, rather than read as every ref being absent.
283
398
  */
284
399
  private getRefTip;
285
- /** The merge base of HEAD and `ref`, preferring git's fork-point reading of `ref`'s reflog when it has one */
400
+ /** Where `reads.from` forked from `ref`: git's fork-point reading of `ref`'s reflog when it has one, else their merge base */
286
401
  private getForkPoint;
402
+ /**
403
+ * `getMergeBase`, sharing its cached and in-flight reads, but telling git's exit 1 (no common ancestor, or no fork
404
+ * point) from a read that failed. Both answer `undefined`; a failed one also clears `reads.pinnable`.
405
+ */
406
+ private readMergeBase;
287
407
  /**
288
408
  * The stored merge target — the user's pick, else the one detected from its PR — skipping any whose branch git
289
409
  * confirms is gone so resolution falls through to the next source. A target that couldn't be checked is kept.