@gitkraken/core-gitlens 0.16.5 → 0.17.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 (63) hide show
  1. package/CHANGELOG.md +32 -1
  2. package/dist/git/cache.d.ts +8 -2
  3. package/dist/git/cache.js +15 -6
  4. package/dist/git/cache.js.map +1 -1
  5. package/dist/git/models/repository.d.ts +4 -2
  6. package/dist/git/models/repository.js +1 -0
  7. package/dist/git/models/repository.js.map +1 -1
  8. package/dist/git/models/worktree.d.ts +5 -1
  9. package/dist/git/models/worktree.js +5 -3
  10. package/dist/git/models/worktree.js.map +1 -1
  11. package/dist/git/providers/provider.d.ts +17 -0
  12. package/dist/git/providers/worktrees.d.ts +17 -2
  13. package/dist/git/run.types.d.ts +7 -0
  14. package/dist/git/service.d.ts +5 -2
  15. package/dist/git/service.js +11 -5
  16. package/dist/git/service.js.map +1 -1
  17. package/dist/git/watching/classifyChange.d.ts +4 -3
  18. package/dist/git/watching/classifyChange.js +7 -4
  19. package/dist/git/watching/classifyChange.js.map +1 -1
  20. package/dist/git/watching/provider.d.ts +6 -0
  21. package/dist/git/watching/watchGroup.d.ts +142 -3
  22. package/dist/git/watching/watchGroup.js +424 -19
  23. package/dist/git/watching/watchGroup.js.map +1 -1
  24. package/dist/git/watching/watchService.d.ts +25 -0
  25. package/dist/git/watching/watchService.js +27 -7
  26. package/dist/git/watching/watchService.js.map +1 -1
  27. package/dist/git/watching/watchSession.d.ts +13 -8
  28. package/dist/git/watching/watchSession.js +50 -10
  29. package/dist/git/watching/watchSession.js.map +1 -1
  30. package/dist/git/watching/watcherPatterns.d.ts +14 -0
  31. package/dist/git/watching/watcherPatterns.js +38 -1
  32. package/dist/git/watching/watcherPatterns.js.map +1 -1
  33. package/dist/git/watching/worktreeSummary.d.ts +64 -2
  34. package/dist/git/watching/worktreeSummary.js +326 -13
  35. package/dist/git/watching/worktreeSummary.js.map +1 -1
  36. package/dist/git-cli/cliGitProvider.d.ts +26 -0
  37. package/dist/git-cli/cliGitProvider.js +66 -5
  38. package/dist/git-cli/cliGitProvider.js.map +1 -1
  39. package/dist/git-cli/exec/commandClassifier.d.ts +9 -3
  40. package/dist/git-cli/exec/commandClassifier.js +98 -17
  41. package/dist/git-cli/exec/commandClassifier.js.map +1 -1
  42. package/dist/git-cli/exec/git.d.ts +20 -0
  43. package/dist/git-cli/exec/git.js +69 -7
  44. package/dist/git-cli/exec/git.js.map +1 -1
  45. package/dist/git-cli/exec/headState.d.ts +5 -0
  46. package/dist/git-cli/exec/headState.js +14 -1
  47. package/dist/git-cli/exec/headState.js.map +1 -1
  48. package/dist/git-cli/parsers/worktreeParser.js +2 -2
  49. package/dist/git-cli/parsers/worktreeParser.js.map +1 -1
  50. package/dist/git-cli/providers/branches.js +8 -4
  51. package/dist/git-cli/providers/branches.js.map +1 -1
  52. package/dist/git-cli/providers/graph.js +1 -1
  53. package/dist/git-cli/providers/graph.js.map +1 -1
  54. package/dist/git-cli/providers/operations.d.ts +3 -0
  55. package/dist/git-cli/providers/operations.js +14 -5
  56. package/dist/git-cli/providers/operations.js.map +1 -1
  57. package/dist/git-cli/providers/worktrees.d.ts +25 -3
  58. package/dist/git-cli/providers/worktrees.js +125 -32
  59. package/dist/git-cli/providers/worktrees.js.map +1 -1
  60. package/dist/git-cli/service.d.ts +2 -0
  61. package/dist/git-cli/service.js +4 -2
  62. package/dist/git-cli/service.js.map +1 -1
  63. package/package.json +1 -1
@@ -42,6 +42,12 @@ export interface FileWatcherOptions {
42
42
  * already down reports `unwatchable` itself. Going from `unwatchable` to anything else makes core rescan.
43
43
  */
44
44
  readonly onDidChangeReliability?: (state: FileWatcherReliability) => void;
45
+ /**
46
+ * Called once, when a watch the provider places asynchronously goes live: whatever changed under `basePath` between
47
+ * `createWatcher` and then went unseen, so core rescans. A provider whose watch is live when `createWatcher` returns
48
+ * never calls it. Passed only to working-tree watchers, whether or not the host opted into polling.
49
+ */
50
+ readonly onDidStart?: () => void;
45
51
  }
46
52
  /**
47
53
  * Factory for creating filesystem watchers. The library calls this
@@ -61,14 +61,51 @@ interface SessionEntry {
61
61
  * starts, is the baseline and delivers nothing; a report arriving before it completes may describe a change it
62
62
  * already holds, so it is delivered unconfined. A read that fails or doesn't settle within a few seconds, or a file
63
63
  * git couldn't parse, is unconfined too.
64
+ *
65
+ * Given a `readFile`, a `readDirectory` (a directory's entries with their types, only the directories counting as
66
+ * admin entries) and the folders whose worktrees the host has core ignore (a tool's throwaway worktrees, which no
67
+ * host shows), the group reports no change of an ignored worktree's admin entry
68
+ * (`<common>/worktrees/<id>`) to any session. Only registered folders count, since a user may keep real worktrees
69
+ * anywhere, `.git` included. It lists the entries and reads each one's `gitdir` once as it starts, and again after a
70
+ * watcher dropped events; a report arriving meanwhile is told at once, and decided once the listing settles, so what
71
+ * is known of its entry catches up. From then on it reads an entry only when its `gitdir` may be new (the entry was
72
+ * created, or its `gitdir` written, or it was removed before), so a real worktree's HEAD moves are told at once,
73
+ * unread. Of two reads of one entry, the later decides both reports. An entry it doesn't know whose `gitdir` can't be
74
+ * read (a watcher can report one before git writes it, and miss the write) is read once more a moment later, its
75
+ * reports held until then, and told if it still can't be. Only the entry's directory or its `gitdir` going is a
76
+ * removal; a deleted `HEAD` (a watcher may report git's lock file renamed over it as a delete) or `locked` is told as
77
+ * the entry is known. Removing an entry deletes the `gitdir` a read needs, so a removal is told from what the entry was
78
+ * known to be (before a read that couldn't read it, if one is waiting to read it again), and an entry it never knew is
79
+ * told as real. Any other report of a removed entry but a delete is read, and one that can't be read is the removal's
80
+ * own (a watcher may report the entry's directory changed beside each file it deletes), unless it creates the entry
81
+ * again. A report of the `worktrees` directory itself (a coalesced
82
+ * removal, a parent directory change, a poll, which sees nothing finer) lists it again: it is told to every session
83
+ * when a real entry was added or removed since the last listing, and to none when only ignored ones were. Git removes
84
+ * the directory with its last entry, so a directory that isn't there is an empty listing, as is a removal of it that
85
+ * can't be listed. Since a listing (or a worktree moved into or out of a folder) changes what every session shows, it
86
+ * is told to all of them; the other watcher's report of the same change then finds nothing left to tell. Where only a
87
+ * poll watches the common dir, it sees just the `worktrees` directory, so an entry removed and added again under the
88
+ * same id between two polls, or an entry's HEAD or lock changed in place, goes untold.
89
+ *
90
+ * Given the folders, the watchers over the common dir leave each one unwatched, since a tool's checkout there would
91
+ * otherwise have every directory of it watched; one that shares a top-level directory with what the `.git` watch reads
92
+ * stays watched.
64
93
  */
65
94
  export declare class WatchGroup implements UnifiedDisposable {
66
95
  readonly commonGitDir: string;
67
96
  private readonly provider;
68
97
  /** When given, a watcher that reports it can't be trusted is polled; otherwise none is asked */
69
98
  private readonly poller?;
70
- /** When given, reports of the shared `.git/config` are classified by what changed in it (see above) */
99
+ /**
100
+ * When given, reports of the shared `.git/config` are classified by what changed in it, and admin entries are
101
+ * read to tell an ignored worktree's (see above)
102
+ */
71
103
  private readonly readFile?;
104
+ /**
105
+ * Returns a directory's entries with their types; with `readFile`, the admin entries are listed, only the
106
+ * directories counting (see above)
107
+ */
108
+ private readonly readDirectory?;
72
109
  private readonly _sessions;
73
110
  private _commonWatcher;
74
111
  private _commonReliability;
@@ -80,11 +117,52 @@ export declare class WatchGroup implements UnifiedDisposable {
80
117
  private _configBaselining;
81
118
  private _configReading;
82
119
  private _configRereadQueued;
120
+ /**
121
+ * Settles once the latest baseline of the admin entries was taken; `undefined` when the group can't tell an
122
+ * ignored worktree's, so every report is told at once
123
+ */
124
+ private _worktreesBaseline;
125
+ /** A baseline is pending, so a report waits for it */
126
+ private _worktreesBaselining;
127
+ private _worktreesRebaselineQueued;
128
+ /** Set by the first baseline; while empty, nothing is ignored and every report is told at once */
129
+ private _ignoredWorktreeRoots;
130
+ /** Listings run one at a time, so each compares with the one before it */
131
+ private _worktreesQueue;
132
+ /** The `worktrees` directory's reports waiting on the queued listing; `undefined` while none is queued */
133
+ private _worktreesRescanQueued;
134
+ /** The admin entries the last listing found */
135
+ private _listedWorktreeIds;
136
+ /** Admin entries known to exist, by id: whether each is an ignored worktree's */
137
+ private readonly _worktreeIds;
138
+ /** What removed admin entries were, by id, oldest first */
139
+ private readonly _removedWorktreeIds;
140
+ /**
141
+ * Each id's latest `gitdir` read, settling with what it found and what the id was known to be before it; only it
142
+ * may update what is known of the id. A removal of the entry drops it
143
+ */
144
+ private readonly _worktreeReads;
145
+ /** Admin entries whose `gitdir` couldn't be read, by id, waiting to be read once more */
146
+ private readonly _worktreeRetries;
147
+ /** The `.git` excludes of a watcher over the common git dir, with the ignored worktrees' folders it may leave out */
148
+ private readonly _commonGitDirExcludes;
83
149
  constructor(commonGitDir: string, provider: FileWatchingProvider,
84
150
  /** When given, a watcher that reports it can't be trusted is polled; otherwise none is asked */
85
151
  poller?: GitDirPoller | undefined,
86
- /** When given, reports of the shared `.git/config` are classified by what changed in it (see above) */
87
- readFile?: ((path: string) => Promise<Uint8Array>) | undefined);
152
+ /**
153
+ * When given, reports of the shared `.git/config` are classified by what changed in it, and admin entries are
154
+ * read to tell an ignored worktree's (see above)
155
+ */
156
+ readFile?: ((path: string) => Promise<Uint8Array>) | undefined,
157
+ /**
158
+ * Returns a directory's entries with their types; with `readFile`, the admin entries are listed, only the
159
+ * directories counting (see above)
160
+ */
161
+ readDirectory?: ((path: string) => Promise<readonly (readonly [string, number])[]>) | undefined,
162
+ /** The absolute, normalized folders whose worktrees are ignored; none reads no admin entry */
163
+ ignoredWorktreeRoots?: Promise<readonly string[]>,
164
+ /** The folders whose worktrees are ignored, relative to the common git dir */
165
+ ignoredWorktreeFolders?: readonly string[]);
88
166
  [Symbol.dispose](): void;
89
167
  /** Dispose the entire group (common watcher + all root watchers). */
90
168
  dispose(): void;
@@ -100,6 +178,12 @@ export declare class WatchGroup implements UnifiedDisposable {
100
178
  private disposeCommonWatcher;
101
179
  /** Hosts that didn't opt into polling get exactly the options they always had */
102
180
  private getWatcherOptions;
181
+ /**
182
+ * The ignored worktrees' folders join the `.git` excludes of a watcher over the common git dir: a tool that keeps its
183
+ * throwaway checkouts inside the git dir would otherwise have each one's every directory watched, and every file it
184
+ * writes reported. Every other watcher sits on a linked worktree's admin entry, which holds none of them
185
+ */
186
+ private getExcludes;
103
187
  private setRootReliability;
104
188
  private setCommonReliability;
105
189
  private stopPolling;
@@ -119,12 +203,67 @@ export declare class WatchGroup implements UnifiedDisposable {
119
203
  private onCommonEvent;
120
204
  private deliverOverflow;
121
205
  private onRootEvent;
206
+ /** A report of the `worktrees` directory, an admin entry or a file in it, once the group may tell them apart */
207
+ private isWorktreesReport;
208
+ /** `deliver` tells the sessions the report reaches of it, should the report concern them (see above) */
209
+ private onWorktreesReported;
210
+ private decideWorktreesReport;
211
+ /**
212
+ * Reads the entry's `gitdir`: whether it names an ignored worktree (`undefined` when it can't be read), and what the
213
+ * id was known to be when this read replaced it. Reads of one id can settle out of order (a slow one from before the
214
+ * worktree moved out of the folder), so only the latest updates what is known of it; an earlier one settles with
215
+ * what the latest finds, without what the id was, since the latest tells a move itself, or once the entry was removed
216
+ * since, with what the removal found it was. One that can't read the entry forgets what it was known to be, since git
217
+ * may be writing its `gitdir` again, and reads it once more a moment later, unless `retry` is false (it then leaves
218
+ * what is known as it was); one that can settles that read, if pending.
219
+ */
220
+ private readWorktreeId;
221
+ /** Reads the entry once more a moment later, unless that is already pending; `previous` is what it was known to be */
222
+ private scheduleWorktreeRetry;
223
+ /**
224
+ * A report whose read couldn't read the entry waits on the entry's next read, and `deliver` is told then, unless that
225
+ * read finds an ignored worktree's; one still unreadable is told. Both watchers report each change of an entry, so
226
+ * the reports of one id wait on one read. Resolves with what it found, as {@link settleWorktreeRetry} does
227
+ */
228
+ private waitForWorktreeRetry;
229
+ /**
230
+ * Tells the reports waiting on the id's retry what the entry turned out to be: nothing when an ignored worktree's,
231
+ * every session when it moved into or out of an ignored folder, and the reports' own sessions otherwise, `ignored`
232
+ * being `undefined` when it still couldn't be read
233
+ */
234
+ private settleWorktreeRetry;
235
+ /**
236
+ * Takes `id` as removed, remembering what it was for the removal's other reports; returns that, or `undefined` when
237
+ * the id was never known
238
+ */
239
+ private forgetWorktreeId;
240
+ /** Whether the entry's `gitdir` names an ignored worktree, or `undefined` when it can't be read. Never rejects */
241
+ private readIgnoredWorktree;
242
+ private queueWorktreesBaseline;
243
+ /** A watcher of the `worktrees` directory dropped events: whatever changed meanwhile went unseen */
244
+ private rebaselineWorktrees;
245
+ /** The watchers' reports of the directory pile onto one queued listing, which tells them apart */
246
+ private queueWorktreesRescan;
247
+ /**
248
+ * Lists the admin entries and compares them with the last listing. A baseline (or a rebaseline, after a watcher
249
+ * dropped events) reads every entry; a rescan only those it doesn't know, reading one it can't read once more a
250
+ * moment later. Git removes the directory with its last entry, so a directory that isn't there is an empty listing,
251
+ * whatever the reports said of it (a poll sees its removal as a change). A listing that fails otherwise is a
252
+ * baseline's empty directory, and a rescan's too when one of its reports (`delivers`) removed the directory. For any
253
+ * other rescan, it is a change it can't rule out, told to the reports' own sessions
254
+ */
255
+ private listWorktrees;
256
+ private deliverWorktreesChange;
122
257
  private onConfigReported;
123
258
  private readConfigBaseline;
124
259
  /** Reads and compares until no report came in during the last read: it may describe a change the read missed */
125
260
  private readConfigChanges;
126
261
  /** `undefined` when the file couldn't be read or parsed, or the read didn't settle in time */
127
262
  private readConfig;
263
+ /** `undefined` when the file couldn't be read, or the read didn't settle in time */
264
+ private readWithTimeout;
265
+ /** `undefined` when `read` rejects, or doesn't settle in time */
266
+ private withTimeout;
128
267
  /**
129
268
  * Tells every session of a change to the shared `.git/config`: confined to some branches' sections, or (`undefined`,
130
269
  * or a change outside them) anywhere, which may have changed a remote's settings too. Either way no ref moved