@gitkraken/core-gitlens 0.10.5 → 0.10.6

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 CHANGED
@@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.10.6] - 2026-10-13
10
+
11
+ ### Added
12
+
13
+ - Adds optional `getSymbolicReferenceNameOrMissing` to the refs sub-provider: `getSymbolicReferenceName`'s answer plus `missing`, which is true only when git confirmed the ref doesn't exist (`rev-parse --verify` exit 1), never for a read that didn't complete (git, git-cli)
14
+
15
+ ### Changed
16
+
17
+ - Changes `getStoredMergeTargetBranchName` to skip a stored merge target whose branch git confirms is gone: it checks the user's pick, then the detected target, returns the first that exists (resolved to its symbolic name), and keeps one it couldn't check. It takes optional `options` (`detectedOnly`, `priority`) and `cancellation`. `getStoredUserMergeTargetBranchName` and `getStoredDetectedMergeTargetBranchName` still return the raw stored values (git, git-cli)
18
+
19
+ ### Fixed
20
+
21
+ - Fixes `getBranchContributionsOverview` measuring against a merge target whose branch no longer exists: a confirmed-gone stored target or pull request base now falls through to the base and default branch, and a gone base is never stored. `storeMergeTargetBranchName` also no longer rewrites an unchanged value (git-cli)
22
+
9
23
  ## [0.10.5] - 2026-10-08
10
24
 
11
25
  ### Added
@@ -593,7 +607,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
593
607
 
594
608
  - Initial release. Bundles `@gitlens/utils`, `@gitlens/git`, `@gitlens/git-cli`, `@gitlens/ai`, and `@gitlens/git-github` into a single core npm package with subpath exports.
595
609
 
596
- [unreleased]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.10.5...HEAD
610
+ [unreleased]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.10.6...HEAD
611
+ [0.10.6]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.10.5...gitkraken:releases/core/v0.10.6
597
612
  [0.10.5]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.10.4...gitkraken:releases/core/v0.10.5
598
613
  [0.10.4]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.10.3...gitkraken:releases/core/v0.10.4
599
614
  [0.10.3]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.10.2...gitkraken:releases/core/v0.10.3
@@ -88,7 +88,10 @@ export interface GitBranchesSubProvider {
88
88
  getBaseBranchName?(repoPath: string, ref: string, options?: {
89
89
  priority?: GitCommandPriority;
90
90
  }, cancellation?: AbortSignal): Promise<string | undefined>;
91
- getStoredMergeTargetBranchName?(repoPath: string, ref: string): Promise<string | undefined>;
91
+ getStoredMergeTargetBranchName?(repoPath: string, ref: string, options?: {
92
+ detectedOnly?: boolean;
93
+ priority?: GitCommandPriority;
94
+ }, cancellation?: AbortSignal): Promise<string | undefined>;
92
95
  getStoredDetectedMergeTargetBranchName?(repoPath: string, ref: string): Promise<string | undefined>;
93
96
  getStoredUserMergeTargetBranchName?(repoPath: string, ref: string): Promise<string | undefined>;
94
97
  onCurrentBranchAccessed?(repoPath: string): Promise<void>;
@@ -45,6 +45,13 @@ export interface GitRefsSubProvider {
45
45
  getSymbolicReferenceName?(repoPath: string, ref: string, options?: {
46
46
  priority?: GitCommandPriority;
47
47
  }, cancellation?: AbortSignal): Promise<string | undefined>;
48
+ /** Like `getSymbolicReferenceName`, but `missing` is true only when git confirmed the ref doesn't exist; a read that didn't complete never reports missing. */
49
+ getSymbolicReferenceNameOrMissing?(repoPath: string, ref: string, options?: {
50
+ priority?: GitCommandPriority;
51
+ }, cancellation?: AbortSignal): Promise<{
52
+ name: string | undefined;
53
+ missing: boolean;
54
+ }>;
48
55
  hasBranchOrTag(repoPath: string | undefined, options?: {
49
56
  filter?: {
50
57
  branches?: ((b: GitBranch) => boolean) | undefined;
@@ -13,8 +13,8 @@ import { getChangesForCommand, leadingCommand } from "./commandClassifier.js";
13
13
  import { EventLoopMonitor } from "./eventLoopMonitor.js";
14
14
  import { GitQueue, getPrimaryGitCommand, inferGitCommandPriority } from "./gitQueue.js";
15
15
  import { resolve } from "path";
16
- import { spawn } from "child_process";
17
16
  import * as process from "process";
17
+ import { spawn } from "child_process";
18
18
  //#region ../git-cli/src/exec/git.ts
19
19
  const slowCallWarningThreshold = 2e3;
20
20
  /** Below this, a queue-wait annotation isn't worth adding to the log line. */
@@ -99,7 +99,16 @@ export declare class BranchesGitSubProvider implements GitBranchesSubProvider {
99
99
  * caches the former forever and must not cache the latter.
100
100
  */
101
101
  private getBaseBranchFromReflog;
102
- getStoredMergeTargetBranchName(repoPath: string, ref: string): Promise<string | undefined>;
102
+ /**
103
+ * The stored merge target — the user's pick, else the one detected from its PR — skipping any whose branch git
104
+ * confirms is gone so resolution falls through to the next source. A target that couldn't be checked is kept.
105
+ * The stored keys are never rewritten here: the user pick is the user's, and Kepler shares the file.
106
+ */
107
+ getStoredMergeTargetBranchName(repoPath: string, ref: string, options?: {
108
+ detectedOnly?: boolean;
109
+ priority?: GitCommandPriority;
110
+ }, cancellation?: AbortSignal): Promise<string | undefined>;
111
+ private resolveStoredMergeTarget;
103
112
  getStoredDetectedMergeTargetBranchName(repoPath: string, ref: string): Promise<string | undefined>;
104
113
  getStoredUserMergeTargetBranchName(repoPath: string, ref: string): Promise<string | undefined>;
105
114
  /** Updates the last accessed timestamp for the current branch */
@@ -240,15 +240,18 @@ var BranchesGitSubProvider = class {
240
240
  };
241
241
  try {
242
242
  let mergeTarget;
243
- const storedTarget = await this.getStoredMergeTargetBranchName(repoPath, ref);
244
- if (storedTarget) mergeTarget = await this.provider.refs.getSymbolicReferenceName(repoPath, storedTarget, priorityOpts, cancellation) || storedTarget;
243
+ mergeTarget = await this.getStoredMergeTargetBranchName(repoPath, ref, priorityOpts, cancellation);
245
244
  if (mergeTarget == null && options?.associatedPullRequest != null) {
246
245
  const pr = await options.associatedPullRequest;
247
246
  if (pr?.refs?.base != null) {
248
247
  const branch = await this.getBranch(repoPath, ref, void 0, cancellation);
249
248
  if (branch == null) return void 0;
250
- mergeTarget = `${branch.remoteName}/${pr.refs.base.branch}`;
251
- if (pr.stack == null) this.storeMergeTargetBranchName(repoPath, ref, mergeTarget, { skipInvalidation: ["branchOverviews"] });
249
+ const prTarget = `${branch.remoteName}/${pr.refs.base.branch}`;
250
+ const { missing } = await this.provider.refs.getSymbolicReferenceNameOrMissing(repoPath, prTarget, priorityOpts, cancellation);
251
+ if (!missing) {
252
+ mergeTarget = prTarget;
253
+ if (pr.stack == null) this.storeMergeTargetBranchName(repoPath, ref, prTarget, { skipInvalidation: ["branchOverviews"] });
254
+ }
252
255
  }
253
256
  }
254
257
  mergeTarget ??= await this.getBaseBranchName(repoPath, ref, priorityOpts, cancellation);
@@ -973,8 +976,29 @@ var BranchesGitSubProvider = class {
973
976
  failed: false
974
977
  };
975
978
  }
976
- async getStoredMergeTargetBranchName(repoPath, ref) {
977
- return (await this.getStoredUserMergeTargetBranchName?.(repoPath, ref) ?? await this.getStoredDetectedMergeTargetBranchName?.(repoPath, ref))?.trim() || void 0;
979
+ /**
980
+ * The stored merge target — the user's pick, else the one detected from its PR — skipping any whose branch git
981
+ * confirms is gone so resolution falls through to the next source. A target that couldn't be checked is kept.
982
+ * The stored keys are never rewritten here: the user pick is the user's, and Kepler shares the file.
983
+ */
984
+ async getStoredMergeTargetBranchName(repoPath, ref, options, cancellation) {
985
+ const priority = options?.priority;
986
+ let goneUserTarget;
987
+ if (!options?.detectedOnly) {
988
+ const userTarget = await this.getStoredUserMergeTargetBranchName(repoPath, ref);
989
+ if (userTarget) {
990
+ const resolved = await this.resolveStoredMergeTarget(repoPath, userTarget, priority, cancellation);
991
+ if (resolved) return resolved;
992
+ goneUserTarget = userTarget;
993
+ }
994
+ }
995
+ const detectedTarget = await this.getStoredDetectedMergeTargetBranchName(repoPath, ref);
996
+ if (!detectedTarget || detectedTarget === goneUserTarget) return void 0;
997
+ return this.resolveStoredMergeTarget(repoPath, detectedTarget, priority, cancellation);
998
+ }
999
+ async resolveStoredMergeTarget(repoPath, target, priority, cancellation) {
1000
+ const { name, missing } = await this.provider.refs.getSymbolicReferenceNameOrMissing(repoPath, target, priority != null ? { priority } : void 0, cancellation);
1001
+ return missing ? void 0 : name || target;
978
1002
  }
979
1003
  async getStoredDetectedMergeTargetBranchName(repoPath, ref) {
980
1004
  return (await this.provider.config.getGkConfig(repoPath, `branch.${ref}.gk-merge-target`) ?? await this.provider.config.getGkConfig(repoPath, `branch.${ref}.gk-target-base`))?.trim() || void 0;
@@ -1059,6 +1083,7 @@ var BranchesGitSubProvider = class {
1059
1083
  await this.provider.config.setGkConfig(repoPath, `branch.${ref}.gk-merge-base`, base, options);
1060
1084
  }
1061
1085
  async storeMergeTargetBranchName(repoPath, ref, target, options) {
1086
+ if (await this.provider.config.getGkConfig(repoPath, `branch.${ref}.gk-merge-target`) === target) return;
1062
1087
  await this.provider.config.setGkConfig(repoPath, `branch.${ref}.gk-merge-target`, target, options);
1063
1088
  }
1064
1089
  async storeUserMergeTargetBranchName(repoPath, ref, target) {