@gitkraken/core-gitlens 0.17.0 → 0.18.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.
- package/CHANGELOG.md +4 -1
- package/dist/git/cache.d.ts +7 -0
- package/dist/git/cache.js +21 -3
- package/dist/git/cache.js.map +1 -1
- package/dist/git/watching/gitIgnoreFilter.d.ts +21 -3
- package/dist/git/watching/gitIgnoreFilter.js +74 -14
- package/dist/git/watching/gitIgnoreFilter.js.map +1 -1
- package/dist/git/watching/provider.d.ts +9 -1
- package/dist/git/watching/watchService.d.ts +14 -1
- package/dist/git/watching/watchService.js +57 -16
- package/dist/git/watching/watchService.js.map +1 -1
- package/dist/git/watching/worktreeSummary.d.ts +38 -10
- package/dist/git/watching/worktreeSummary.js +164 -50
- package/dist/git/watching/worktreeSummary.js.map +1 -1
- package/dist/git-cli/cliGitProvider.js +4 -4
- package/dist/git-cli/cliGitProvider.js.map +1 -1
- package/dist/git-cli/providers/branches.js +1 -32
- package/dist/git-cli/providers/branches.js.map +1 -1
- package/dist/git-cli/providers/config.d.ts +21 -0
- package/dist/git-cli/providers/config.js +72 -1
- package/dist/git-cli/providers/config.js.map +1 -1
- package/dist/plus/integrations/providers/issueSorts.d.ts +0 -1
- package/dist/plus/integrations/reads/drains.d.ts +0 -1
- package/package.json +1 -1
|
@@ -25,6 +25,7 @@ const allFields = 7;
|
|
|
25
25
|
const maxConcurrentReadsPerRepository = 4;
|
|
26
26
|
const maxConcurrentReads = 8;
|
|
27
27
|
const maxUnwatchedReads = 256;
|
|
28
|
+
const maxDeferredDirtyMs = 1e4;
|
|
28
29
|
const emptyRefs = Object.freeze([]);
|
|
29
30
|
const noBaseKeys = [
|
|
30
31
|
void 0,
|
|
@@ -66,6 +67,9 @@ var SummarySubscription = class {
|
|
|
66
67
|
get current() {
|
|
67
68
|
return this.disposed ? void 0 : this.entry.value;
|
|
68
69
|
}
|
|
70
|
+
get dirtyReadAt() {
|
|
71
|
+
return this.disposed || this.entry.value == null ? void 0 : this.entry.dirtyReadAt;
|
|
72
|
+
}
|
|
69
73
|
get onDidChange() {
|
|
70
74
|
return this.emitter.event;
|
|
71
75
|
}
|
|
@@ -101,7 +105,10 @@ var SummarySubscription = class {
|
|
|
101
105
|
* has working changes, and how far it is past its base — kept current by the repository watch layer.
|
|
102
106
|
*
|
|
103
107
|
* **Lifecycle.** Entries are per repository key and ref-counted across {@link subscribe} calls. The first subscriber
|
|
104
|
-
* starts watching the worktree and reads everything
|
|
108
|
+
* starts watching the worktree and reads everything, or, for a worktree last read without a subscription, starts from
|
|
109
|
+
* that read: it re-reads the groups whose inputs moved since, by the same rules as such a read, and always `dirty` —
|
|
110
|
+
* unless its working-tree watch is still starting, when the rescan that watch owes reads it, and the summary keeps the
|
|
111
|
+
* saved read's flag, with its `dirtyReadAt`, until then. The last one to leave aborts any in-flight read, releases the
|
|
105
112
|
* watch and drops the value. Each subscriber's timing options join the watch session's cadence (the shortest wins);
|
|
106
113
|
* the service's own listening subscriptions never constrain it.
|
|
107
114
|
*
|
|
@@ -128,7 +135,8 @@ var SummarySubscription = class {
|
|
|
128
135
|
* **Value-change-only notification.** {@link WorktreeSummarySubscription.onDidChange} and {@link onDidChangeSummary}
|
|
129
136
|
* fire only when some field's value differs from the previous summary — a recompute that reads the same answer is
|
|
130
137
|
* silent, so a consumer can re-render on every event without diffing. A failed recompute keeps the last values and
|
|
131
|
-
* sets `stale` (firing once); the next successful one clears it.
|
|
138
|
+
* sets `stale` (firing once); the next successful one clears it. A summary still showing the dirty flag of a read
|
|
139
|
+
* without a subscription fires again, unchanged, once that flag is read again (its `dirtyReadAt` cleared).
|
|
132
140
|
*
|
|
133
141
|
* **Worktrees without a subscription.** {@link getSummary} and {@link getSummarySnapshot} answer one from its last read
|
|
134
142
|
* (kept for the {@link maxUnwatchedReads} most recently asked), re-reading only the groups whose inputs moved since:
|
|
@@ -140,11 +148,14 @@ var SummarySubscription = class {
|
|
|
140
148
|
* asks about this way for others' changes to show. Its working tree is unwatched, so an edit that leaves the index
|
|
141
149
|
* alone goes unseen until `dirty` is read again: the snapshot says when that was, and `probeDirty` reads it anyway.
|
|
142
150
|
* Concurrent reads of a worktree share one, and take no read slot: each is a caller's foreground read, which never
|
|
143
|
-
* waits behind subscribed worktrees' runs.
|
|
151
|
+
* waits behind subscribed worktrees' runs. A first subscriber takes over the last read.
|
|
144
152
|
*/
|
|
145
153
|
var WorktreeSummaryService = class {
|
|
146
154
|
_onDidChangeSummary = new Emitter();
|
|
147
|
-
/**
|
|
155
|
+
/**
|
|
156
|
+
* Fires when the summary of any subscribed worktree changes value, and with the same summary when a dirty flag kept
|
|
157
|
+
* from a read without a subscription is read again (see {@link WorktreeSummarySubscription.dirtyReadAt})
|
|
158
|
+
*/
|
|
148
159
|
get onDidChangeSummary() {
|
|
149
160
|
return this._onDidChangeSummary.event;
|
|
150
161
|
}
|
|
@@ -192,7 +203,11 @@ var WorktreeSummaryService = class {
|
|
|
192
203
|
this.entries.clear();
|
|
193
204
|
this._onDidChangeSummary.dispose();
|
|
194
205
|
}
|
|
195
|
-
/**
|
|
206
|
+
/**
|
|
207
|
+
* Subscribes to a worktree's summary, starting to watch and read it if this is its first subscriber: from its last
|
|
208
|
+
* read without a subscription, if any, re-reading the groups whose inputs moved since and the dirty flag — at once,
|
|
209
|
+
* or, while its working-tree watch is still starting, as that watch goes live
|
|
210
|
+
*/
|
|
196
211
|
subscribe(repoPath, options) {
|
|
197
212
|
const key = getRepositoryKey(repoPath);
|
|
198
213
|
let entry = this._disposed ? void 0 : this.entries.get(key);
|
|
@@ -207,16 +222,11 @@ var WorktreeSummaryService = class {
|
|
|
207
222
|
target.subscribers.add(subscription);
|
|
208
223
|
if (isNew) {
|
|
209
224
|
if (!target.disposed) {
|
|
210
|
-
this.unwatchedReads.delete(key);
|
|
211
225
|
this.unwatchedFlights.delete(key);
|
|
212
|
-
target.pending = 23;
|
|
213
226
|
target.running = this.start(target);
|
|
214
227
|
}
|
|
215
228
|
} else if (target.handle != null) subscription.attach(target.handle.session);
|
|
216
|
-
else if (target.running == null && !target.disposed)
|
|
217
|
-
target.pending = 23;
|
|
218
|
-
target.running = this.start(target);
|
|
219
|
-
}
|
|
229
|
+
else if (target.running == null && !target.disposed) target.running = this.start(target);
|
|
220
230
|
return subscription;
|
|
221
231
|
}
|
|
222
232
|
/**
|
|
@@ -232,7 +242,8 @@ var WorktreeSummaryService = class {
|
|
|
232
242
|
}
|
|
233
243
|
/**
|
|
234
244
|
* Returns a worktree's summary, with when its dirty flag was read. A subscribed worktree answers as
|
|
235
|
-
* {@link getSummary} does, with `dirtyReadAt` `undefined
|
|
245
|
+
* {@link getSummary} does, with `dirtyReadAt` `undefined` once its summary follows its working tree, and until then
|
|
246
|
+
* the saved read's (see {@link WorktreeSummarySubscription.dirtyReadAt}), which `probeDirty` reads again. Any other
|
|
236
247
|
* answers from its last read, re-reading only the groups whose inputs moved since (no git when none did), and in
|
|
237
248
|
* full the first time, or after a failed or stale read. Its working tree is unwatched, so the dirty flag is re-read
|
|
238
249
|
* only when the index file moved, or with `probeDirty`; a rejection drops the last read. Its inputs are core's
|
|
@@ -242,9 +253,17 @@ var WorktreeSummaryService = class {
|
|
|
242
253
|
const key = getRepositoryKey(repoPath);
|
|
243
254
|
const entry = this.entries.get(key);
|
|
244
255
|
if (entry == null) return this.getUnwatchedSnapshot(key, options?.probeDirty ?? false, options?.cancellation);
|
|
256
|
+
return this.getSubscribedSnapshot(entry, options?.probeDirty ?? false, options?.cancellation);
|
|
257
|
+
}
|
|
258
|
+
async getSubscribedSnapshot(entry, probeDirty, cancellation) {
|
|
259
|
+
let summary = await this.getSubscribedSummary(entry, cancellation);
|
|
260
|
+
if (probeDirty && entry.dirtyReadAt != null) {
|
|
261
|
+
this.queue(entry, dirtyField);
|
|
262
|
+
summary = await this.getSubscribedSummary(entry, cancellation);
|
|
263
|
+
}
|
|
245
264
|
return {
|
|
246
|
-
summary
|
|
247
|
-
dirtyReadAt:
|
|
265
|
+
summary,
|
|
266
|
+
dirtyReadAt: entry.dirtyReadAt
|
|
248
267
|
};
|
|
249
268
|
}
|
|
250
269
|
async getSubscribedSummary(entry, cancellation) {
|
|
@@ -269,10 +288,7 @@ var WorktreeSummaryService = class {
|
|
|
269
288
|
if (flight === waited) flight = void 0;
|
|
270
289
|
}
|
|
271
290
|
const entry = this.entries.get(key);
|
|
272
|
-
if (entry != null) return
|
|
273
|
-
summary: await this.getSubscribedSummary(entry, cancellation),
|
|
274
|
-
dirtyReadAt: void 0
|
|
275
|
-
};
|
|
291
|
+
if (entry != null) return this.getSubscribedSnapshot(entry, true, cancellation);
|
|
276
292
|
}
|
|
277
293
|
if (flight == null) {
|
|
278
294
|
flight = new UnwatchedFlight(key, probeDirty, this._disposed, (f) => this.readUnwatched(f));
|
|
@@ -313,33 +329,14 @@ var WorktreeSummaryService = class {
|
|
|
313
329
|
const repo = this.getRepository(key);
|
|
314
330
|
if (repo == null) throw new Error(`No repository found for '${key}'`);
|
|
315
331
|
const headRemotes = last != null ? getHeadRemotes(last.result.summary.baseDependsOn) : void 0;
|
|
316
|
-
const probe = await this.probeUnwatched(repo, headRemotes, signal);
|
|
332
|
+
const probe = await this.probeUnwatched(repo, headRemotes, true, signal);
|
|
317
333
|
if (flight.disposed) throw new CancellationError();
|
|
318
334
|
let fields;
|
|
319
335
|
let baseMoves;
|
|
320
336
|
if (last == null) fields = 23;
|
|
321
337
|
else {
|
|
322
|
-
fields = last.
|
|
323
|
-
|
|
324
|
-
const previous = last.result.summary;
|
|
325
|
-
if (probe.branch !== inputs.branch || probe.detached !== inputs.detached || probe.sha !== inputs.sha) fields |= allFields;
|
|
326
|
-
else {
|
|
327
|
-
if (probe.upstream !== inputs.upstream) fields |= 18;
|
|
328
|
-
else if (getUpstreamTips(probe.tips, probe.upstream) !== inputs.upstreamTips) fields |= branchField;
|
|
329
|
-
for (const ref of previous.baseDependsOn) {
|
|
330
|
-
const value = getBaseInput(probe, ref);
|
|
331
|
-
if (value !== null && value === inputs.baseTips.get(ref)) continue;
|
|
332
|
-
baseMoves ??= /* @__PURE__ */ new Set();
|
|
333
|
-
baseMoves.add(ref);
|
|
334
|
-
}
|
|
335
|
-
if (baseMoves != null) fields |= baseMoveField;
|
|
336
|
-
if ((fields & baseConfigField) === 0 && last.result.baseConfigKey != null && repo.branches.getAheadOfBase != null && (probe.detached || probe.branch != null)) {
|
|
337
|
-
const configKey = getBaseConfigKey(await readBaseConfig(repo, signal), previous);
|
|
338
|
-
if (flight.disposed) throw new CancellationError();
|
|
339
|
-
if (configKey != null && configKey !== last.result.baseConfigKey) fields |= 18;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
if (flight.probeDirty || probe.index == null || probe.index !== inputs.index) fields |= dirtyField;
|
|
338
|
+
({fields, baseMoves} = await getMovedFields(repo, last, probe, flight.probeDirty, signal));
|
|
339
|
+
if (flight.disposed) throw new CancellationError();
|
|
343
340
|
if (fields === 0) {
|
|
344
341
|
this.unwatchedReads.touch(key);
|
|
345
342
|
return last;
|
|
@@ -370,18 +367,18 @@ var WorktreeSummaryService = class {
|
|
|
370
367
|
}
|
|
371
368
|
/**
|
|
372
369
|
* Reads an unwatched read's inputs: cached answers but for the index file's stat (see {@link UnwatchedInputs}), with
|
|
373
|
-
* the `HEAD` symrefs of `remotes` (every remote's when `undefined`)
|
|
370
|
+
* the `HEAD` symrefs of `remotes` (every remote's when `undefined`); without `statIndex`, the index is unknown
|
|
374
371
|
*/
|
|
375
|
-
async probeUnwatched(repo, remotes, signal) {
|
|
372
|
+
async probeUnwatched(repo, remotes, statIndex, signal) {
|
|
376
373
|
const remoteHeads = /* @__PURE__ */ new Map();
|
|
374
|
+
const stat = statIndex ? this.stat : void 0;
|
|
377
375
|
const [current, tips, gitDir] = await Promise.all([
|
|
378
376
|
repo.branches.getBranch(void 0, void 0, signal),
|
|
379
377
|
repo.refs.getRefTips(void 0, signal),
|
|
380
|
-
getGitDir(repo),
|
|
378
|
+
stat != null ? getGitDir(repo) : void 0,
|
|
381
379
|
readRemoteHeads(repo, remoteHeads, remotes, signal)
|
|
382
380
|
]);
|
|
383
381
|
let index;
|
|
384
|
-
const stat = this.stat;
|
|
385
382
|
if (stat != null && gitDir != null) try {
|
|
386
383
|
const stats = await stat(joinPaths(gitDir.uri.fsPath, "index"));
|
|
387
384
|
index = stats != null ? `${stats.size}:${stats.mtime}` : "";
|
|
@@ -419,6 +416,15 @@ var WorktreeSummaryService = class {
|
|
|
419
416
|
this.fail(entry, /* @__PURE__ */ new Error(`Unable to watch '${entry.key}': no repository or git directory`));
|
|
420
417
|
return;
|
|
421
418
|
}
|
|
419
|
+
let last = this.unwatchedReads.get(entry.key);
|
|
420
|
+
this.unwatchedReads.delete(entry.key);
|
|
421
|
+
if (last?.result.summary.stale) last = void 0;
|
|
422
|
+
if (last != null) {
|
|
423
|
+
entry.seed = last.result.summary;
|
|
424
|
+
entry.baseKeys = last.result.baseKeys;
|
|
425
|
+
entry.baseConfigKey = last.result.baseConfigKey;
|
|
426
|
+
entry.baseDefaultBranch = last.result.baseDefaultBranch;
|
|
427
|
+
} else entry.pending |= 23;
|
|
422
428
|
entry.handle = handle;
|
|
423
429
|
entry.slotsKey = getRepositoryKey(gitDir.commonUri ?? gitDir.uri);
|
|
424
430
|
const session = handle.session;
|
|
@@ -437,10 +443,56 @@ var WorktreeSummaryService = class {
|
|
|
437
443
|
workingTreeSub
|
|
438
444
|
];
|
|
439
445
|
for (const subscription of entry.subscribers) subscription.attach(session);
|
|
446
|
+
if (last != null) {
|
|
447
|
+
await this.queueSeedStart(entry, last, this.watchService.isWorkingTreeStarting(entry.key));
|
|
448
|
+
if (entry.disposed) return;
|
|
449
|
+
}
|
|
440
450
|
await this.drain(entry);
|
|
441
451
|
}
|
|
452
|
+
/**
|
|
453
|
+
* Queues the groups of the saved read `last` whose inputs moved since, as an unwatched read finds them, and the
|
|
454
|
+
* dirty flag, which no input vouches for; everything when its inputs can't be read. With `deferDirty`, the dirty
|
|
455
|
+
* flag is left to the rescan of a working-tree watch still starting, and the value keeps `last`'s until then
|
|
456
|
+
*/
|
|
457
|
+
async queueSeedStart(entry, last, deferDirty) {
|
|
458
|
+
const signal = entry.abort.signal;
|
|
459
|
+
let moved;
|
|
460
|
+
try {
|
|
461
|
+
const repo = this.getRepository(entry.key);
|
|
462
|
+
if (repo != null) {
|
|
463
|
+
const probe = await this.probeUnwatched(repo, getHeadRemotes(last.result.summary.baseDependsOn), false, signal);
|
|
464
|
+
if (entry.disposed) return;
|
|
465
|
+
moved = await getMovedFields(repo, last, probe, true, signal);
|
|
466
|
+
}
|
|
467
|
+
} catch {}
|
|
468
|
+
if (entry.disposed) return;
|
|
469
|
+
if (moved == null) {
|
|
470
|
+
dropSeed(entry);
|
|
471
|
+
entry.pending |= 23;
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
if (deferDirty) {
|
|
475
|
+
entry.pending |= moved.fields & -2;
|
|
476
|
+
entry.dirtyReadAt = last.dirtyReadAt;
|
|
477
|
+
entry.dirtyReadTimer = setTimeout(() => {
|
|
478
|
+
entry.dirtyReadTimer = void 0;
|
|
479
|
+
this.queue(entry, dirtyField);
|
|
480
|
+
}, maxDeferredDirtyMs);
|
|
481
|
+
if (entry.pending === 0 && entry.seed != null) {
|
|
482
|
+
const seed = entry.seed;
|
|
483
|
+
entry.error = void 0;
|
|
484
|
+
entry.seed = void 0;
|
|
485
|
+
entry.value = seed;
|
|
486
|
+
this.fireChange(entry, seed);
|
|
487
|
+
}
|
|
488
|
+
} else entry.pending |= moved.fields;
|
|
489
|
+
if (moved.baseMoves != null) {
|
|
490
|
+
entry.baseMoves ??= /* @__PURE__ */ new Set();
|
|
491
|
+
for (const ref of moved.baseMoves) entry.baseMoves.add(ref);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
442
494
|
onRepoChanged(entry, e) {
|
|
443
|
-
const value = entry.value;
|
|
495
|
+
const value = entry.value ?? entry.seed;
|
|
444
496
|
if (value == null || e.changed("unknown", "head")) {
|
|
445
497
|
this.queue(entry, allFields | (e.changed("config") ? baseConfigField : 0));
|
|
446
498
|
return;
|
|
@@ -497,7 +549,8 @@ var WorktreeSummaryService = class {
|
|
|
497
549
|
}
|
|
498
550
|
queue(entry, fields, baseMoves) {
|
|
499
551
|
if (entry.disposed || fields === 0) return;
|
|
500
|
-
|
|
552
|
+
const value = entry.value ?? entry.seed;
|
|
553
|
+
entry.pending |= value == null || value.stale ? fields | 23 : fields;
|
|
501
554
|
if (baseMoves != null) {
|
|
502
555
|
entry.baseMoves ??= /* @__PURE__ */ new Set();
|
|
503
556
|
for (const ref of baseMoves) entry.baseMoves.add(ref);
|
|
@@ -559,7 +612,8 @@ var WorktreeSummaryService = class {
|
|
|
559
612
|
return true;
|
|
560
613
|
}
|
|
561
614
|
async run(entry, fields, baseMoves) {
|
|
562
|
-
const
|
|
615
|
+
const { value, seed } = entry;
|
|
616
|
+
const previous = value ?? seed;
|
|
563
617
|
let result;
|
|
564
618
|
try {
|
|
565
619
|
const repo = this.getRepository(entry.key);
|
|
@@ -573,16 +627,27 @@ var WorktreeSummaryService = class {
|
|
|
573
627
|
if (entry.disposed) return;
|
|
574
628
|
if (result.summary.stale && (previous == null || !previous.stale)) _logger.warn(`WorktreeSummaryService: reading the base of '${entry.key}' failed: ${String(result.baseError)}`);
|
|
575
629
|
entry.error = void 0;
|
|
630
|
+
entry.seed = void 0;
|
|
576
631
|
entry.baseKeys = result.baseKeys;
|
|
577
632
|
entry.baseConfigKey = entry.pending & baseConfigField ? void 0 : result.baseConfigKey;
|
|
578
633
|
entry.baseDefaultBranch = result.baseDefaultBranch;
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
634
|
+
const dirtyConfirmed = result.dirtyReadAt != null && entry.dirtyReadAt != null;
|
|
635
|
+
if (dirtyConfirmed) clearDeferredDirty(entry);
|
|
636
|
+
if (value != null && summariesEqual(value, result.summary)) {
|
|
637
|
+
if (dirtyConfirmed) this.fireChange(entry, value);
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
const summary = value == null && seed != null && summariesEqual(seed, result.summary) ? seed : result.summary;
|
|
641
|
+
entry.value = summary;
|
|
642
|
+
this.fireChange(entry, summary);
|
|
582
643
|
}
|
|
583
644
|
fail(entry, ex) {
|
|
584
645
|
const previous = entry.value;
|
|
585
646
|
if (previous == null) {
|
|
647
|
+
if (entry.seed != null) {
|
|
648
|
+
dropSeed(entry);
|
|
649
|
+
if (entry.pending !== 0) entry.pending |= 23;
|
|
650
|
+
}
|
|
586
651
|
if (entry.error == null) _logger.warn(`WorktreeSummaryService: reading '${entry.key}' failed: ${String(ex)}`);
|
|
587
652
|
entry.error = ex instanceof Error ? ex : new Error(String(ex));
|
|
588
653
|
return;
|
|
@@ -617,6 +682,8 @@ var WorktreeSummaryService = class {
|
|
|
617
682
|
entry.handle?.dispose();
|
|
618
683
|
entry.handle = void 0;
|
|
619
684
|
entry.value = void 0;
|
|
685
|
+
entry.seed = void 0;
|
|
686
|
+
clearDeferredDirty(entry);
|
|
620
687
|
entry.baseKeys = void 0;
|
|
621
688
|
entry.baseConfigKey = void 0;
|
|
622
689
|
entry.baseDefaultBranch = void 0;
|
|
@@ -635,6 +702,19 @@ function* getConfigRelevantRefs(value) {
|
|
|
635
702
|
if (value.upstream != null) yield `refs/heads/${value.upstream.name}`;
|
|
636
703
|
yield* value.baseDependsOn;
|
|
637
704
|
}
|
|
705
|
+
/** Drops the saved read a first run was to start from, with the values its base read consulted and its dirty flag */
|
|
706
|
+
function dropSeed(entry) {
|
|
707
|
+
entry.seed = void 0;
|
|
708
|
+
clearDeferredDirty(entry);
|
|
709
|
+
entry.baseKeys = void 0;
|
|
710
|
+
entry.baseConfigKey = void 0;
|
|
711
|
+
entry.baseDefaultBranch = void 0;
|
|
712
|
+
}
|
|
713
|
+
function clearDeferredDirty(entry) {
|
|
714
|
+
entry.dirtyReadAt = void 0;
|
|
715
|
+
clearTimeout(entry.dirtyReadTimer);
|
|
716
|
+
entry.dirtyReadTimer = void 0;
|
|
717
|
+
}
|
|
638
718
|
function createEntry(key) {
|
|
639
719
|
return {
|
|
640
720
|
key,
|
|
@@ -644,6 +724,9 @@ function createEntry(key) {
|
|
|
644
724
|
handle: void 0,
|
|
645
725
|
listeners: void 0,
|
|
646
726
|
value: void 0,
|
|
727
|
+
seed: void 0,
|
|
728
|
+
dirtyReadAt: void 0,
|
|
729
|
+
dirtyReadTimer: void 0,
|
|
647
730
|
baseKeys: void 0,
|
|
648
731
|
baseConfigKey: void 0,
|
|
649
732
|
baseDefaultBranch: void 0,
|
|
@@ -807,6 +890,37 @@ function getTipsByName(tips) {
|
|
|
807
890
|
}
|
|
808
891
|
return byName;
|
|
809
892
|
}
|
|
893
|
+
/**
|
|
894
|
+
* The read groups due on a read from `last`, given what `probe` found of its inputs since (with the refs the base
|
|
895
|
+
* depends on that moved): those `last` made due, and those whose inputs moved
|
|
896
|
+
*/
|
|
897
|
+
async function getMovedFields(repo, last, probe, probeDirty, signal) {
|
|
898
|
+
let fields = last.due;
|
|
899
|
+
let baseMoves;
|
|
900
|
+
const { inputs } = last;
|
|
901
|
+
const previous = last.result.summary;
|
|
902
|
+
if (probe.branch !== inputs.branch || probe.detached !== inputs.detached || probe.sha !== inputs.sha) fields |= allFields;
|
|
903
|
+
else {
|
|
904
|
+
if (probe.upstream !== inputs.upstream) fields |= 18;
|
|
905
|
+
else if (getUpstreamTips(probe.tips, probe.upstream) !== inputs.upstreamTips) fields |= branchField;
|
|
906
|
+
for (const ref of previous.baseDependsOn) {
|
|
907
|
+
const value = getBaseInput(probe, ref);
|
|
908
|
+
if (value !== null && value === inputs.baseTips.get(ref)) continue;
|
|
909
|
+
baseMoves ??= /* @__PURE__ */ new Set();
|
|
910
|
+
baseMoves.add(ref);
|
|
911
|
+
}
|
|
912
|
+
if (baseMoves != null) fields |= baseMoveField;
|
|
913
|
+
if ((fields & baseConfigField) === 0 && last.result.baseConfigKey != null && repo.branches.getAheadOfBase != null && (probe.detached || probe.branch != null)) {
|
|
914
|
+
const configKey = getBaseConfigKey(await readBaseConfig(repo, signal), previous);
|
|
915
|
+
if (configKey != null && configKey !== last.result.baseConfigKey) fields |= 18;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
if (probeDirty || probe.index == null || probe.index !== inputs.index) fields |= dirtyField;
|
|
919
|
+
return {
|
|
920
|
+
fields,
|
|
921
|
+
baseMoves
|
|
922
|
+
};
|
|
923
|
+
}
|
|
810
924
|
/** The upstream's tips as a remote-tracking and as a local branch, since its short name doesn't say which */
|
|
811
925
|
function getUpstreamTips(tips, upstream) {
|
|
812
926
|
if (upstream == null) return void 0;
|