Skip to content

Commit 11ee8e7

Browse files
committed
Fixes pull request comparisons
1 parent 0405035 commit 11ee8e7

File tree

11 files changed

+194
-115
lines changed

11 files changed

+194
-115
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
2222

2323
- Fixes [#3152](https://github.com/gitkraken/vscode-gitlens/issues/3152) - Fixes double encoding of redirect URLs during account sign-in which affects certain environments
2424
- Fixes [#3153](https://github.com/gitkraken/vscode-gitlens/issues/3153) - `gitlens.defaultDateStyle` not working in Commit Details view
25+
- Fixes the _Open Pull Request Changes_ & _Compare Pull Request_ commands to scope the changes only to the pull request
2526
- Fixes issue when switching to a worktree via branch switch when there are multiple repos in the workspace
2627

2728
## [14.8.2] - 2024-02-16

src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ export interface StoredRepoVisibilityInfo {
970970

971971
export interface StoredBranchComparison {
972972
ref: string;
973+
label?: string;
973974
notation: '..' | '...' | undefined;
974975
type: Exclude<ViewShowBranchComparison, false> | undefined;
975976
checkedFiles?: string[];

src/git/actions/commit.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { showRevisionFilesPicker } from '../../quickpicks/revisionFilesPicker';
1616
import { executeCommand, executeCoreGitCommand, executeEditorCommand } from '../../system/command';
1717
import { configuration } from '../../system/configuration';
1818
import { findOrOpenEditor, findOrOpenEditors, openChangesEditor } from '../../system/utils';
19+
import { getAheadBehindFilesQuery } from '../../views/nodes/compareResultsNode';
1920
import { GitUri } from '../gitUri';
2021
import type { GitCommit } from '../models/commit';
2122
import { isCommit } from '../models/commit';
@@ -24,15 +25,16 @@ import type { GitFile } from '../models/file';
2425
import { GitFileChange } from '../models/file';
2526
import type { GitRevisionReference } from '../models/reference';
2627
import {
28+
createRevisionRange,
2729
getReferenceFromRevision,
2830
getReferenceLabel,
2931
isUncommitted,
3032
isUncommittedStaged,
3133
shortenRevision,
3234
} from '../models/reference';
3335

34-
type Ref = { repoPath: string; ref: string };
35-
type RefRange = { repoPath: string; rhs: string; lhs: string };
36+
export type Ref = { repoPath: string; ref: string };
37+
export type RefRange = { repoPath: string; rhs: string; lhs: string };
3638

3739
export interface FilesComparison {
3840
files: GitFile[];
@@ -454,6 +456,24 @@ export async function openChangesWithWorking(
454456
}));
455457
}
456458

459+
export async function openComparisonChanges(
460+
container: Container,
461+
refs: RefRange,
462+
options?: TextDocumentShowOptions & { title?: string },
463+
): Promise<void> {
464+
refs.lhs = refs.lhs || 'HEAD';
465+
refs.rhs = refs.rhs || 'HEAD';
466+
467+
const { files } = await getAheadBehindFilesQuery(
468+
container,
469+
refs.repoPath,
470+
createRevisionRange(refs.lhs, refs.rhs, '...'),
471+
refs.rhs === '',
472+
);
473+
474+
await openAllChangesInChangesEditor(files ?? [], refs, options);
475+
}
476+
457477
export async function openDirectoryCompare(
458478
repoPath: string,
459479
ref: string,

src/git/models/pullRequest.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Container } from '../../container';
22
import { formatDate, fromNow } from '../../system/date';
33
import { memoize } from '../../system/decorators/memoize';
44
import type { IssueOrPullRequest, IssueOrPullRequestState as PullRequestState } from './issue';
5+
import { shortenRevision } from './reference';
56
import type { RemoteProviderReference } from './remoteProvider';
67

78
export type { PullRequestState };
@@ -202,3 +203,31 @@ export class PullRequest implements PullRequestShape {
202203
return fromNow(this.date);
203204
}
204205
}
206+
207+
export interface PullRequestComparisonRefs {
208+
repoPath: string;
209+
base: { ref: string; label: string };
210+
head: { ref: string; label: string };
211+
}
212+
213+
export async function getComparisonRefsForPullRequest(
214+
container: Container,
215+
repoPath: string,
216+
prRefs: PullRequestRefs,
217+
): Promise<PullRequestComparisonRefs> {
218+
const refs: PullRequestComparisonRefs = {
219+
repoPath: repoPath,
220+
base: { ref: prRefs.base.sha, label: `${prRefs.base.branch} (${shortenRevision(prRefs.base.sha)})` },
221+
head: { ref: prRefs.head.sha, label: prRefs.head.branch },
222+
};
223+
224+
// Find the merge base to show a more accurate comparison for the PR
225+
const mergeBase =
226+
(await container.git.getMergeBase(refs.repoPath, refs.base.ref, refs.head.ref, { forkPoint: true })) ??
227+
(await container.git.getMergeBase(refs.repoPath, refs.base.ref, refs.head.ref));
228+
if (mergeBase != null) {
229+
refs.base = { ref: mergeBase, label: `${prRefs.base.branch} (${shortenRevision(mergeBase)})` };
230+
}
231+
232+
return refs;
233+
}

src/plus/integrations/providers/github/models.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export function fromGitHubPullRequest(pr: GitHubPullRequest, provider: Provider)
185185
head: {
186186
exists: pr.headRepository != null,
187187
owner: pr.headRepository?.owner.login,
188-
repo: pr.baseRepository?.name,
188+
repo: pr.headRepository?.name,
189189
sha: pr.headRefOid,
190190
branch: pr.headRefName,
191191
url: pr.headRepository?.url,
@@ -284,7 +284,7 @@ export function fromGitHubPullRequestDetailed(pr: GitHubDetailedPullRequest, pro
284284
head: {
285285
exists: pr.headRepository != null,
286286
owner: pr.headRepository?.owner.login,
287-
repo: pr.baseRepository?.name,
287+
repo: pr.headRepository?.name,
288288
sha: pr.headRefOid,
289289
branch: pr.headRefName,
290290
url: pr.headRepository?.url,

src/plus/webviews/graph/graphWebview.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
openAllChangesIndividually,
2323
openAllChangesWithWorking,
2424
openAllChangesWithWorkingIndividually,
25+
openComparisonChanges,
2526
openFiles,
2627
openFilesAtRevision,
2728
openOnlyChangedFiles,
@@ -39,6 +40,7 @@ import type { GitCommit } from '../../../git/models/commit';
3940
import { uncommitted } from '../../../git/models/constants';
4041
import { GitContributor } from '../../../git/models/contributor';
4142
import type { GitGraph, GitGraphRowType } from '../../../git/models/graph';
43+
import { getComparisonRefsForPullRequest } from '../../../git/models/pullRequest';
4244
import type {
4345
GitBranchReference,
4446
GitReference,
@@ -2689,14 +2691,18 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
26892691
}
26902692

26912693
@debug()
2692-
private openPullRequestChanges(item?: GraphItemContext) {
2694+
private async openPullRequestChanges(item?: GraphItemContext) {
26932695
if (isGraphItemTypedContext(item, 'pullrequest')) {
26942696
const pr = item.webviewItemValue;
26952697
if (pr.refs?.base != null && pr.refs.head != null) {
2696-
return this.container.searchAndCompareView.openComparisonChanges(
2697-
pr.repoPath,
2698-
{ ref: pr.refs.head.sha, label: pr.refs.head.branch },
2699-
{ ref: pr.refs.base.sha, label: pr.refs.base.branch },
2698+
const refs = await getComparisonRefsForPullRequest(this.container, pr.repoPath, pr.refs);
2699+
return openComparisonChanges(
2700+
this.container,
2701+
{
2702+
repoPath: refs.repoPath,
2703+
lhs: refs.base.ref,
2704+
rhs: refs.head.ref,
2705+
},
27002706
{ title: `Changes in Pull Request #${pr.id}` },
27012707
);
27022708
}
@@ -2706,15 +2712,12 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
27062712
}
27072713

27082714
@debug()
2709-
private openPullRequestComparison(item?: GraphItemContext) {
2715+
private async openPullRequestComparison(item?: GraphItemContext) {
27102716
if (isGraphItemTypedContext(item, 'pullrequest')) {
27112717
const pr = item.webviewItemValue;
27122718
if (pr.refs?.base != null && pr.refs.head != null) {
2713-
return this.container.searchAndCompareView.compare(
2714-
pr.repoPath,
2715-
{ ref: pr.refs.head.sha, label: pr.refs.head.branch },
2716-
{ ref: pr.refs.base.sha, label: pr.refs.base.branch },
2717-
);
2719+
const refs = await getComparisonRefsForPullRequest(this.container, pr.repoPath, pr.refs);
2720+
return this.container.searchAndCompareView.compare(refs.repoPath, refs.head, refs.base);
27182721
}
27192722
}
27202723

src/views/nodes/branchNode.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { MarkdownString, ThemeColor, ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri, window } from 'vscode';
22
import type { ViewShowBranchComparison } from '../../config';
3-
import type { Colors } from '../../constants';
3+
import type { Colors, StoredBranchComparison } from '../../constants';
44
import { GlyphChars } from '../../constants';
55
import type { GitUri } from '../../git/gitUri';
66
import type { GitBranch } from '../../git/models/branch';
77
import type { GitLog } from '../../git/models/log';
88
import type { PullRequest, PullRequestState } from '../../git/models/pullRequest';
99
import type { GitBranchReference } from '../../git/models/reference';
10+
import { shortenRevision } from '../../git/models/reference';
1011
import { getHighlanderProviders } from '../../git/models/remote';
1112
import type { Repository } from '../../git/models/repository';
1213
import type { GitUser } from '../../git/models/user';
@@ -160,6 +161,18 @@ export class BranchNode
160161
let pullRequest;
161162
let pullRequestInsertIndex = 0;
162163

164+
function getPullRequestComparison(pr: PullRequest | null | undefined): StoredBranchComparison | undefined {
165+
if (pr?.refs?.base == null && pr?.refs?.head == null) return undefined;
166+
167+
return {
168+
ref: pr.refs.base.sha,
169+
label: `${pr.refs.base.branch} (${shortenRevision(pr.refs.base.sha)})`,
170+
notation: '...',
171+
type: 'branch',
172+
checkedFiles: [],
173+
};
174+
}
175+
163176
if (
164177
this.view.config.pullRequests.enabled &&
165178
this.view.config.pullRequests.showForBranches &&
@@ -194,6 +207,18 @@ export class BranchNode
194207
0,
195208
new PullRequestNode(this.view, this, pr, branch),
196209
);
210+
211+
if (pr?.refs?.base != null && pr?.refs?.head != null) {
212+
const comparisonNode = this.children.find((n): n is CompareBranchNode =>
213+
n.is('compare-branch'),
214+
);
215+
if (comparisonNode != null) {
216+
const comparison = getPullRequestComparison(pr);
217+
if (comparison != null) {
218+
await comparisonNode.setDefaultCompareWith(comparison);
219+
}
220+
}
221+
}
197222
}
198223

199224
// Refresh this node to add the pull request node or remove the spinner
@@ -319,6 +344,7 @@ export class BranchNode
319344
branch,
320345
this.options.showComparison,
321346
this.splatted,
347+
getPullRequestComparison(pullRequest),
322348
),
323349
);
324350
}

src/views/nodes/compareBranchNode.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,16 @@ export class CompareBranchNode extends SubscribeableViewNode<
4949
private showComparison: ViewShowBranchComparison,
5050
// Specifies that the node is shown as a root
5151
public readonly root: boolean = false,
52+
defaultCompareWith?: StoredBranchComparison,
5253
) {
5354
super('compare-branch', uri, view, parent);
5455

5556
this.updateContext({ branch: branch, root: root, storedComparisonId: this.getStorageId() });
5657
this._uniqueId = getViewNodeId(this.type, this.context);
5758
this.loadCompareWith();
59+
if (defaultCompareWith != null) {
60+
void this.setDefaultCompareWith(defaultCompareWith);
61+
}
5862
}
5963

6064
protected override etag(): number {
@@ -199,12 +203,12 @@ export class CompareBranchNode extends SubscribeableViewNode<
199203
this.compareWithWorkingTree ? 'Working Tree' : this.branch.name
200204
} with a branch, tag, or ref`;
201205
} else {
202-
label = `Compare ${this.compareWithWorkingTree ? 'Working Tree' : this.branch.name} with ${shortenRevision(
203-
this._compareWith.ref,
204-
{
206+
label = `Compare ${this.compareWithWorkingTree ? 'Working Tree' : this.branch.name} with ${
207+
this._compareWith.label ??
208+
shortenRevision(this._compareWith.ref, {
205209
strings: { working: 'Working Tree' },
206-
},
207-
)}`;
210+
})
211+
}`;
208212
state = TreeItemCollapsibleState.Collapsed;
209213
}
210214

@@ -270,6 +274,13 @@ export class CompareBranchNode extends SubscribeableViewNode<
270274
this.view.triggerNodeChange(this);
271275
}
272276

277+
@log()
278+
async setDefaultCompareWith(compareWith: StoredBranchComparison) {
279+
if (this._compareWith != null) return;
280+
281+
await this.updateCompareWith(compareWith);
282+
}
283+
273284
private get comparisonType() {
274285
return this._compareWith?.type ?? this.showComparison;
275286
}

0 commit comments

Comments
 (0)