@gitkraken/core-gitlens 0.9.1 → 0.9.3
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 +26 -1
- package/dist/git/providers/diff.d.ts +9 -0
- package/dist/git-cli/providers/diff.d.ts +7 -1
- package/dist/git-cli/providers/diff.js +28 -6
- package/dist/git-cli/providers/diff.js.map +1 -1
- package/dist/git-cli/providers/operations.d.ts +1 -0
- package/dist/git-cli/providers/operations.js +36 -22
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/plus/git-github/api/github.js +1 -1
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/git-github/providers/github/diff.d.ts +3 -1
- package/dist/plus/git-github/providers/github/diff.js +2 -1
- package/dist/plus/git-github/providers/github/diff.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +2 -1
- package/dist/plus/integrations/integrationService.js +3 -1
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +8 -0
- package/dist/plus/integrations/models/integration.js +9 -0
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/providers/azure/azure.d.ts +3 -0
- package/dist/plus/integrations/providers/azure/azure.js +18 -0
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
- package/dist/plus/integrations/providers/azure/azure.utils.d.ts +12 -0
- package/dist/plus/integrations/providers/azure/azure.utils.js +46 -0
- package/dist/plus/integrations/providers/azure/azure.utils.js.map +1 -0
- package/dist/plus/integrations/providers/azure/models.d.ts +1 -0
- package/dist/plus/integrations/providers/azure/models.js +1 -1
- package/dist/plus/integrations/providers/azure/models.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.d.ts +3 -0
- package/dist/plus/integrations/providers/azureDevOps.js +7 -0
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket/bitbucket.utils.d.ts +17 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.utils.js +25 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.utils.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +3 -0
- package/dist/plus/integrations/providers/bitbucket-server.js +7 -0
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.d.ts +3 -0
- package/dist/plus/integrations/providers/bitbucket.js +7 -0
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/jira-server.d.ts +3 -1
- package/dist/plus/integrations/providers/jira-server.js +19 -5
- package/dist/plus/integrations/providers/jira-server.js.map +1 -1
- package/dist/plus/integrations/providers/jira.d.ts +20 -3
- package/dist/plus/integrations/providers/jira.js +129 -50
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/linear.d.ts +13 -2
- package/dist/plus/integrations/providers/linear.js +41 -10
- package/dist/plus/integrations/providers/linear.js.map +1 -1
- package/dist/plus/integrations/providers/providerErrors.d.ts +11 -0
- package/dist/plus/integrations/providers/providerErrors.js +22 -1
- package/dist/plus/integrations/providers/providerErrors.js.map +1 -1
- package/dist/plus/integrations/providers/utils/discoveryCache.d.ts +36 -0
- package/dist/plus/integrations/providers/utils/discoveryCache.js +59 -0
- package/dist/plus/integrations/providers/utils/discoveryCache.js.map +1 -0
- package/dist/plus/integrations/reads/drains.js +4 -4
- package/dist/plus/integrations/reads/drains.js.map +1 -1
- package/dist/plus/integrations/reads/warnings.d.ts +11 -0
- package/dist/plus/integrations/reads/warnings.js +14 -1
- package/dist/plus/integrations/reads/warnings.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,29 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.3] - 2026-09-30
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Adds single pull request reads and URL identity parsing for Azure DevOps, Bitbucket Cloud and Bitbucket Data Center ([#5886](https://github.com/gitkraken/vscode-gitlens/issues/5886)). `Integration.getPullRequest(resource, id)` and `getPullRequestIdentityFromMaybeUrl(url)`, until now only implemented by GitHub and GitLab, resolve on these hosts too. Azure DevOps reads `{org}/{project}/_apis/git/pullrequests/{id}` — no repository required, since a pull request id is unique within the organization — with the project taken from the descriptor's `project` or else from a `{project}/_git/{repo}` or bare project name, and its URL parser decodes the path and anchors on `/_git/{repo}/pullrequest/{id}`, covering `dev.azure.com`, a Server address behind a virtual directory (dropped from the identity, so the connection's configured URL must include it), the legacy `{org}.visualstudio.com` host, and the short `{org}/_git/{repo}` form. Bitbucket Cloud and Data Center read through the strict by-id reads `getPullRequest` and `getServerPullRequest`, and their parsers accept `{workspace}/{repo}/pull-requests/{id}` and `projects/{KEY}/repos/{repo}/pull-requests/{id}` (a personal repository's `users/{slug}/repos/…` as project `~{slug}`), each rejecting the other's path shapes. Only a 404 resolves to `undefined`; every other failure reaches `getPullRequest`'s own error handling, so it is not cached as a miss (plus/integrations)
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Fixes a page-budgeted GitHub pull request sweep reporting its stop as an unrecoverable cap when the account has more than 1,000 matches — the search ceiling is now flagged only on the page where it ends the walk. This also changes an account-wide GitHub `listPullRequestsPage`: a page over the ceiling that can still continue no longer reports `page.truncated` or an `exhausted` warning, and only the page the ceiling ends on does (plus/git-github)
|
|
18
|
+
- Fixes a pull request sweep that stopped at its page budget reporting it cannot be continued once any page was capped. A read that folds several searches into one page (GitHub's per-state facets) caps them independently, so one facet reaching the 1,000-result ceiling no longer hides a sibling that a bigger budget still reaches. This reverses 0.5.102's rule that a cap outranks a budget stop: a stop with a usable cursor is now always `page-budget`, and one drain can report two warnings, the `page-budget` one and, for the part paging could not reach, one with `recovery: 'none'` (or the SDK's own `provider-limit`, when the cap came from its metadata). A consumer that treated `page-budget` as proof the provider capped nothing must now check the drain's other warnings too (plus/integrations)
|
|
19
|
+
- Fixes a tracker's project list (Jira and Jira Data Center projects and sites, Linear teams) being cached for the whole session, so a project created mid-session never appeared in `listIssueTrackerIssuesPage` or `listProjects` until a restart, and a deleted one kept being searched. The list is now dropped when the connection is re-synced (`refreshConnections()`, or `forceSync` on a read), including the copy Jira Cloud persisted for its next connect, and it expires after 5 minutes. A Jira search that fails because its project no longer exists or is no longer visible (`400` "does not exist for the field 'project'") now reads that project as empty and drops the stale list, instead of failing the whole provider on every read (#5907) (plus/integrations)
|
|
20
|
+
|
|
21
|
+
## [0.9.2] - 2026-09-30
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Adds `errors: 'throw'` to `diff.getDiff`, `getParsedDiff`, `getDiffStatus` and `getChangedFilesCount`, so a failed diff rejects instead of resolving `undefined`: with a `GitError` carrying git's `stderr` when git ran and failed (an unresolvable revision, a path that is no longer a repository, a permission denial), or with the error that kept it from starting (a deleted working directory, a missing git binary). Without it they resolve `undefined` as before (git, git-cli)
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Fixes a typed `ops.fetch`, `pull` or `push` that rejects announcing nothing, so reads kept serving what they cached before a run that had already stored some refs or stopped on a conflict, until a file watcher caught up. They announce their changes as a finished run does; a fetch that ran no git command still announces nothing (git-cli)
|
|
30
|
+
- Fixes `diff.getDiff` and `getParsedDiff` failing to diff from `HEAD` in a repository with no commits yet, where HEAD names nothing. It diffs against the empty tree, and `GitDiff.from` reports that tree's id (git-cli)
|
|
31
|
+
|
|
9
32
|
## [0.9.1] - 2026-09-29
|
|
10
33
|
|
|
11
34
|
### Added
|
|
@@ -457,7 +480,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
|
|
|
457
480
|
|
|
458
481
|
- 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.
|
|
459
482
|
|
|
460
|
-
[unreleased]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.9.
|
|
483
|
+
[unreleased]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.9.3...HEAD
|
|
484
|
+
[0.9.3]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.9.2...gitkraken:releases/core/v0.9.3
|
|
485
|
+
[0.9.2]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.9.1...gitkraken:releases/core/v0.9.2
|
|
461
486
|
[0.9.1]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.9.0...gitkraken:releases/core/v0.9.1
|
|
462
487
|
[0.9.0]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.8.0...gitkraken:releases/core/v0.9.0
|
|
463
488
|
[0.8.0]: https://github.com/gitkraken/vscode-gitlens/compare/releases/core/v0.7.2...gitkraken:releases/core/v0.8.0
|
|
@@ -3,6 +3,7 @@ import { DiffRange, RevisionUri } from "./types.js";
|
|
|
3
3
|
import { GitRevisionRange, GitRevisionRangeNotation } from "../models/revision.js";
|
|
4
4
|
import { GitDiff, GitDiffFiles, GitDiffFilter, GitDiffShortStat, ParsedGitDiff, ParsedGitDiffHunks } from "../models/diff.js";
|
|
5
5
|
import { GitFile } from "../models/file.js";
|
|
6
|
+
import { GitErrorHandling } from "../run.types.js";
|
|
6
7
|
import { DisposableTemporaryGitIndex } from "./staging.js";
|
|
7
8
|
//#region ../git/src/providers/diff.d.ts
|
|
8
9
|
export interface NextComparisonUrisResult {
|
|
@@ -21,12 +22,18 @@ export interface GitDiffSubProvider {
|
|
|
21
22
|
getChangedFilesCount(repoPath: string, to?: string, from?: string, options?: {
|
|
22
23
|
uris?: (string | Uri)[];
|
|
23
24
|
includeUntracked?: boolean;
|
|
25
|
+
errors?: GitErrorHandling;
|
|
24
26
|
}, cancellation?: AbortSignal): Promise<GitDiffShortStat | undefined>;
|
|
25
27
|
getDiff?(repoPath: string, to: string, from?: string, options?: {
|
|
26
28
|
context?: number;
|
|
27
29
|
index?: DisposableTemporaryGitIndex;
|
|
28
30
|
notation?: GitRevisionRangeNotation;
|
|
29
31
|
uris?: (string | Uri)[];
|
|
32
|
+
/**
|
|
33
|
+
* `'throw'` rejects with the failure (a `GitError` carrying git's `stderr` when git ran) rather than
|
|
34
|
+
* resolving `undefined`, which is the default for every failure
|
|
35
|
+
*/
|
|
36
|
+
errors?: GitErrorHandling;
|
|
30
37
|
}, cancellation?: AbortSignal): Promise<GitDiff | undefined>;
|
|
31
38
|
/**
|
|
32
39
|
* Runs `git diff` and returns the fully parsed structure (files with hunks together) in a
|
|
@@ -39,6 +46,7 @@ export interface GitDiffSubProvider {
|
|
|
39
46
|
context?: number;
|
|
40
47
|
notation?: GitRevisionRangeNotation;
|
|
41
48
|
uris?: (string | Uri)[];
|
|
49
|
+
errors?: GitErrorHandling;
|
|
42
50
|
}, cancellation?: AbortSignal): Promise<ParsedGitDiff | undefined>;
|
|
43
51
|
getDiffFiles?(repoPath: string, contents: string, cancellation?: AbortSignal): Promise<GitDiffFiles | undefined>;
|
|
44
52
|
getDiffStatus(repoPath: string, ref1OrRange: string | GitRevisionRange, ref2?: string, options?: {
|
|
@@ -47,6 +55,7 @@ export interface GitDiffSubProvider {
|
|
|
47
55
|
path?: string;
|
|
48
56
|
renameLimit?: number;
|
|
49
57
|
similarityThreshold?: number;
|
|
58
|
+
errors?: GitErrorHandling;
|
|
50
59
|
}): Promise<GitFile[] | undefined>;
|
|
51
60
|
getDiffTool?(repoPath?: string): Promise<string | undefined>;
|
|
52
61
|
getNextComparisonUris(repoPath: string, pathOrUri: string | Uri, rev: string | undefined, skip?: number, options?: {
|
|
@@ -4,7 +4,7 @@ import { GitRevisionRange, GitRevisionRangeNotation } from "../../git/models/rev
|
|
|
4
4
|
import { GitDiff, GitDiffFiles, GitDiffFilter, GitDiffShortStat, ParsedGitDiff, ParsedGitDiffHunks } from "../../git/models/diff.js";
|
|
5
5
|
import { GitFile } from "../../git/models/file.js";
|
|
6
6
|
import { GitServiceContext } from "../../git/context.js";
|
|
7
|
-
import { GitResult } from "../../git/run.types.js";
|
|
7
|
+
import { GitErrorHandling, GitResult } from "../../git/run.types.js";
|
|
8
8
|
import { Cache } from "../../git/cache.js";
|
|
9
9
|
import { DisposableTemporaryGitIndex } from "../../git/providers/staging.js";
|
|
10
10
|
import { GitDiffSubProvider, NextComparisonUrisResult, PreviousComparisonUrisResult, PreviousRangeComparisonUrisResult } from "../../git/providers/diff.js";
|
|
@@ -22,17 +22,22 @@ export declare class DiffGitSubProvider implements GitDiffSubProvider {
|
|
|
22
22
|
getChangedFilesCount(repoPath: string, to?: string, from?: string, options?: {
|
|
23
23
|
uris?: (string | Uri)[];
|
|
24
24
|
includeUntracked?: boolean;
|
|
25
|
+
errors?: GitErrorHandling;
|
|
25
26
|
}, _cancellation?: AbortSignal): Promise<GitDiffShortStat | undefined>;
|
|
26
27
|
getDiff(repoPath: string, to: string, from?: string, options?: {
|
|
27
28
|
context?: number;
|
|
28
29
|
index?: DisposableTemporaryGitIndex;
|
|
29
30
|
notation?: GitRevisionRangeNotation;
|
|
30
31
|
uris?: (string | Uri)[];
|
|
32
|
+
errors?: GitErrorHandling;
|
|
31
33
|
}, _cancellation?: AbortSignal): Promise<GitDiff | undefined>;
|
|
34
|
+
/** Whether `ex` is git failing to resolve `HEAD` because the repository has no commit yet */
|
|
35
|
+
private isUnbornHeadFailure;
|
|
32
36
|
getParsedDiff(repoPath: string, to: string, from?: string, options?: {
|
|
33
37
|
context?: number;
|
|
34
38
|
notation?: GitRevisionRangeNotation;
|
|
35
39
|
uris?: (string | Uri)[];
|
|
40
|
+
errors?: GitErrorHandling;
|
|
36
41
|
}, cancellation?: AbortSignal): Promise<ParsedGitDiff | undefined>;
|
|
37
42
|
getDiffFiles(repoPath: string, contents: string, _cancellation?: AbortSignal): Promise<GitDiffFiles | undefined>;
|
|
38
43
|
getDiffStatus(repoPath: string, ref1OrRange: string | GitRevisionRange, ref2?: string, options?: {
|
|
@@ -41,6 +46,7 @@ export declare class DiffGitSubProvider implements GitDiffSubProvider {
|
|
|
41
46
|
path?: string;
|
|
42
47
|
renameLimit?: number;
|
|
43
48
|
similarityThreshold?: number;
|
|
49
|
+
errors?: GitErrorHandling;
|
|
44
50
|
}): Promise<GitFile[] | undefined>;
|
|
45
51
|
getDiffTool(repoPath?: string): Promise<string | undefined>;
|
|
46
52
|
getNextComparisonUris(repoPath: string, pathOrUri: string | Uri, rev: string | undefined, skip?: number, options?: {
|
|
@@ -34,7 +34,8 @@ var DiffGitSubProvider = class {
|
|
|
34
34
|
try {
|
|
35
35
|
const result = await this.git.run({
|
|
36
36
|
cwd: repoPath,
|
|
37
|
-
configs: gitConfigsDiff
|
|
37
|
+
configs: gitConfigsDiff,
|
|
38
|
+
errors: options?.errors === "throw" ? "throw" : void 0
|
|
38
39
|
}, "diff", "--shortstat", "--no-ext-diff", ...args, "--", ...options?.uris?.map((p) => this.provider.getRelativePath(p, repoPath)) ?? []);
|
|
39
40
|
const stat = result.stdout ? parseGitDiffShortStat(result.stdout) : void 0;
|
|
40
41
|
if (options?.includeUntracked && !options.uris?.length && isWorkingTreeComparison(to, from)) {
|
|
@@ -48,7 +49,7 @@ var DiffGitSubProvider = class {
|
|
|
48
49
|
return stat;
|
|
49
50
|
} catch (ex) {
|
|
50
51
|
const msg = ex?.toString() ?? "";
|
|
51
|
-
if (GitErrors.noMergeBase.test(msg) || GitErrors.badRevision.test(msg)) return;
|
|
52
|
+
if (options?.errors !== "throw" && (GitErrors.noMergeBase.test(msg) || GitErrors.badRevision.test(msg))) return;
|
|
52
53
|
scope?.error(ex);
|
|
53
54
|
throw ex;
|
|
54
55
|
}
|
|
@@ -67,6 +68,7 @@ var DiffGitSubProvider = class {
|
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
70
|
}
|
|
71
|
+
const hasFrom = from != null;
|
|
70
72
|
from = prepareToFromDiffArgs(to, from, args, options?.notation);
|
|
71
73
|
let paths;
|
|
72
74
|
if (options?.uris) {
|
|
@@ -82,7 +84,16 @@ var DiffGitSubProvider = class {
|
|
|
82
84
|
env: options?.index?.env
|
|
83
85
|
}, "diff", ...args, args.includes("--") ? void 0 : "--");
|
|
84
86
|
} catch (ex) {
|
|
87
|
+
if (isHead(from) && await this.isUnbornHeadFailure(repoPath, ex)) {
|
|
88
|
+
const emptyTree = await this.provider.revision.getEmptyTreeSha(repoPath);
|
|
89
|
+
const retried = await this.getDiff(repoPath, !hasFrom && isHead(to) ? "" : to, emptyTree, options, _cancellation);
|
|
90
|
+
return retried != null ? {
|
|
91
|
+
...retried,
|
|
92
|
+
to
|
|
93
|
+
} : void 0;
|
|
94
|
+
}
|
|
85
95
|
scope?.error(ex);
|
|
96
|
+
if (options?.errors === "throw") throw ex;
|
|
86
97
|
return;
|
|
87
98
|
}
|
|
88
99
|
return {
|
|
@@ -92,6 +103,12 @@ var DiffGitSubProvider = class {
|
|
|
92
103
|
notation: options?.notation
|
|
93
104
|
};
|
|
94
105
|
}
|
|
106
|
+
/** Whether `ex` is git failing to resolve `HEAD` because the repository has no commit yet */
|
|
107
|
+
async isUnbornHeadFailure(repoPath, ex) {
|
|
108
|
+
const ref = GitErrors.badRevision.exec(String(ex))?.[1];
|
|
109
|
+
if (!isHead(ref)) return false;
|
|
110
|
+
return await this.provider.refs.validateReference(repoPath, "HEAD", { force: true }) == null;
|
|
111
|
+
}
|
|
95
112
|
async getParsedDiff(repoPath, to, from, options, cancellation) {
|
|
96
113
|
const diff = await this.getDiff(repoPath, to, from, options, cancellation);
|
|
97
114
|
if (!diff?.contents) return void 0;
|
|
@@ -116,7 +133,8 @@ var DiffGitSubProvider = class {
|
|
|
116
133
|
] : gitConfigsDiff;
|
|
117
134
|
const result = await this.git.run({
|
|
118
135
|
cwd: repoPath,
|
|
119
|
-
configs
|
|
136
|
+
configs,
|
|
137
|
+
errors: options?.errors === "throw" ? "throw" : void 0
|
|
120
138
|
}, "diff", "--numstat", "--summary", `-M${similarityThreshold == null ? "" : `${similarityThreshold}%`}`, "--no-ext-diff", "-z", options?.filters?.length ? `--diff-filter=${options.filters.join("")}` : void 0, ref1OrRange ? ref1OrRange : void 0, ref2 ? ref2 : void 0, "--", options?.path ? options.path : void 0);
|
|
121
139
|
const files = result.stdout ? parseGitDiffNumStatFiles(result.stdout, repoPath) ?? [] : [];
|
|
122
140
|
if (options?.includeUntracked && ref2 == null && typeof ref1OrRange === "string" && !isRevisionRange(ref1OrRange) && !isUncommittedStaged(ref1OrRange) && filtersAllowUntracked(options.filters) && !isNonExactPathspec(options.path)) {
|
|
@@ -131,7 +149,8 @@ var DiffGitSubProvider = class {
|
|
|
131
149
|
}
|
|
132
150
|
}
|
|
133
151
|
return files.length ? files : void 0;
|
|
134
|
-
} catch (
|
|
152
|
+
} catch (ex) {
|
|
153
|
+
if (options?.errors === "throw") throw ex;
|
|
135
154
|
return;
|
|
136
155
|
}
|
|
137
156
|
}
|
|
@@ -591,9 +610,12 @@ function isWorkingTreeComparison(to, from) {
|
|
|
591
610
|
if (isRevisionRange(to) || isUncommittedStaged(to)) return false;
|
|
592
611
|
if (isUncommitted(to)) return true;
|
|
593
612
|
if (to === "") return from == null || !isUncommittedStaged(from);
|
|
594
|
-
if (to
|
|
613
|
+
if (isHead(to) && from == null) return true;
|
|
595
614
|
return false;
|
|
596
615
|
}
|
|
616
|
+
function isHead(ref) {
|
|
617
|
+
return ref?.toUpperCase() === "HEAD";
|
|
618
|
+
}
|
|
597
619
|
function prepareToFromDiffArgs(to, from, args, notation) {
|
|
598
620
|
if (to === "0000000000000000000000000000000000000000") {
|
|
599
621
|
if (from != null) args.push(from);
|
|
@@ -603,7 +625,7 @@ function prepareToFromDiffArgs(to, from, args, notation) {
|
|
|
603
625
|
if (from != null) args.push(from);
|
|
604
626
|
else from = "HEAD";
|
|
605
627
|
} else if (from == null) {
|
|
606
|
-
if (to === "" || to
|
|
628
|
+
if (to === "" || isHead(to)) {
|
|
607
629
|
from = "HEAD";
|
|
608
630
|
args.push(from);
|
|
609
631
|
} else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","names":[],"sources":["../../../../git-cli/src/providers/diff.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport type {\n\tGitDiff,\n\tGitDiffFiles,\n\tGitDiffFilter,\n\tGitDiffShortStat,\n\tParsedGitDiff,\n\tParsedGitDiffHunks,\n} from '@gitlens/git/models/diff.js';\nimport type { GitFile } from '@gitlens/git/models/file.js';\nimport type { GitRevisionRange, GitRevisionRangeNotation } from '@gitlens/git/models/revision.js';\nimport { deletedOrMissing, uncommitted, uncommittedStaged } from '@gitlens/git/models/revision.js';\nimport {\n\tparseGitApplyFiles,\n\tparseGitDiff,\n\tparseGitDiffNumStatFiles,\n\tparseGitDiffShortStat,\n\tparseGitFileDiff,\n} from '@gitlens/git/parsers/diffParser.js';\nimport type {\n\tGitDiffSubProvider,\n\tNextComparisonUrisResult,\n\tPreviousComparisonUrisResult,\n\tPreviousRangeComparisonUrisResult,\n} from '@gitlens/git/providers/diff.js';\nimport type { DisposableTemporaryGitIndex } from '@gitlens/git/providers/staging.js';\nimport type { DiffRange, RevisionUri } from '@gitlens/git/providers/types.js';\nimport {\n\tgetRevisionRangeParts,\n\tisRevisionRange,\n\tisUncommitted,\n\tisUncommittedStaged,\n} from '@gitlens/git/utils/revision.utils.js';\nimport { encodeGitLensRevisionUriAuthority } from '@gitlens/git/utils/uriAuthority.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { fnv1aHash } from '@gitlens/utils/hash.js';\nimport { first } from '@gitlens/utils/iterable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { normalizePath, splitPath } from '@gitlens/utils/path.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fromUri, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult } from '../exec/exec.types.js';\nimport type { Git } from '../exec/git.js';\nimport { gitConfigsDiff, gitConfigsLog, GitError, GitErrors } from '../exec/git.js';\nimport type { LogParsedFile } from '../parsers/logParser.js';\nimport { getShaAndFileRangeLogParser, getShaAndFileSummaryLogParser } from '../parsers/logParser.js';\n\nexport class DiffGitSubProvider implements GitDiffSubProvider {\n\tconstructor(\n\t\tprivate readonly context: GitServiceContext,\n\t\tprivate readonly git: Git,\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: CliGitProviderInternal,\n\t) {}\n\n\t@debug()\n\tasync getChangedFilesCount(\n\t\trepoPath: string,\n\t\tto?: string,\n\t\tfrom?: string,\n\t\toptions?: { uris?: (string | Uri)[]; includeUntracked?: boolean },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiffShortStat | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst args: string[] = [];\n\t\tif (to != null) {\n\t\t\t// Handle revision ranges specially if there is no `from`, otherwise `prepareToFromDiffArgs` will duplicate the range\n\t\t\tif (isRevisionRange(to) && from == null) {\n\t\t\t\targs.push(to);\n\t\t\t} else {\n\t\t\t\tprepareToFromDiffArgs(to, from, args);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff },\n\t\t\t\t'diff',\n\t\t\t\t'--shortstat',\n\t\t\t\t'--no-ext-diff',\n\t\t\t\t...args,\n\t\t\t\t'--',\n\t\t\t\t...(options?.uris?.map(p => this.provider.getRelativePath(p, repoPath)) ?? []),\n\t\t\t);\n\n\t\t\tconst stat = result.stdout ? parseGitDiffShortStat(result.stdout) : undefined;\n\n\t\t\t// Merge in untracked files when the comparison involves the working tree.\n\t\t\t// Skip when a pathspec filter is active — mixing a path-filtered diff count with an\n\t\t\t// unfiltered untracked count would silently produce wrong totals.\n\t\t\tif (options?.includeUntracked && !options.uris?.length && isWorkingTreeComparison(to, from)) {\n\t\t\t\tconst untracked = (await this.provider.status?.getUntrackedFiles?.(repoPath)) ?? [];\n\t\t\t\tif (untracked.length) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tfiles: (stat?.files ?? 0) + untracked.length,\n\t\t\t\t\t\tadditions: stat?.additions ?? 0,\n\t\t\t\t\t\tdeletions: stat?.deletions ?? 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stat;\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif (GitErrors.noMergeBase.test(msg) || GitErrors.badRevision.test(msg)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDiff(\n\t\trepoPath: string,\n\t\tto: string,\n\t\tfrom?: string,\n\t\toptions?: {\n\t\t\tcontext?: number;\n\t\t\tindex?: DisposableTemporaryGitIndex;\n\t\t\tnotation?: GitRevisionRangeNotation;\n\t\t\turis?: (string | Uri)[];\n\t\t},\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiff | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst args = [`-U${options?.context ?? 3}`];\n\n\t\tif (to != null && isRevisionRange(to)) {\n\t\t\tconst parts = getRevisionRangeParts(to);\n\t\t\tif (parts != null) {\n\t\t\t\tto = parts.right ?? '';\n\t\t\t\tfrom = parts.left;\n\t\t\t\toptions = { ...options, notation: parts.notation };\n\t\t\t}\n\t\t}\n\n\t\tfrom = prepareToFromDiffArgs(to, from, args, options?.notation);\n\n\t\tlet paths: Set<string> | undefined;\n\t\tif (options?.uris) {\n\t\t\tpaths = new Set<string>(options.uris.map(p => this.provider.getRelativePath(p, repoPath)));\n\t\t\targs.push('--', ...paths);\n\t\t}\n\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, errors: 'throw', env: options?.index?.env },\n\t\t\t\t'diff',\n\t\t\t\t...args,\n\t\t\t\targs.includes('--') ? undefined : '--',\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst diff: GitDiff = { contents: result.stdout, from: from, to: to, notation: options?.notation };\n\t\treturn diff;\n\t}\n\n\t@debug()\n\tasync getParsedDiff(\n\t\trepoPath: string,\n\t\tto: string,\n\t\tfrom?: string,\n\t\toptions?: {\n\t\t\tcontext?: number;\n\t\t\tnotation?: GitRevisionRangeNotation;\n\t\t\turis?: (string | Uri)[];\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ParsedGitDiff | undefined> {\n\t\tconst diff = await this.getDiff(repoPath, to, from, options, cancellation);\n\t\tif (!diff?.contents) return undefined;\n\n\t\treturn parseGitDiff(diff.contents);\n\t}\n\n\t@debug({ args: repoPath => ({ repoPath: repoPath }) })\n\tasync getDiffFiles(\n\t\trepoPath: string,\n\t\tcontents: string,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiffFiles | undefined> {\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, configs: gitConfigsLog, stdin: contents },\n\t\t\t'apply',\n\t\t\t'--numstat',\n\t\t\t'--summary',\n\t\t\t'-z',\n\t\t\t'-',\n\t\t);\n\t\tif (!result.stdout) return undefined;\n\n\t\tconst files = parseGitApplyFiles(result.stdout, repoPath);\n\t\treturn {\n\t\t\tfiles: files,\n\t\t};\n\t}\n\n\t@debug()\n\tasync getDiffStatus(\n\t\trepoPath: string,\n\t\tref1OrRange: string | GitRevisionRange,\n\t\tref2?: string,\n\t\toptions?: {\n\t\t\tfilters?: GitDiffFilter[];\n\t\t\tincludeUntracked?: boolean;\n\t\t\tpath?: string;\n\t\t\trenameLimit?: number;\n\t\t\tsimilarityThreshold?: number;\n\t\t},\n\t): Promise<GitFile[] | undefined> {\n\t\ttry {\n\t\t\tconst similarityThreshold =\n\t\t\t\toptions?.similarityThreshold ?? this.context.config?.commits.similarityThreshold;\n\t\t\tconst configs =\n\t\t\t\toptions?.renameLimit != null\n\t\t\t\t\t? [...gitConfigsDiff, '-c', `diff.renameLimit=${options.renameLimit}`]\n\t\t\t\t\t: gitConfigsDiff;\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: configs },\n\t\t\t\t'diff',\n\t\t\t\t'--numstat',\n\t\t\t\t'--summary',\n\t\t\t\t`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`,\n\t\t\t\t'--no-ext-diff',\n\t\t\t\t'-z',\n\t\t\t\toptions?.filters?.length ? `--diff-filter=${options.filters.join('')}` : undefined,\n\t\t\t\tref1OrRange ? ref1OrRange : undefined,\n\t\t\t\tref2 ? ref2 : undefined,\n\t\t\t\t'--',\n\t\t\t\toptions?.path ? options.path : undefined,\n\t\t\t);\n\n\t\t\tconst files = result.stdout ? (parseGitDiffNumStatFiles(result.stdout, repoPath) ?? []) : [];\n\n\t\t\t// Merge in untracked files when the comparison involves the working tree.\n\t\t\t// Skip when `filters` excludes additions (untracked entries are semantically 'A'/added),\n\t\t\t// or when `path` is a non-exact pathspec we can't reliably match against the untracked list.\n\t\t\tif (\n\t\t\t\toptions?.includeUntracked &&\n\t\t\t\tref2 == null &&\n\t\t\t\ttypeof ref1OrRange === 'string' &&\n\t\t\t\t!isRevisionRange(ref1OrRange) &&\n\t\t\t\t!isUncommittedStaged(ref1OrRange) &&\n\t\t\t\tfiltersAllowUntracked(options.filters) &&\n\t\t\t\t!isNonExactPathspec(options.path)\n\t\t\t) {\n\t\t\t\tconst untracked = (await this.provider.status?.getUntrackedFiles?.(repoPath)) ?? [];\n\t\t\t\tif (untracked.length) {\n\t\t\t\t\tconst seen = new Set(files.map(f => f.path));\n\t\t\t\t\tfor (const file of untracked) {\n\t\t\t\t\t\tif (seen.has(file.path)) continue;\n\t\t\t\t\t\tif (options.path && options.path !== file.path) continue;\n\n\t\t\t\t\t\tfiles.push(file);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn files.length ? files : undefined;\n\t\t} catch (_ex) {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDiffTool(repoPath?: string): Promise<string | undefined> {\n\t\treturn (\n\t\t\t(await this.provider.config.getConfig?.(repoPath, 'diff.guitool', { runGitLocally: true })) ??\n\t\t\tthis.provider.config.getConfig?.(repoPath, 'diff.tool', { runGitLocally: true })\n\t\t);\n\t}\n\n\t@debug()\n\tasync getNextComparisonUris(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\tskip: number = 0,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<NextComparisonUrisResult | undefined> {\n\t\t// If we have no revision there is no next commit\n\t\tif (!rev) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\n\t\tif (isUncommittedStaged(rev)) {\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, relativePath, rev),\n\t\t\t\tnext: createRevisionUri(this.provider, repoPath, relativePath, undefined),\n\t\t\t};\n\t\t} else if (isUncommitted(rev)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\t\tconst args = ['log', ...parser.arguments];\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\targs.push(\n\t\t\t\t// Use reverse to get the next commits (oldest to newest instead of newest to oldest)\n\t\t\t\t'--reverse',\n\t\t\t);\n\n\t\t\tif (rev !== deletedOrMissing) {\n\t\t\t\targs.push(\n\t\t\t\t\t// Ancestry path to ensure we only follow the path from the given revision to HEAD\n\t\t\t\t\t'--ancestry-path',\n\t\t\t\t\t// Range from the given revision to HEAD\n\t\t\t\t\t`${rev}..HEAD`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Follow file history and specify the file path\n\t\t\targs.push('--follow', '--', relativePath);\n\n\t\t\t// Unbounded --follow walk over file history can be slow on long histories — queue as background\n\t\t\t// so it doesn't compete with interactive work.\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsLog, priority: 'background' },\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tlet currentSha;\n\t\t\tlet currentPath;\n\n\t\t\tif (skip === 0) {\n\t\t\t\tcurrentSha = rev;\n\t\t\t\tcurrentPath = relativePath;\n\t\t\t} else {\n\t\t\t\tskip--;\n\t\t\t}\n\n\t\t\tlet nextSha;\n\t\t\tlet nextPath;\n\n\t\t\tlet file;\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.path && file.path !== relativePath) {\n\t\t\t\t\trelativePath = file.path;\n\t\t\t\t}\n\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t} else if (nextSha == null) {\n\t\t\t\t\t// if (commit.sha === rev) continue;\n\n\t\t\t\t\tnextSha = commit.sha;\n\t\t\t\t\tnextPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, relativePath);\n\t\t\t\tif (status != null) {\n\t\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\t\tcurrentSha = uncommittedStaged;\n\t\t\t\t\t\tcurrentPath = status.originalPath ?? status.path;\n\t\t\t\t\t\tnextSha = '';\n\t\t\t\t\t\tnextPath = status.path;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (nextSha == null || nextPath == null) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, relativePath);\n\t\t\t\tif (status != null) {\n\t\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\t\tnextSha = uncommittedStaged;\n\t\t\t\t\t\tnextPath = status.originalPath ?? status.path;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnextSha = '';\n\t\t\t\t\t\tnextPath = status.path;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnextSha = '';\n\t\t\t\t\tnextPath = relativePath;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tnext: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tnextPath ?? currentPath,\n\t\t\t\t\t(nextSha ?? deletedOrMissing) || undefined,\n\t\t\t\t),\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getPreviousComparisonUris(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\tskip: number = 0,\n\t\tunsaved?: boolean,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PreviousComparisonUrisResult | undefined> {\n\t\tif (rev === deletedOrMissing) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tif (rev === uncommitted) {\n\t\t\trev = undefined;\n\t\t}\n\n\t\t/* Rules:\n\t\t * Starting from working tree (rev is empty or undefined):\n\t\t * 1. Check file status:\n\t\t * 1.1. If file has both staged and working (or unsaved) changes:\n\t\t * - If skip=0: diff working with staged\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.2. If file has only staged changes:\n\t\t * - If skip=0: diff working with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.3. If file has only working changes:\n\t\t * - If skip=0: diff working with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.4. If file has no changes (or no status found):\n\t\t * - If skip=0: diff working with HEAD~1\n\t\t * - If skip>0: skip through revs starting at HEAD~1\n\t\t *\n\t\t * Starting from staged (rev is uncommittedStaged):\n\t\t * 1. Check file status:\n\t\t * 1.1. If status exists:\n\t\t * - If skip=0: diff staged with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.2. If status doesn't exist:\n\t\t * - If skip=0: diff HEAD with HEAD~1\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * Starting from a commit (rev is a SHA):\n\t\t * - If skip=0: diff SHA with SHA^\n\t\t * - If skip>0: skip through revs starting at SHA\n\t\t */\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\t\tlet skipPrev = 0;\n\n\t\tlet revs: [string, string][] = [];\n\t\tif (!rev) {\n\t\t\trevs = [['', relativePath]];\n\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\trevs.push([uncommittedStaged, status.originalPath ?? status.path]);\n\t\t\t\t}\n\n\t\t\t\trevs.push(['HEAD', status.originalPath ?? status.path]);\n\t\t\t\tif (status.workingTreeStatus == null && !unsaved) {\n\t\t\t\t\tif (skip === 0 || status.indexStatus == null) {\n\t\t\t\t\t\t// Skip over the HEAD commit to get a diff, because working and HEAD are the same\n\t\t\t\t\t\tskipPrev++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trevs.push(['HEAD', relativePath]);\n\t\t\t\tif (!unsaved) {\n\t\t\t\t\t// Skip over the HEAD commit to get a diff, because working and HEAD are the same\n\t\t\t\t\tskipPrev++;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isUncommittedStaged(rev)) {\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\trevs = [\n\t\t\t\t\t[uncommittedStaged, status.originalPath ?? status.path],\n\t\t\t\t\t['HEAD', status.originalPath ?? status.path],\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\t// Even though we supposedly started at staged, there is no staged version\n\t\t\t\trevs = [['HEAD', relativePath]];\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet currentSha;\n\t\tlet currentPath;\n\n\t\tif (revs.length) {\n\t\t\tskip++;\n\t\t\twhile (revs.length && skip > 0) {\n\t\t\t\tskip--;\n\t\t\t\t[rev, relativePath] = revs.shift()!;\n\t\t\t}\n\n\t\t\tif (rev !== 'HEAD') {\n\t\t\t\tcurrentSha = rev;\n\t\t\t\tcurrentPath = relativePath;\n\n\t\t\t\tskipPrev++;\n\t\t\t\twhile (revs.length && skipPrev > 0) {\n\t\t\t\t\tskipPrev--;\n\t\t\t\t\t[rev, relativePath] = revs.shift()!;\n\t\t\t\t}\n\n\t\t\t\tif (skipPrev > 0) {\n\t\t\t\t\tskip += skipPrev;\n\t\t\t\t}\n\n\t\t\t\tif (rev !== 'HEAD' && skip === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha),\n\t\t\t\t\t\tprevious: createRevisionUri(this.provider, repoPath, relativePath, rev),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\t\tconst args = ['log', ...parser.arguments, `-n${skip + 2}`]; // Don't use --skip as it doesn't work with --follow\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\targs.push('--follow', rev!, '--', relativePath);\n\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tconfigs: gitConfigsLog,\n\t\t\t\t\tcaching: { cache: this.cache.gitResults, options: { accessTTL: 5 * 60 * 1000 } },\n\t\t\t\t},\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tlet previousSha;\n\t\t\tlet previousPath;\n\t\t\tlet file;\n\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.originalPath && file.originalPath !== relativePath) {\n\t\t\t\t\trelativePath = file.originalPath;\n\t\t\t\t}\n\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t} else if (previousSha == null) {\n\t\t\t\t\tif (commit.sha === rev) continue;\n\n\t\t\t\t\tpreviousSha = commit.sha;\n\t\t\t\t\tpreviousPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) return undefined;\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tprevious: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpreviousPath ?? currentPath,\n\t\t\t\t\tpreviousSha ?? deletedOrMissing,\n\t\t\t\t),\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getPreviousComparisonUrisForRange(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\trange: DiffRange,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null; skipFirstRev?: boolean },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PreviousRangeComparisonUrisResult | undefined> {\n\t\tif (rev === deletedOrMissing) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tif (rev === uncommitted) {\n\t\t\trev = undefined;\n\t\t}\n\n\t\tlet currentSha;\n\t\tlet currentPath;\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\t\tconst skipFirstRev = options?.skipFirstRev ?? true;\n\n\t\t// If we are at the working tree (i.e. no ref), we need to dig deeper to figure out where to go\n\t\tif (!rev) {\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\tif (status.workingTreeStatus != null && !skipFirstRev) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, relativePath, undefined),\n\t\t\t\t\t\t\tprevious: createRevisionUri(this.provider, repoPath, relativePath, uncommittedStaged),\n\t\t\t\t\t\t\trange: range,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrentSha = uncommittedStaged;\n\t\t\t\t\tcurrentPath = status.originalPath ?? status.path;\n\t\t\t\t\tif (status.originalPath != null) {\n\t\t\t\t\t\trelativePath = status.originalPath;\n\t\t\t\t\t}\n\t\t\t\t\trev = uncommittedStaged;\n\t\t\t\t} else if (status.workingTreeStatus != null && !skipFirstRev) {\n\t\t\t\t\tcurrentSha = '';\n\t\t\t\t\tcurrentPath = relativePath;\n\t\t\t\t\trev = '';\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (!skipFirstRev) {\n\t\t\tcurrentSha = rev;\n\t\t\tcurrentPath = relativePath;\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileRangeLogParser();\n\t\t\tconst args = ['log', ...parser.arguments, '-n2']; // Don't use --skip as it doesn't work with --follow\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\tif (rev && !isUncommittedStaged(rev)) {\n\t\t\t\targs.push(rev);\n\t\t\t}\n\n\t\t\targs.push(`-L${range.startLine},${range.endLine}:${relativePath}`);\n\n\t\t\tlet result: GitResult;\n\t\t\ttry {\n\t\t\t\tresult = await this.git.run({ cwd: repoPath, configs: gitConfigsLog }, ...args);\n\t\t\t} catch (ex) {\n\t\t\t\tif (rev && !isUncommittedStaged(rev)) throw ex;\n\n\t\t\t\t// If the line count is invalid reset to a valid range\n\t\t\t\tconst match = GitErrors.invalidLineCount.exec(ex?.toString() ?? '');\n\t\t\t\tif (match == null) throw ex;\n\n\t\t\t\tconst line = parseInt(match[1], 10);\n\t\t\t\tif (isNaN(line)) throw ex;\n\n\t\t\t\tconst index = args.findIndex(a => a.startsWith('-L'));\n\t\t\t\tif (index === -1) throw ex;\n\n\t\t\t\trange = {\n\t\t\t\t\tstartLine: Math.min(range.startLine, line),\n\t\t\t\t\tstartCharacter: range.startCharacter,\n\t\t\t\t\tendLine: Math.min(range.endLine, line),\n\t\t\t\t\tendCharacter: range.endCharacter,\n\t\t\t\t\tactive: range.active,\n\t\t\t\t};\n\n\t\t\t\targs.splice(index, 1, `-L${range.startLine},${range.endLine}:${relativePath}`);\n\t\t\t\tresult = await this.git.run({ cwd: repoPath, configs: gitConfigsLog }, ...args);\n\t\t\t}\n\n\t\t\tlet currentRange;\n\t\t\tlet previousSha;\n\t\t\tlet previousPath;\n\t\t\tlet file;\n\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// If we couldn't find the file, but there is only one file in the commit, use that one and assume the filename changed\n\t\t\t\tif (file == null && commit.files.length === 1) {\n\t\t\t\t\tfile = commit.files[0];\n\t\t\t\t\trelativePath = file.path;\n\t\t\t\t}\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.originalPath && file.originalPath !== relativePath) {\n\t\t\t\t\trelativePath = file.originalPath;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t\tcurrentRange =\n\t\t\t\t\t\tfile?.range != null ? { ...file.range, startCharacter: 1, endCharacter: 1 } : undefined;\n\t\t\t\t} else if (previousSha == null) {\n\t\t\t\t\tif (commit.sha === rev) continue;\n\n\t\t\t\t\tpreviousSha = commit.sha;\n\t\t\t\t\tpreviousPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) return undefined;\n\n\t\t\t// If we have no previous SHA but have a real current SHA, resolve the parent commit.\n\t\t\t// This handles the case where a line is newly added — the line has no prior history,\n\t\t\t// but the file likely existed at the parent commit\n\t\t\tif (previousSha == null && currentSha) {\n\t\t\t\tpreviousSha =\n\t\t\t\t\t(await this.provider.refs.validateReference(repoPath, `${currentSha}^`)) ?? deletedOrMissing;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tprevious: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpreviousPath ?? currentPath,\n\t\t\t\t\tpreviousSha ?? deletedOrMissing,\n\t\t\t\t),\n\t\t\t\trange: currentRange ?? range,\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Returns raw diff output for a file between two revisions. */\n\tasync diff(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1?: string,\n\t\tref2?: string,\n\t\toptions?: {\n\t\t\tencoding?: string;\n\t\t\tfilters?: GitDiffFilter[];\n\t\t\tlinesOfContext?: number;\n\t\t\trenames?: boolean;\n\t\t\tsimilarityThreshold?: number | null;\n\t\t},\n\t): Promise<GitResult> {\n\t\tconst params = ['diff', '--no-ext-diff', '--minimal'];\n\n\t\tif (options?.linesOfContext != null) {\n\t\t\tparams.push(`-U${options.linesOfContext}`);\n\t\t}\n\n\t\tif (options?.renames) {\n\t\t\tparams.push(`-M${options.similarityThreshold == null ? '' : `${options.similarityThreshold}%`}`);\n\t\t}\n\n\t\tif (options?.filters != null && options.filters.length !== 0) {\n\t\t\tparams.push(`--diff-filter=${options.filters.join('')}`);\n\t\t}\n\n\t\tif (ref1) {\n\t\t\t// <sha>^3 signals an untracked file in a stash and if we are trying to find its parent, use the empty tree\n\t\t\tif (ref1.endsWith('^3^')) {\n\t\t\t\tref1 = await this.provider.revision.getEmptyTreeSha(repoPath);\n\t\t\t}\n\t\t\tparams.push(isUncommittedStaged(ref1) ? '--staged' : ref1);\n\t\t}\n\t\tif (ref2) {\n\t\t\tparams.push(isUncommittedStaged(ref2) ? '--staged' : ref2);\n\t\t}\n\n\t\ttry {\n\t\t\treturn await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, encoding: options?.encoding },\n\t\t\t\t...params,\n\t\t\t\t'--',\n\t\t\t\tfileName,\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tconst match = GitErrors.badRevision.exec(ex.message);\n\t\t\tif (match !== null) {\n\t\t\t\tconst [, ref] = match;\n\n\t\t\t\t// If the bad ref is trying to find a parent ref, assume we hit to the last commit, so try again using the empty tree\n\t\t\t\tif (ref === ref1 && ref?.endsWith('^')) {\n\t\t\t\t\treturn this.diff(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tfileName,\n\t\t\t\t\t\tawait this.provider.revision.getEmptyTreeSha(repoPath),\n\t\t\t\t\t\tref2,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Returns raw diff output comparing a file's revision with given contents via stdin. */\n\tasync diffContents(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions?: { encoding?: string; filters?: GitDiffFilter[]; similarityThreshold?: number | null },\n\t): Promise<string> {\n\t\tconst params = [\n\t\t\t'diff',\n\t\t\t`-M${options?.similarityThreshold == null ? '' : `${options.similarityThreshold}%`}`,\n\t\t\t'--no-ext-diff',\n\t\t\t'-U0',\n\t\t\t'--minimal',\n\t\t];\n\n\t\tif (options?.filters != null && options.filters.length !== 0) {\n\t\t\tparams.push(`--diff-filter=${options.filters.join('')}`);\n\t\t}\n\n\t\tparams.push('--no-index');\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tconfigs: gitConfigsDiff,\n\t\t\t\t\tencoding: options?.encoding,\n\t\t\t\t\tstdin: contents,\n\t\t\t\t},\n\t\t\t\t...params,\n\t\t\t\t'--',\n\t\t\t\tfileName,\n\t\t\t\t// Pipe the contents to stdin\n\t\t\t\t'-',\n\t\t\t);\n\t\t\treturn result.stdout;\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof GitError && ex.stdout) {\n\t\t\t\treturn ex.stdout;\n\t\t\t}\n\n\t\t\tconst match = GitErrors.badRevision.exec(ex.message);\n\t\t\tif (match !== null) {\n\t\t\t\tconst [, matchedRef] = match;\n\n\t\t\t\t// If the bad ref is trying to find a parent ref, assume we hit to the last commit, so try again using the empty tree\n\t\t\t\tif (matchedRef === ref && matchedRef?.endsWith('^')) {\n\t\t\t\t\treturn this.diffContents(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tfileName,\n\t\t\t\t\t\tawait this.provider.revision.getEmptyTreeSha(repoPath),\n\t\t\t\t\t\tcontents,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Returns parsed diff hunks for a file between two revisions. */\n\t@debug()\n\tgetDiffForFile(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1: string | undefined,\n\t\tref2?: string,\n\t\toptions?: { encoding?: string },\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst cacheKey = `${normalizePath(fileName)}:${ref1 ?? ''}:${ref2 ?? ''}`;\n\t\treturn this.cache.diff.getOrCreate(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\t() => this.getDiffForFileCore(repoPath, fileName, ref1, ref2, options),\n\t\t\t{ errorTTL: 1000 * 60 },\n\t\t);\n\t}\n\n\tprivate async getDiffForFileCore(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1: string | undefined,\n\t\tref2: string | undefined,\n\t\toptions: { encoding?: string } | undefined,\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\t// Include renames (R) and copies (C) so content diffs on renamed files still surface;\n\t\t// --diff-filter runs after `-M` rename detection, so 'M' alone would drop valid rename diffs.\n\t\tconst result = await this.diff(repoPath, fileName, ref1, ref2, {\n\t\t\tencoding: options?.encoding,\n\t\t\tfilters: ['M', 'R', 'C'],\n\t\t\tlinesOfContext: 0,\n\t\t\trenames: true,\n\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t});\n\t\treturn parseGitFileDiff(result.stdout);\n\t}\n\n\t/** Returns parsed diff hunks comparing a file's revision with given contents via stdin. */\n\t@debug()\n\tgetDiffForFileContents(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions?: { encoding?: string },\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst cacheKey = `${normalizePath(fileName)}:${ref}:~${fnv1aHash(contents)}`;\n\t\treturn this.cache.diff.getOrCreate(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\t() => this.getDiffForFileContentsCore(repoPath, fileName, ref, contents, options),\n\t\t\t{ errorTTL: 1000 * 60 },\n\t\t);\n\t}\n\n\tprivate async getDiffForFileContentsCore(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions: { encoding?: string } | undefined,\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst data = await this.diffContents(repoPath, fileName, ref, contents, {\n\t\t\tencoding: options?.encoding,\n\t\t\tfilters: ['M', 'R', 'C'],\n\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t});\n\t\treturn parseGitFileDiff(data);\n\t}\n\n\t/** Finds the most recent commit where the given path was copied, renamed, or deleted. */\n\t@debug()\n\tasync findPathStatusChanged(\n\t\trepoPath: string,\n\t\tpathspec: string,\n\t\trev: string | undefined,\n\t\toptions?: { filters?: GitDiffFilter[]; ordering?: 'date' | 'author-date' | 'topo' | null },\n\t): Promise<{ sha: string; file: LogParsedFile | undefined } | undefined> {\n\t\treturn findPathStatusChanged(this.git, repoPath, pathspec, rev, options);\n\t}\n\n\t@debug()\n\tasync openDiffTool(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\toptions?: { ref1?: string; ref2?: string; staged?: boolean; tool?: string },\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\t\tconst [relativePath, root] = splitPath(toFsPath(pathOrUri), repoPath);\n\n\t\ttry {\n\t\t\tlet tool = options?.tool;\n\t\t\tif (!tool) {\n\t\t\t\tconst scope = getScopedLogger();\n\n\t\t\t\ttool = await this.getDiffTool(root);\n\t\t\t\tif (tool == null) throw new Error('No diff tool found');\n\n\t\t\t\tscope?.debug(`Using tool=${tool}`);\n\t\t\t}\n\n\t\t\tawait this.git.run(\n\t\t\t\t{ cwd: root },\n\t\t\t\t'difftool',\n\t\t\t\t'--no-prompt',\n\t\t\t\t`--tool=${tool}`,\n\t\t\t\toptions?.staged ? '--staged' : undefined,\n\t\t\t\toptions?.ref1 ? options.ref1 : undefined,\n\t\t\t\toptions?.ref2 ? options.ref2 : undefined,\n\t\t\t\t'--',\n\t\t\t\trelativePath,\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif ((ex instanceof Error && ex.message === 'No diff tool found') || /Unknown .+? tool/.test(msg)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Unable to open changes because the specified diff tool cannot be found or no Git diff tool is configured',\n\t\t\t\t\t),\n\t\t\t\t\t{ cause: ex },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync openDirectoryCompare(repoPath: string, ref1: string, ref2?: string, tool?: string): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tif (!tool) {\n\t\t\t\tconst scope = getScopedLogger();\n\n\t\t\t\ttool = await this.getDiffTool(repoPath);\n\t\t\t\tif (tool == null) throw new Error('No diff tool found');\n\n\t\t\t\tscope?.debug(`Using tool=${tool}`);\n\t\t\t}\n\n\t\t\tawait this.git.run({ cwd: repoPath }, 'difftool', '--dir-diff', `--tool=${tool}`, ref1, ref2);\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif ((ex instanceof Error && ex.message === 'No diff tool found') || /Unknown .+? tool/.test(msg)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Unable to open directory compare because the specified diff tool cannot be found or no Git diff tool is configured',\n\t\t\t\t\t),\n\t\t\t\t\t{ cause: ex },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n}\n// Returns true when no --diff-filter is active or when it includes additions ('A' or '*').\n// Untracked files are semantically \"added\" — if a caller restricts filters to e.g. ['M'],\n// honor that and omit untracked.\nfunction filtersAllowUntracked(filters: GitDiffFilter[] | undefined): boolean {\n\tif (!filters?.length) return true;\n\treturn filters.includes('A') || filters.includes('*');\n}\n\n// Returns true when the path is a git pathspec we can't match with simple equality\n// (directory prefix, glob, or magic pathspec). In that case, skip the untracked merge\n// rather than risk excluding legitimate matches or including wrong ones.\nfunction isNonExactPathspec(path: string | undefined): boolean {\n\tif (!path) return false;\n\treturn path.endsWith('/') || /[*?[\\]]|^:/.test(path);\n}\n\n// Returns true when the `git diff` invocation shape includes the working tree\n// (i.e. `git diff`, `git diff HEAD`, or `git diff <ref>` with no `from`), and\n// therefore untracked files are a meaningful addition to the result.\nfunction isWorkingTreeComparison(to: string | undefined, from: string | undefined): boolean {\n\tif (to == null) return true;\n\tif (isRevisionRange(to) || isUncommittedStaged(to)) return false;\n\n\t// `to === uncommitted` always targets the working tree (`prepareToFromDiffArgs` sets\n\t// `from = 'HEAD'` when omitted, or diffs against the caller-supplied `from`).\n\tif (isUncommitted(to)) return true;\n\n\t// `git diff <from>` — `to === ''` means the caller explicitly asked for working tree vs `from`\n\tif (to === '') return from == null || !isUncommittedStaged(from);\n\n\t// `getChangedFilesCount` uses `prepareToFromDiffArgs`, which translates `to` (with no `from`)\n\t// to `${to}^ ${to}` UNLESS `to` is HEAD or empty.\n\tif (to.toUpperCase() === 'HEAD' && from == null) return true;\n\treturn false;\n}\n\nfunction prepareToFromDiffArgs(\n\tto: string,\n\tfrom: string | undefined,\n\targs: string[],\n\tnotation?: GitRevisionRangeNotation,\n): string {\n\tif (to === uncommitted) {\n\t\tif (from != null) {\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\t// Get only unstaged changes\n\t\t\tfrom = 'HEAD';\n\t\t}\n\t} else if (to === uncommittedStaged) {\n\t\targs.push('--staged');\n\t\tif (from != null) {\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\t// Get only staged changes\n\t\t\tfrom = 'HEAD';\n\t\t}\n\t} else if (from == null) {\n\t\tif (to === '' || to.toUpperCase() === 'HEAD') {\n\t\t\tfrom = 'HEAD';\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\tfrom = `${to}^`;\n\t\t\targs.push(from, to);\n\t\t}\n\t} else if (to === '') {\n\t\targs.push(from);\n\t} else if (notation != null) {\n\t\targs.push(`${from}${notation}${to}`);\n\t} else {\n\t\targs.push(from, to);\n\t}\n\treturn from;\n}\n\nfunction createRevisionUri(\n\tprovider: CliGitProviderInternal,\n\trepoPath: string,\n\trelativePath: string,\n\tsha: string | undefined,\n): RevisionUri {\n\treturn {\n\t\turi: sha\n\t\t\t? fromUri({\n\t\t\t\t\tscheme: 'gitlens',\n\t\t\t\t\tauthority: encodeGitLensRevisionUriAuthority({ ref: sha, repoPath: repoPath }),\n\t\t\t\t\tpath: provider.getAbsoluteUri(relativePath, repoPath).path,\n\t\t\t\t})\n\t\t\t: provider.getAbsoluteUri(relativePath, repoPath),\n\t\tpath: relativePath,\n\t\tsha: sha,\n\t\trepoPath: repoPath,\n\t};\n}\n\nexport async function findPathStatusChanged(\n\tgit: Git,\n\trepoPath: string,\n\tpathspec: string,\n\trev: string | undefined,\n\toptions?: { filters?: GitDiffFilter[]; ordering?: 'date' | 'author-date' | 'topo' | null },\n): Promise<{ sha: string; file: LogParsedFile | undefined } | undefined> {\n\tconst parser = getShaAndFileSummaryLogParser();\n\n\tconst ordering = options?.ordering;\n\n\tconst result = await git.run(\n\t\t{ cwd: repoPath, configs: gitConfigsLog },\n\t\t'log',\n\t\t...parser.arguments,\n\t\tordering ? `--${ordering}-order` : undefined,\n\t\t'--no-walk',\n\t\t`--diff-filter=${options?.filters?.length ? options.filters.join('') : 'RCD'}`,\n\t\trev,\n\t\t// Note: --no-walk constrains to the exact commit (no ancestor search). Pathspec is omitted\n\t\t// because git suppresses rename detection with pathspecs (shows D instead of R, losing the destination path).\n\t\t'--',\n\t);\n\n\tconst commit = first(parser.parse(result.stdout));\n\tif (commit == null) return undefined;\n\n\tconst file = commit.files.find(f => f.path === pathspec || f.originalPath === pathspec);\n\treturn { sha: commit.sha, file: file };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"diff.js","names":[],"sources":["../../../../git-cli/src/providers/diff.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { GitServiceContext } from '@gitlens/git/context.js';\nimport type {\n\tGitDiff,\n\tGitDiffFiles,\n\tGitDiffFilter,\n\tGitDiffShortStat,\n\tParsedGitDiff,\n\tParsedGitDiffHunks,\n} from '@gitlens/git/models/diff.js';\nimport type { GitFile } from '@gitlens/git/models/file.js';\nimport type { GitRevisionRange, GitRevisionRangeNotation } from '@gitlens/git/models/revision.js';\nimport { deletedOrMissing, uncommitted, uncommittedStaged } from '@gitlens/git/models/revision.js';\nimport {\n\tparseGitApplyFiles,\n\tparseGitDiff,\n\tparseGitDiffNumStatFiles,\n\tparseGitDiffShortStat,\n\tparseGitFileDiff,\n} from '@gitlens/git/parsers/diffParser.js';\nimport type {\n\tGitDiffSubProvider,\n\tNextComparisonUrisResult,\n\tPreviousComparisonUrisResult,\n\tPreviousRangeComparisonUrisResult,\n} from '@gitlens/git/providers/diff.js';\nimport type { DisposableTemporaryGitIndex } from '@gitlens/git/providers/staging.js';\nimport type { DiffRange, RevisionUri } from '@gitlens/git/providers/types.js';\nimport type { GitErrorHandling } from '@gitlens/git/run.types.js';\nimport {\n\tgetRevisionRangeParts,\n\tisRevisionRange,\n\tisUncommitted,\n\tisUncommittedStaged,\n} from '@gitlens/git/utils/revision.utils.js';\nimport { encodeGitLensRevisionUriAuthority } from '@gitlens/git/utils/uriAuthority.js';\nimport { debug } from '@gitlens/utils/decorators/log.js';\nimport { fnv1aHash } from '@gitlens/utils/hash.js';\nimport { first } from '@gitlens/utils/iterable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { normalizePath, splitPath } from '@gitlens/utils/path.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fromUri, toFsPath } from '@gitlens/utils/uri.js';\nimport type { CliGitProviderInternal } from '../cliGitProvider.js';\nimport type { GitResult } from '../exec/exec.types.js';\nimport type { Git } from '../exec/git.js';\nimport { gitConfigsDiff, gitConfigsLog, GitError, GitErrors } from '../exec/git.js';\nimport type { LogParsedFile } from '../parsers/logParser.js';\nimport { getShaAndFileRangeLogParser, getShaAndFileSummaryLogParser } from '../parsers/logParser.js';\n\nexport class DiffGitSubProvider implements GitDiffSubProvider {\n\tconstructor(\n\t\tprivate readonly context: GitServiceContext,\n\t\tprivate readonly git: Git,\n\t\tprivate readonly cache: Cache,\n\t\tprivate readonly provider: CliGitProviderInternal,\n\t) {}\n\n\t@debug()\n\tasync getChangedFilesCount(\n\t\trepoPath: string,\n\t\tto?: string,\n\t\tfrom?: string,\n\t\toptions?: { uris?: (string | Uri)[]; includeUntracked?: boolean; errors?: GitErrorHandling },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiffShortStat | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst args: string[] = [];\n\t\tif (to != null) {\n\t\t\t// Handle revision ranges specially if there is no `from`, otherwise `prepareToFromDiffArgs` will duplicate the range\n\t\t\tif (isRevisionRange(to) && from == null) {\n\t\t\t\targs.push(to);\n\t\t\t} else {\n\t\t\t\tprepareToFromDiffArgs(to, from, args);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// A default run swallows a failure matching a git warning (not a repository, say) into empty output\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, errors: options?.errors === 'throw' ? 'throw' : undefined },\n\t\t\t\t'diff',\n\t\t\t\t'--shortstat',\n\t\t\t\t'--no-ext-diff',\n\t\t\t\t...args,\n\t\t\t\t'--',\n\t\t\t\t...(options?.uris?.map(p => this.provider.getRelativePath(p, repoPath)) ?? []),\n\t\t\t);\n\n\t\t\tconst stat = result.stdout ? parseGitDiffShortStat(result.stdout) : undefined;\n\n\t\t\t// Merge in untracked files when the comparison involves the working tree.\n\t\t\t// Skip when a pathspec filter is active — mixing a path-filtered diff count with an\n\t\t\t// unfiltered untracked count would silently produce wrong totals.\n\t\t\tif (options?.includeUntracked && !options.uris?.length && isWorkingTreeComparison(to, from)) {\n\t\t\t\tconst untracked = (await this.provider.status?.getUntrackedFiles?.(repoPath)) ?? [];\n\t\t\t\tif (untracked.length) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tfiles: (stat?.files ?? 0) + untracked.length,\n\t\t\t\t\t\tadditions: stat?.additions ?? 0,\n\t\t\t\t\t\tdeletions: stat?.deletions ?? 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stat;\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif (options?.errors !== 'throw' && (GitErrors.noMergeBase.test(msg) || GitErrors.badRevision.test(msg))) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDiff(\n\t\trepoPath: string,\n\t\tto: string,\n\t\tfrom?: string,\n\t\toptions?: {\n\t\t\tcontext?: number;\n\t\t\tindex?: DisposableTemporaryGitIndex;\n\t\t\tnotation?: GitRevisionRangeNotation;\n\t\t\turis?: (string | Uri)[];\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiff | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst args = [`-U${options?.context ?? 3}`];\n\n\t\tif (to != null && isRevisionRange(to)) {\n\t\t\tconst parts = getRevisionRangeParts(to);\n\t\t\tif (parts != null) {\n\t\t\t\tto = parts.right ?? '';\n\t\t\t\tfrom = parts.left;\n\t\t\t\toptions = { ...options, notation: parts.notation };\n\t\t\t}\n\t\t}\n\n\t\tconst hasFrom = from != null;\n\t\tfrom = prepareToFromDiffArgs(to, from, args, options?.notation);\n\n\t\tlet paths: Set<string> | undefined;\n\t\tif (options?.uris) {\n\t\t\tpaths = new Set<string>(options.uris.map(p => this.provider.getRelativePath(p, repoPath)));\n\t\t\targs.push('--', ...paths);\n\t\t}\n\n\t\tlet result;\n\t\ttry {\n\t\t\tresult = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, errors: 'throw', env: options?.index?.env },\n\t\t\t\t'diff',\n\t\t\t\t...args,\n\t\t\t\targs.includes('--') ? undefined : '--',\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\t// Before its first commit HEAD names nothing, so a diff from it fails; the empty tree is what it is against\n\t\t\tif (isHead(from) && (await this.isUnbornHeadFailure(repoPath, ex))) {\n\t\t\t\tconst emptyTree = await this.provider.revision.getEmptyTreeSha(repoPath);\n\t\t\t\t// With no `from`, a `to` of HEAD means the working tree against HEAD, so it is the empty tree alone\n\t\t\t\tconst retried = await this.getDiff(\n\t\t\t\t\trepoPath,\n\t\t\t\t\t!hasFrom && isHead(to) ? '' : to,\n\t\t\t\t\temptyTree,\n\t\t\t\t\toptions,\n\t\t\t\t\t_cancellation,\n\t\t\t\t);\n\t\t\t\treturn retried != null ? { ...retried, to: to } : undefined;\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tif (options?.errors === 'throw') throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst diff: GitDiff = { contents: result.stdout, from: from, to: to, notation: options?.notation };\n\t\treturn diff;\n\t}\n\n\t/** Whether `ex` is git failing to resolve `HEAD` because the repository has no commit yet */\n\tprivate async isUnbornHeadFailure(repoPath: string, ex: unknown): Promise<boolean> {\n\t\tconst ref = GitErrors.badRevision.exec(String(ex))?.[1];\n\t\tif (!isHead(ref)) return false;\n\n\t\treturn (await this.provider.refs.validateReference(repoPath, 'HEAD', { force: true })) == null;\n\t}\n\n\t@debug()\n\tasync getParsedDiff(\n\t\trepoPath: string,\n\t\tto: string,\n\t\tfrom?: string,\n\t\toptions?: {\n\t\t\tcontext?: number;\n\t\t\tnotation?: GitRevisionRangeNotation;\n\t\t\turis?: (string | Uri)[];\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ParsedGitDiff | undefined> {\n\t\tconst diff = await this.getDiff(repoPath, to, from, options, cancellation);\n\t\tif (!diff?.contents) return undefined;\n\n\t\treturn parseGitDiff(diff.contents);\n\t}\n\n\t@debug({ args: repoPath => ({ repoPath: repoPath }) })\n\tasync getDiffFiles(\n\t\trepoPath: string,\n\t\tcontents: string,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<GitDiffFiles | undefined> {\n\t\tconst result = await this.git.run(\n\t\t\t{ cwd: repoPath, configs: gitConfigsLog, stdin: contents },\n\t\t\t'apply',\n\t\t\t'--numstat',\n\t\t\t'--summary',\n\t\t\t'-z',\n\t\t\t'-',\n\t\t);\n\t\tif (!result.stdout) return undefined;\n\n\t\tconst files = parseGitApplyFiles(result.stdout, repoPath);\n\t\treturn {\n\t\t\tfiles: files,\n\t\t};\n\t}\n\n\t@debug()\n\tasync getDiffStatus(\n\t\trepoPath: string,\n\t\tref1OrRange: string | GitRevisionRange,\n\t\tref2?: string,\n\t\toptions?: {\n\t\t\tfilters?: GitDiffFilter[];\n\t\t\tincludeUntracked?: boolean;\n\t\t\tpath?: string;\n\t\t\trenameLimit?: number;\n\t\t\tsimilarityThreshold?: number;\n\t\t\terrors?: GitErrorHandling;\n\t\t},\n\t): Promise<GitFile[] | undefined> {\n\t\ttry {\n\t\t\tconst similarityThreshold =\n\t\t\t\toptions?.similarityThreshold ?? this.context.config?.commits.similarityThreshold;\n\t\t\tconst configs =\n\t\t\t\toptions?.renameLimit != null\n\t\t\t\t\t? [...gitConfigsDiff, '-c', `diff.renameLimit=${options.renameLimit}`]\n\t\t\t\t\t: gitConfigsDiff;\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: configs, errors: options?.errors === 'throw' ? 'throw' : undefined },\n\t\t\t\t'diff',\n\t\t\t\t'--numstat',\n\t\t\t\t'--summary',\n\t\t\t\t`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`,\n\t\t\t\t'--no-ext-diff',\n\t\t\t\t'-z',\n\t\t\t\toptions?.filters?.length ? `--diff-filter=${options.filters.join('')}` : undefined,\n\t\t\t\tref1OrRange ? ref1OrRange : undefined,\n\t\t\t\tref2 ? ref2 : undefined,\n\t\t\t\t'--',\n\t\t\t\toptions?.path ? options.path : undefined,\n\t\t\t);\n\n\t\t\tconst files = result.stdout ? (parseGitDiffNumStatFiles(result.stdout, repoPath) ?? []) : [];\n\n\t\t\t// Merge in untracked files when the comparison involves the working tree.\n\t\t\t// Skip when `filters` excludes additions (untracked entries are semantically 'A'/added),\n\t\t\t// or when `path` is a non-exact pathspec we can't reliably match against the untracked list.\n\t\t\tif (\n\t\t\t\toptions?.includeUntracked &&\n\t\t\t\tref2 == null &&\n\t\t\t\ttypeof ref1OrRange === 'string' &&\n\t\t\t\t!isRevisionRange(ref1OrRange) &&\n\t\t\t\t!isUncommittedStaged(ref1OrRange) &&\n\t\t\t\tfiltersAllowUntracked(options.filters) &&\n\t\t\t\t!isNonExactPathspec(options.path)\n\t\t\t) {\n\t\t\t\tconst untracked = (await this.provider.status?.getUntrackedFiles?.(repoPath)) ?? [];\n\t\t\t\tif (untracked.length) {\n\t\t\t\t\tconst seen = new Set(files.map(f => f.path));\n\t\t\t\t\tfor (const file of untracked) {\n\t\t\t\t\t\tif (seen.has(file.path)) continue;\n\t\t\t\t\t\tif (options.path && options.path !== file.path) continue;\n\n\t\t\t\t\t\tfiles.push(file);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn files.length ? files : undefined;\n\t\t} catch (ex) {\n\t\t\tif (options?.errors === 'throw') throw ex;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getDiffTool(repoPath?: string): Promise<string | undefined> {\n\t\treturn (\n\t\t\t(await this.provider.config.getConfig?.(repoPath, 'diff.guitool', { runGitLocally: true })) ??\n\t\t\tthis.provider.config.getConfig?.(repoPath, 'diff.tool', { runGitLocally: true })\n\t\t);\n\t}\n\n\t@debug()\n\tasync getNextComparisonUris(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\tskip: number = 0,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<NextComparisonUrisResult | undefined> {\n\t\t// If we have no revision there is no next commit\n\t\tif (!rev) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\n\t\tif (isUncommittedStaged(rev)) {\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, relativePath, rev),\n\t\t\t\tnext: createRevisionUri(this.provider, repoPath, relativePath, undefined),\n\t\t\t};\n\t\t} else if (isUncommitted(rev)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\t\tconst args = ['log', ...parser.arguments];\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\targs.push(\n\t\t\t\t// Use reverse to get the next commits (oldest to newest instead of newest to oldest)\n\t\t\t\t'--reverse',\n\t\t\t);\n\n\t\t\tif (rev !== deletedOrMissing) {\n\t\t\t\targs.push(\n\t\t\t\t\t// Ancestry path to ensure we only follow the path from the given revision to HEAD\n\t\t\t\t\t'--ancestry-path',\n\t\t\t\t\t// Range from the given revision to HEAD\n\t\t\t\t\t`${rev}..HEAD`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Follow file history and specify the file path\n\t\t\targs.push('--follow', '--', relativePath);\n\n\t\t\t// Unbounded --follow walk over file history can be slow on long histories — queue as background\n\t\t\t// so it doesn't compete with interactive work.\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsLog, priority: 'background' },\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tlet currentSha;\n\t\t\tlet currentPath;\n\n\t\t\tif (skip === 0) {\n\t\t\t\tcurrentSha = rev;\n\t\t\t\tcurrentPath = relativePath;\n\t\t\t} else {\n\t\t\t\tskip--;\n\t\t\t}\n\n\t\t\tlet nextSha;\n\t\t\tlet nextPath;\n\n\t\t\tlet file;\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.path && file.path !== relativePath) {\n\t\t\t\t\trelativePath = file.path;\n\t\t\t\t}\n\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t} else if (nextSha == null) {\n\t\t\t\t\t// if (commit.sha === rev) continue;\n\n\t\t\t\t\tnextSha = commit.sha;\n\t\t\t\t\tnextPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, relativePath);\n\t\t\t\tif (status != null) {\n\t\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\t\tcurrentSha = uncommittedStaged;\n\t\t\t\t\t\tcurrentPath = status.originalPath ?? status.path;\n\t\t\t\t\t\tnextSha = '';\n\t\t\t\t\t\tnextPath = status.path;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (nextSha == null || nextPath == null) {\n\t\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, relativePath);\n\t\t\t\tif (status != null) {\n\t\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\t\tnextSha = uncommittedStaged;\n\t\t\t\t\t\tnextPath = status.originalPath ?? status.path;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnextSha = '';\n\t\t\t\t\t\tnextPath = status.path;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnextSha = '';\n\t\t\t\t\tnextPath = relativePath;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tnext: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tnextPath ?? currentPath,\n\t\t\t\t\t(nextSha ?? deletedOrMissing) || undefined,\n\t\t\t\t),\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getPreviousComparisonUris(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\tskip: number = 0,\n\t\tunsaved?: boolean,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PreviousComparisonUrisResult | undefined> {\n\t\tif (rev === deletedOrMissing) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tif (rev === uncommitted) {\n\t\t\trev = undefined;\n\t\t}\n\n\t\t/* Rules:\n\t\t * Starting from working tree (rev is empty or undefined):\n\t\t * 1. Check file status:\n\t\t * 1.1. If file has both staged and working (or unsaved) changes:\n\t\t * - If skip=0: diff working with staged\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.2. If file has only staged changes:\n\t\t * - If skip=0: diff working with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.3. If file has only working changes:\n\t\t * - If skip=0: diff working with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.4. If file has no changes (or no status found):\n\t\t * - If skip=0: diff working with HEAD~1\n\t\t * - If skip>0: skip through revs starting at HEAD~1\n\t\t *\n\t\t * Starting from staged (rev is uncommittedStaged):\n\t\t * 1. Check file status:\n\t\t * 1.1. If status exists:\n\t\t * - If skip=0: diff staged with HEAD\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * 1.2. If status doesn't exist:\n\t\t * - If skip=0: diff HEAD with HEAD~1\n\t\t * - If skip>0: skip through revs starting at HEAD\n\t\t *\n\t\t * Starting from a commit (rev is a SHA):\n\t\t * - If skip=0: diff SHA with SHA^\n\t\t * - If skip>0: skip through revs starting at SHA\n\t\t */\n\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\t\tlet skipPrev = 0;\n\n\t\tlet revs: [string, string][] = [];\n\t\tif (!rev) {\n\t\t\trevs = [['', relativePath]];\n\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\trevs.push([uncommittedStaged, status.originalPath ?? status.path]);\n\t\t\t\t}\n\n\t\t\t\trevs.push(['HEAD', status.originalPath ?? status.path]);\n\t\t\t\tif (status.workingTreeStatus == null && !unsaved) {\n\t\t\t\t\tif (skip === 0 || status.indexStatus == null) {\n\t\t\t\t\t\t// Skip over the HEAD commit to get a diff, because working and HEAD are the same\n\t\t\t\t\t\tskipPrev++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trevs.push(['HEAD', relativePath]);\n\t\t\t\tif (!unsaved) {\n\t\t\t\t\t// Skip over the HEAD commit to get a diff, because working and HEAD are the same\n\t\t\t\t\tskipPrev++;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isUncommittedStaged(rev)) {\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\trevs = [\n\t\t\t\t\t[uncommittedStaged, status.originalPath ?? status.path],\n\t\t\t\t\t['HEAD', status.originalPath ?? status.path],\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\t// Even though we supposedly started at staged, there is no staged version\n\t\t\t\trevs = [['HEAD', relativePath]];\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet currentSha;\n\t\tlet currentPath;\n\n\t\tif (revs.length) {\n\t\t\tskip++;\n\t\t\twhile (revs.length && skip > 0) {\n\t\t\t\tskip--;\n\t\t\t\t[rev, relativePath] = revs.shift()!;\n\t\t\t}\n\n\t\t\tif (rev !== 'HEAD') {\n\t\t\t\tcurrentSha = rev;\n\t\t\t\tcurrentPath = relativePath;\n\n\t\t\t\tskipPrev++;\n\t\t\t\twhile (revs.length && skipPrev > 0) {\n\t\t\t\t\tskipPrev--;\n\t\t\t\t\t[rev, relativePath] = revs.shift()!;\n\t\t\t\t}\n\n\t\t\t\tif (skipPrev > 0) {\n\t\t\t\t\tskip += skipPrev;\n\t\t\t\t}\n\n\t\t\t\tif (rev !== 'HEAD' && skip === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha),\n\t\t\t\t\t\tprevious: createRevisionUri(this.provider, repoPath, relativePath, rev),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileSummaryLogParser();\n\t\t\tconst args = ['log', ...parser.arguments, `-n${skip + 2}`]; // Don't use --skip as it doesn't work with --follow\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\targs.push('--follow', rev!, '--', relativePath);\n\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tconfigs: gitConfigsLog,\n\t\t\t\t\tcaching: { cache: this.cache.gitResults, options: { accessTTL: 5 * 60 * 1000 } },\n\t\t\t\t},\n\t\t\t\t...args,\n\t\t\t);\n\n\t\t\tlet previousSha;\n\t\t\tlet previousPath;\n\t\t\tlet file;\n\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.originalPath && file.originalPath !== relativePath) {\n\t\t\t\t\trelativePath = file.originalPath;\n\t\t\t\t}\n\n\t\t\t\tif (skip > 0) {\n\t\t\t\t\tskip--;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t} else if (previousSha == null) {\n\t\t\t\t\tif (commit.sha === rev) continue;\n\n\t\t\t\t\tpreviousSha = commit.sha;\n\t\t\t\t\tpreviousPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) return undefined;\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tprevious: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpreviousPath ?? currentPath,\n\t\t\t\t\tpreviousSha ?? deletedOrMissing,\n\t\t\t\t),\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync getPreviousComparisonUrisForRange(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\trev: string | undefined,\n\t\trange: DiffRange,\n\t\toptions?: { ordering?: 'date' | 'author-date' | 'topo' | null; skipFirstRev?: boolean },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PreviousRangeComparisonUrisResult | undefined> {\n\t\tif (rev === deletedOrMissing) return undefined;\n\n\t\tconst scope = getScopedLogger();\n\n\t\tif (rev === uncommitted) {\n\t\t\trev = undefined;\n\t\t}\n\n\t\tlet currentSha;\n\t\tlet currentPath;\n\t\tlet relativePath = this.provider.getRelativePath(pathOrUri, repoPath);\n\t\tconst skipFirstRev = options?.skipFirstRev ?? true;\n\n\t\t// If we are at the working tree (i.e. no ref), we need to dig deeper to figure out where to go\n\t\tif (!rev) {\n\t\t\tconst status = await this.provider.status?.getStatusForFile?.(repoPath, pathOrUri);\n\t\t\tif (status != null) {\n\t\t\t\tif (status.indexStatus != null) {\n\t\t\t\t\tif (status.workingTreeStatus != null && !skipFirstRev) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, relativePath, undefined),\n\t\t\t\t\t\t\tprevious: createRevisionUri(this.provider, repoPath, relativePath, uncommittedStaged),\n\t\t\t\t\t\t\trange: range,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrentSha = uncommittedStaged;\n\t\t\t\t\tcurrentPath = status.originalPath ?? status.path;\n\t\t\t\t\tif (status.originalPath != null) {\n\t\t\t\t\t\trelativePath = status.originalPath;\n\t\t\t\t\t}\n\t\t\t\t\trev = uncommittedStaged;\n\t\t\t\t} else if (status.workingTreeStatus != null && !skipFirstRev) {\n\t\t\t\t\tcurrentSha = '';\n\t\t\t\t\tcurrentPath = relativePath;\n\t\t\t\t\trev = '';\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (!skipFirstRev) {\n\t\t\tcurrentSha = rev;\n\t\t\tcurrentPath = relativePath;\n\t\t}\n\n\t\ttry {\n\t\t\tconst parser = getShaAndFileRangeLogParser();\n\t\t\tconst args = ['log', ...parser.arguments, '-n2']; // Don't use --skip as it doesn't work with --follow\n\n\t\t\tconst ordering = options?.ordering ?? this.context.config?.commits.ordering;\n\t\t\tif (ordering) {\n\t\t\t\targs.push(`--${ordering}-order`);\n\t\t\t}\n\n\t\t\tif (rev && !isUncommittedStaged(rev)) {\n\t\t\t\targs.push(rev);\n\t\t\t}\n\n\t\t\targs.push(`-L${range.startLine},${range.endLine}:${relativePath}`);\n\n\t\t\tlet result: GitResult;\n\t\t\ttry {\n\t\t\t\tresult = await this.git.run({ cwd: repoPath, configs: gitConfigsLog }, ...args);\n\t\t\t} catch (ex) {\n\t\t\t\tif (rev && !isUncommittedStaged(rev)) throw ex;\n\n\t\t\t\t// If the line count is invalid reset to a valid range\n\t\t\t\tconst match = GitErrors.invalidLineCount.exec(ex?.toString() ?? '');\n\t\t\t\tif (match == null) throw ex;\n\n\t\t\t\tconst line = parseInt(match[1], 10);\n\t\t\t\tif (isNaN(line)) throw ex;\n\n\t\t\t\tconst index = args.findIndex(a => a.startsWith('-L'));\n\t\t\t\tif (index === -1) throw ex;\n\n\t\t\t\trange = {\n\t\t\t\t\tstartLine: Math.min(range.startLine, line),\n\t\t\t\t\tstartCharacter: range.startCharacter,\n\t\t\t\t\tendLine: Math.min(range.endLine, line),\n\t\t\t\t\tendCharacter: range.endCharacter,\n\t\t\t\t\tactive: range.active,\n\t\t\t\t};\n\n\t\t\t\targs.splice(index, 1, `-L${range.startLine},${range.endLine}:${relativePath}`);\n\t\t\t\tresult = await this.git.run({ cwd: repoPath, configs: gitConfigsLog }, ...args);\n\t\t\t}\n\n\t\t\tlet currentRange;\n\t\t\tlet previousSha;\n\t\t\tlet previousPath;\n\t\t\tlet file;\n\n\t\t\tfor (const commit of parser.parse(result.stdout)) {\n\t\t\t\tconst path = relativePath;\n\t\t\t\tfile = commit.files.find(f => f.path === path || f.originalPath === path);\n\t\t\t\t// If we couldn't find the file, but there is only one file in the commit, use that one and assume the filename changed\n\t\t\t\tif (file == null && commit.files.length === 1) {\n\t\t\t\t\tfile = commit.files[0];\n\t\t\t\t\trelativePath = file.path;\n\t\t\t\t}\n\t\t\t\t// Keep track of the file changing paths\n\t\t\t\tif (file?.originalPath && file.originalPath !== relativePath) {\n\t\t\t\t\trelativePath = file.originalPath;\n\t\t\t\t}\n\n\t\t\t\tif (currentSha == null) {\n\t\t\t\t\tcurrentSha = commit.sha;\n\t\t\t\t\tcurrentPath = file?.path ?? relativePath;\n\t\t\t\t\tcurrentRange =\n\t\t\t\t\t\tfile?.range != null ? { ...file.range, startCharacter: 1, endCharacter: 1 } : undefined;\n\t\t\t\t} else if (previousSha == null) {\n\t\t\t\t\tif (commit.sha === rev) continue;\n\n\t\t\t\t\tpreviousSha = commit.sha;\n\t\t\t\t\tpreviousPath = file?.path ?? relativePath;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentSha == null || currentPath == null) return undefined;\n\n\t\t\t// If we have no previous SHA but have a real current SHA, resolve the parent commit.\n\t\t\t// This handles the case where a line is newly added — the line has no prior history,\n\t\t\t// but the file likely existed at the parent commit\n\t\t\tif (previousSha == null && currentSha) {\n\t\t\t\tpreviousSha =\n\t\t\t\t\t(await this.provider.refs.validateReference(repoPath, `${currentSha}^`)) ?? deletedOrMissing;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcurrent: createRevisionUri(this.provider, repoPath, currentPath, currentSha || undefined),\n\t\t\t\tprevious: createRevisionUri(\n\t\t\t\t\tthis.provider,\n\t\t\t\t\trepoPath,\n\t\t\t\t\tpreviousPath ?? currentPath,\n\t\t\t\t\tpreviousSha ?? deletedOrMissing,\n\t\t\t\t),\n\t\t\t\trange: currentRange ?? range,\n\t\t\t};\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Returns raw diff output for a file between two revisions. */\n\tasync diff(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1?: string,\n\t\tref2?: string,\n\t\toptions?: {\n\t\t\tencoding?: string;\n\t\t\tfilters?: GitDiffFilter[];\n\t\t\tlinesOfContext?: number;\n\t\t\trenames?: boolean;\n\t\t\tsimilarityThreshold?: number | null;\n\t\t},\n\t): Promise<GitResult> {\n\t\tconst params = ['diff', '--no-ext-diff', '--minimal'];\n\n\t\tif (options?.linesOfContext != null) {\n\t\t\tparams.push(`-U${options.linesOfContext}`);\n\t\t}\n\n\t\tif (options?.renames) {\n\t\t\tparams.push(`-M${options.similarityThreshold == null ? '' : `${options.similarityThreshold}%`}`);\n\t\t}\n\n\t\tif (options?.filters != null && options.filters.length !== 0) {\n\t\t\tparams.push(`--diff-filter=${options.filters.join('')}`);\n\t\t}\n\n\t\tif (ref1) {\n\t\t\t// <sha>^3 signals an untracked file in a stash and if we are trying to find its parent, use the empty tree\n\t\t\tif (ref1.endsWith('^3^')) {\n\t\t\t\tref1 = await this.provider.revision.getEmptyTreeSha(repoPath);\n\t\t\t}\n\t\t\tparams.push(isUncommittedStaged(ref1) ? '--staged' : ref1);\n\t\t}\n\t\tif (ref2) {\n\t\t\tparams.push(isUncommittedStaged(ref2) ? '--staged' : ref2);\n\t\t}\n\n\t\ttry {\n\t\t\treturn await this.git.run(\n\t\t\t\t{ cwd: repoPath, configs: gitConfigsDiff, encoding: options?.encoding },\n\t\t\t\t...params,\n\t\t\t\t'--',\n\t\t\t\tfileName,\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tconst match = GitErrors.badRevision.exec(ex.message);\n\t\t\tif (match !== null) {\n\t\t\t\tconst [, ref] = match;\n\n\t\t\t\t// If the bad ref is trying to find a parent ref, assume we hit to the last commit, so try again using the empty tree\n\t\t\t\tif (ref === ref1 && ref?.endsWith('^')) {\n\t\t\t\t\treturn this.diff(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tfileName,\n\t\t\t\t\t\tawait this.provider.revision.getEmptyTreeSha(repoPath),\n\t\t\t\t\t\tref2,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Returns raw diff output comparing a file's revision with given contents via stdin. */\n\tasync diffContents(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions?: { encoding?: string; filters?: GitDiffFilter[]; similarityThreshold?: number | null },\n\t): Promise<string> {\n\t\tconst params = [\n\t\t\t'diff',\n\t\t\t`-M${options?.similarityThreshold == null ? '' : `${options.similarityThreshold}%`}`,\n\t\t\t'--no-ext-diff',\n\t\t\t'-U0',\n\t\t\t'--minimal',\n\t\t];\n\n\t\tif (options?.filters != null && options.filters.length !== 0) {\n\t\t\tparams.push(`--diff-filter=${options.filters.join('')}`);\n\t\t}\n\n\t\tparams.push('--no-index');\n\n\t\ttry {\n\t\t\tconst result = await this.git.run(\n\t\t\t\t{\n\t\t\t\t\tcwd: repoPath,\n\t\t\t\t\tconfigs: gitConfigsDiff,\n\t\t\t\t\tencoding: options?.encoding,\n\t\t\t\t\tstdin: contents,\n\t\t\t\t},\n\t\t\t\t...params,\n\t\t\t\t'--',\n\t\t\t\tfileName,\n\t\t\t\t// Pipe the contents to stdin\n\t\t\t\t'-',\n\t\t\t);\n\t\t\treturn result.stdout;\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof GitError && ex.stdout) {\n\t\t\t\treturn ex.stdout;\n\t\t\t}\n\n\t\t\tconst match = GitErrors.badRevision.exec(ex.message);\n\t\t\tif (match !== null) {\n\t\t\t\tconst [, matchedRef] = match;\n\n\t\t\t\t// If the bad ref is trying to find a parent ref, assume we hit to the last commit, so try again using the empty tree\n\t\t\t\tif (matchedRef === ref && matchedRef?.endsWith('^')) {\n\t\t\t\t\treturn this.diffContents(\n\t\t\t\t\t\trepoPath,\n\t\t\t\t\t\tfileName,\n\t\t\t\t\t\tawait this.provider.revision.getEmptyTreeSha(repoPath),\n\t\t\t\t\t\tcontents,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/** Returns parsed diff hunks for a file between two revisions. */\n\t@debug()\n\tgetDiffForFile(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1: string | undefined,\n\t\tref2?: string,\n\t\toptions?: { encoding?: string },\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst cacheKey = `${normalizePath(fileName)}:${ref1 ?? ''}:${ref2 ?? ''}`;\n\t\treturn this.cache.diff.getOrCreate(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\t() => this.getDiffForFileCore(repoPath, fileName, ref1, ref2, options),\n\t\t\t{ errorTTL: 1000 * 60 },\n\t\t);\n\t}\n\n\tprivate async getDiffForFileCore(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref1: string | undefined,\n\t\tref2: string | undefined,\n\t\toptions: { encoding?: string } | undefined,\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\t// Include renames (R) and copies (C) so content diffs on renamed files still surface;\n\t\t// --diff-filter runs after `-M` rename detection, so 'M' alone would drop valid rename diffs.\n\t\tconst result = await this.diff(repoPath, fileName, ref1, ref2, {\n\t\t\tencoding: options?.encoding,\n\t\t\tfilters: ['M', 'R', 'C'],\n\t\t\tlinesOfContext: 0,\n\t\t\trenames: true,\n\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t});\n\t\treturn parseGitFileDiff(result.stdout);\n\t}\n\n\t/** Returns parsed diff hunks comparing a file's revision with given contents via stdin. */\n\t@debug()\n\tgetDiffForFileContents(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions?: { encoding?: string },\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst cacheKey = `${normalizePath(fileName)}:${ref}:~${fnv1aHash(contents)}`;\n\t\treturn this.cache.diff.getOrCreate(\n\t\t\trepoPath,\n\t\t\tcacheKey,\n\t\t\t() => this.getDiffForFileContentsCore(repoPath, fileName, ref, contents, options),\n\t\t\t{ errorTTL: 1000 * 60 },\n\t\t);\n\t}\n\n\tprivate async getDiffForFileContentsCore(\n\t\trepoPath: string,\n\t\tfileName: string,\n\t\tref: string,\n\t\tcontents: string,\n\t\toptions: { encoding?: string } | undefined,\n\t): Promise<ParsedGitDiffHunks | undefined> {\n\t\tconst data = await this.diffContents(repoPath, fileName, ref, contents, {\n\t\t\tencoding: options?.encoding,\n\t\t\tfilters: ['M', 'R', 'C'],\n\t\t\tsimilarityThreshold: this.context.config?.commits.similarityThreshold,\n\t\t});\n\t\treturn parseGitFileDiff(data);\n\t}\n\n\t/** Finds the most recent commit where the given path was copied, renamed, or deleted. */\n\t@debug()\n\tasync findPathStatusChanged(\n\t\trepoPath: string,\n\t\tpathspec: string,\n\t\trev: string | undefined,\n\t\toptions?: { filters?: GitDiffFilter[]; ordering?: 'date' | 'author-date' | 'topo' | null },\n\t): Promise<{ sha: string; file: LogParsedFile | undefined } | undefined> {\n\t\treturn findPathStatusChanged(this.git, repoPath, pathspec, rev, options);\n\t}\n\n\t@debug()\n\tasync openDiffTool(\n\t\trepoPath: string,\n\t\tpathOrUri: string | Uri,\n\t\toptions?: { ref1?: string; ref2?: string; staged?: boolean; tool?: string },\n\t): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\t\tconst [relativePath, root] = splitPath(toFsPath(pathOrUri), repoPath);\n\n\t\ttry {\n\t\t\tlet tool = options?.tool;\n\t\t\tif (!tool) {\n\t\t\t\tconst scope = getScopedLogger();\n\n\t\t\t\ttool = await this.getDiffTool(root);\n\t\t\t\tif (tool == null) throw new Error('No diff tool found');\n\n\t\t\t\tscope?.debug(`Using tool=${tool}`);\n\t\t\t}\n\n\t\t\tawait this.git.run(\n\t\t\t\t{ cwd: root },\n\t\t\t\t'difftool',\n\t\t\t\t'--no-prompt',\n\t\t\t\t`--tool=${tool}`,\n\t\t\t\toptions?.staged ? '--staged' : undefined,\n\t\t\t\toptions?.ref1 ? options.ref1 : undefined,\n\t\t\t\toptions?.ref2 ? options.ref2 : undefined,\n\t\t\t\t'--',\n\t\t\t\trelativePath,\n\t\t\t);\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif ((ex instanceof Error && ex.message === 'No diff tool found') || /Unknown .+? tool/.test(msg)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Unable to open changes because the specified diff tool cannot be found or no Git diff tool is configured',\n\t\t\t\t\t),\n\t\t\t\t\t{ cause: ex },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@debug()\n\tasync openDirectoryCompare(repoPath: string, ref1: string, ref2?: string, tool?: string): Promise<void> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tif (!tool) {\n\t\t\t\tconst scope = getScopedLogger();\n\n\t\t\t\ttool = await this.getDiffTool(repoPath);\n\t\t\t\tif (tool == null) throw new Error('No diff tool found');\n\n\t\t\t\tscope?.debug(`Using tool=${tool}`);\n\t\t\t}\n\n\t\t\tawait this.git.run({ cwd: repoPath }, 'difftool', '--dir-diff', `--tool=${tool}`, ref1, ref2);\n\t\t} catch (ex) {\n\t\t\tconst msg: string = ex?.toString() ?? '';\n\t\t\tif ((ex instanceof Error && ex.message === 'No diff tool found') || /Unknown .+? tool/.test(msg)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tl10n.t(\n\t\t\t\t\t\t'Unable to open directory compare because the specified diff tool cannot be found or no Git diff tool is configured',\n\t\t\t\t\t),\n\t\t\t\t\t{ cause: ex },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\tthrow ex;\n\t\t}\n\t}\n}\n// Returns true when no --diff-filter is active or when it includes additions ('A' or '*').\n// Untracked files are semantically \"added\" — if a caller restricts filters to e.g. ['M'],\n// honor that and omit untracked.\nfunction filtersAllowUntracked(filters: GitDiffFilter[] | undefined): boolean {\n\tif (!filters?.length) return true;\n\treturn filters.includes('A') || filters.includes('*');\n}\n\n// Returns true when the path is a git pathspec we can't match with simple equality\n// (directory prefix, glob, or magic pathspec). In that case, skip the untracked merge\n// rather than risk excluding legitimate matches or including wrong ones.\nfunction isNonExactPathspec(path: string | undefined): boolean {\n\tif (!path) return false;\n\treturn path.endsWith('/') || /[*?[\\]]|^:/.test(path);\n}\n\n// Returns true when the `git diff` invocation shape includes the working tree\n// (i.e. `git diff`, `git diff HEAD`, or `git diff <ref>` with no `from`), and\n// therefore untracked files are a meaningful addition to the result.\nfunction isWorkingTreeComparison(to: string | undefined, from: string | undefined): boolean {\n\tif (to == null) return true;\n\tif (isRevisionRange(to) || isUncommittedStaged(to)) return false;\n\n\t// `to === uncommitted` always targets the working tree (`prepareToFromDiffArgs` sets\n\t// `from = 'HEAD'` when omitted, or diffs against the caller-supplied `from`).\n\tif (isUncommitted(to)) return true;\n\n\t// `git diff <from>` — `to === ''` means the caller explicitly asked for working tree vs `from`\n\tif (to === '') return from == null || !isUncommittedStaged(from);\n\n\t// `getChangedFilesCount` uses `prepareToFromDiffArgs`, which translates `to` (with no `from`)\n\t// to `${to}^ ${to}` UNLESS `to` is HEAD or empty.\n\tif (isHead(to) && from == null) return true;\n\treturn false;\n}\n\nfunction isHead(ref: string | undefined): boolean {\n\treturn ref?.toUpperCase() === 'HEAD';\n}\n\nfunction prepareToFromDiffArgs(\n\tto: string,\n\tfrom: string | undefined,\n\targs: string[],\n\tnotation?: GitRevisionRangeNotation,\n): string {\n\tif (to === uncommitted) {\n\t\tif (from != null) {\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\t// Get only unstaged changes\n\t\t\tfrom = 'HEAD';\n\t\t}\n\t} else if (to === uncommittedStaged) {\n\t\targs.push('--staged');\n\t\tif (from != null) {\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\t// Get only staged changes\n\t\t\tfrom = 'HEAD';\n\t\t}\n\t} else if (from == null) {\n\t\tif (to === '' || isHead(to)) {\n\t\t\tfrom = 'HEAD';\n\t\t\targs.push(from);\n\t\t} else {\n\t\t\tfrom = `${to}^`;\n\t\t\targs.push(from, to);\n\t\t}\n\t} else if (to === '') {\n\t\targs.push(from);\n\t} else if (notation != null) {\n\t\targs.push(`${from}${notation}${to}`);\n\t} else {\n\t\targs.push(from, to);\n\t}\n\treturn from;\n}\n\nfunction createRevisionUri(\n\tprovider: CliGitProviderInternal,\n\trepoPath: string,\n\trelativePath: string,\n\tsha: string | undefined,\n): RevisionUri {\n\treturn {\n\t\turi: sha\n\t\t\t? fromUri({\n\t\t\t\t\tscheme: 'gitlens',\n\t\t\t\t\tauthority: encodeGitLensRevisionUriAuthority({ ref: sha, repoPath: repoPath }),\n\t\t\t\t\tpath: provider.getAbsoluteUri(relativePath, repoPath).path,\n\t\t\t\t})\n\t\t\t: provider.getAbsoluteUri(relativePath, repoPath),\n\t\tpath: relativePath,\n\t\tsha: sha,\n\t\trepoPath: repoPath,\n\t};\n}\n\nexport async function findPathStatusChanged(\n\tgit: Git,\n\trepoPath: string,\n\tpathspec: string,\n\trev: string | undefined,\n\toptions?: { filters?: GitDiffFilter[]; ordering?: 'date' | 'author-date' | 'topo' | null },\n): Promise<{ sha: string; file: LogParsedFile | undefined } | undefined> {\n\tconst parser = getShaAndFileSummaryLogParser();\n\n\tconst ordering = options?.ordering;\n\n\tconst result = await git.run(\n\t\t{ cwd: repoPath, configs: gitConfigsLog },\n\t\t'log',\n\t\t...parser.arguments,\n\t\tordering ? `--${ordering}-order` : undefined,\n\t\t'--no-walk',\n\t\t`--diff-filter=${options?.filters?.length ? options.filters.join('') : 'RCD'}`,\n\t\trev,\n\t\t// Note: --no-walk constrains to the exact commit (no ancestor search). Pathspec is omitted\n\t\t// because git suppresses rename detection with pathspecs (shows D instead of R, losing the destination path).\n\t\t'--',\n\t);\n\n\tconst commit = first(parser.parse(result.stdout));\n\tif (commit == null) return undefined;\n\n\tconst file = commit.files.find(f => f.path === pathspec || f.originalPath === pathspec);\n\treturn { sha: commit.sha, file: file };\n}\n"],"mappings":"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"}
|
|
@@ -62,6 +62,7 @@ export declare class OperationsGitSubProvider implements GitOperationsSubProvide
|
|
|
62
62
|
tags?: boolean;
|
|
63
63
|
source?: unknown;
|
|
64
64
|
}, runOptions?: GitOperationRunOptions): Promise<void>;
|
|
65
|
+
private announcePull;
|
|
65
66
|
private pullCore;
|
|
66
67
|
push(repoPath: string, options?: {
|
|
67
68
|
reference?: GitReference;
|