Browse Source

Adds open/copy comparison on remote

main
Eric Amodio 4 years ago
parent
commit
871451652a
17 changed files with 263 additions and 52 deletions
  1. +50
    -13
      package.json
  2. +1
    -0
      src/commands.ts
  3. +2
    -0
      src/commands/common.ts
  4. +63
    -0
      src/commands/openComparisonOnRemote.ts
  5. +1
    -0
      src/config.ts
  6. +4
    -0
      src/git/remotes/azure-devops.ts
  7. +4
    -0
      src/git/remotes/bitbucket-server.ts
  8. +4
    -0
      src/git/remotes/bitbucket.ts
  9. +9
    -0
      src/git/remotes/custom.ts
  10. +4
    -0
      src/git/remotes/github.ts
  11. +4
    -0
      src/git/remotes/gitlab.ts
  12. +18
    -1
      src/git/remotes/provider.ts
  13. +22
    -6
      src/quickpicks/remoteProviderPicker.ts
  14. +35
    -16
      src/views/nodes/compareBranchNode.ts
  15. +29
    -14
      src/views/nodes/compareResultsNode.ts
  16. +11
    -1
      src/views/nodes/resultsCommitsNode.ts
  17. +2
    -1
      src/views/nodes/viewNode.ts

+ 50
- 13
package.json View File

@ -148,6 +148,8 @@
"onCommand:gitlens.copyRemoteBranchUrl", "onCommand:gitlens.copyRemoteBranchUrl",
"onCommand:gitlens.openCommitOnRemote", "onCommand:gitlens.openCommitOnRemote",
"onCommand:gitlens.copyRemoteCommitUrl", "onCommand:gitlens.copyRemoteCommitUrl",
"onCommand:gitlens.openComparisonOnRemote",
"onCommand:gitlens.copyRemoteComparisonUrl",
"onCommand:gitlens.openFileFromRemote", "onCommand:gitlens.openFileFromRemote",
"onCommand:gitlens.openFileOnRemote", "onCommand:gitlens.openFileOnRemote",
"onCommand:gitlens.copyRemoteFileUrlToClipboard", "onCommand:gitlens.copyRemoteFileUrlToClipboard",
@ -3099,6 +3101,21 @@
} }
}, },
{ {
"command": "gitlens.openComparisonOnRemote",
"title": "Open Comparison on Remote",
"category": "GitLens",
"icon": "$(globe)"
},
{
"command": "gitlens.copyRemoteComparisonUrl",
"title": "Copy Remote Comparison Url",
"category": "GitLens",
"icon": {
"dark": "images/dark/icon-copy-link.svg",
"light": "images/light/icon-copy-link.svg"
}
},
{
"command": "gitlens.openFileFromRemote", "command": "gitlens.openFileFromRemote",
"title": "Open File from Remote", "title": "Open File from Remote",
"category": "GitLens" "category": "GitLens"
@ -4718,6 +4735,14 @@
"when": "gitlens:activeFileStatus =~ /tracked/ && gitlens:activeFileStatus =~ /remotes/" "when": "gitlens:activeFileStatus =~ /tracked/ && gitlens:activeFileStatus =~ /remotes/"
}, },
{ {
"command": "gitlens.openComparisonOnRemote",
"when": "false"
},
{
"command": "gitlens.copyRemoteComparisonUrl",
"when": "false"
},
{
"command": "gitlens.openPullRequestOnRemote", "command": "gitlens.openPullRequestOnRemote",
"when": "false" "when": "false"
}, },
@ -7083,7 +7108,7 @@
}, },
{ {
"command": "gitlens.views.dismissNode", "command": "gitlens.views.dismissNode",
"when": "viewItem =~ /gitlens:(compare:picker|(compare|search):results\\b(?!.*?\\b\\+pinned\\b))\\b(?!:(commits|files))/",
"when": "viewItem =~ /gitlens:(compare:picker|(compare|search):results(?!:)\\b(?!.*?\\b\\+pinned\\b))\\b(?!:(commits|files))/",
"group": "inline@99" "group": "inline@99"
}, },
{ {
@ -7128,60 +7153,72 @@
}, },
{ {
"command": "gitlens.views.searchAndCompare.swapComparison", "command": "gitlens.views.searchAndCompare.swapComparison",
"when": "viewItem =~ /gitlens:compare:results\\b/",
"when": "viewItem =~ /gitlens:compare:results(?!:)\\b/",
"group": "inline@1" "group": "inline@1"
}, },
{ {
"command": "gitlens.views.refreshNode", "command": "gitlens.views.refreshNode",
"when": "viewItem =~ /gitlens:compare:(branch(?=.*?\\b\\+comparing\\b)|results)\\b/",
"when": "viewItem =~ /gitlens:compare:(branch(?=.*?\\b\\+comparing\\b)|results(?!:))\\b/",
"group": "inline@97" "group": "inline@97"
}, },
{ {
"command": "gitlens.views.refreshNode", "command": "gitlens.views.refreshNode",
"when": "viewItem =~ /gitlens:search:results\\b/",
"when": "viewItem =~ /gitlens:search:results(?!:)\\b/",
"group": "inline@97" "group": "inline@97"
}, },
{ {
"command": "gitlens.views.searchAndCompare.pin", "command": "gitlens.views.searchAndCompare.pin",
"when": "viewItem =~ /gitlens:(compare|search):results\\b(?!.*?\\b\\+pinned\\b)/",
"when": "viewItem =~ /gitlens:(compare|search):results(?!:)\\b(?!.*?\\b\\+pinned\\b)/",
"group": "inline@98" "group": "inline@98"
}, },
{ {
"command": "gitlens.views.searchAndCompare.unpin", "command": "gitlens.views.searchAndCompare.unpin",
"when": "viewItem =~ /gitlens:(compare|search):results\\b(?=.*?\\b\\+pinned\\b)/",
"when": "viewItem =~ /gitlens:(compare|search):results(?!:)\\b(?=.*?\\b\\+pinned\\b)/",
"group": "inline@98" "group": "inline@98"
}, },
{ {
"command": "gitlens.views.searchAndCompare.swapComparison", "command": "gitlens.views.searchAndCompare.swapComparison",
"when": "viewItem =~ /gitlens:compare:results\\b/",
"when": "viewItem =~ /gitlens:compare:results(?!:)\\b/",
"group": "1_gitlens_actions@2" "group": "1_gitlens_actions@2"
}, },
{ {
"command": "gitlens.views.openDirectoryDiff", "command": "gitlens.views.openDirectoryDiff",
"when": "viewItem =~ /gitlens:compare:results\\b/",
"when": "viewItem =~ /gitlens:compare:results(?!:)\\b/",
"group": "2_gitlens_quickopen@1" "group": "2_gitlens_quickopen@1"
}, },
{ {
"command": "gitlens.views.searchAndCompare.pin", "command": "gitlens.views.searchAndCompare.pin",
"when": "viewItem =~ /gitlens:(compare|search):results\\b(?!.*?\\b\\+pinned\\b)/",
"when": "viewItem =~ /gitlens:(compare|search):results(?!:)\\b(?!.*?\\b\\+pinned\\b)/",
"group": "8_gitlens_actions@1" "group": "8_gitlens_actions@1"
}, },
{ {
"command": "gitlens.views.searchAndCompare.unpin", "command": "gitlens.views.searchAndCompare.unpin",
"when": "viewItem =~ /gitlens:(compare|search):results\\b(?=.*?\\b\\+pinned\\b)/",
"when": "viewItem =~ /gitlens:(compare|search):results(?!:)\\b(?=.*?\\b\\+pinned\\b)/",
"group": "8_gitlens_actions@1" "group": "8_gitlens_actions@1"
}, },
{ {
"command": "gitlens.views.searchAndCompare.edit", "command": "gitlens.views.searchAndCompare.edit",
"when": "viewItem =~ /gitlens:search:results\\b/",
"when": "viewItem =~ /gitlens:search:results(?!:)\\b/",
"group": "inline@1" "group": "inline@1"
}, },
{ {
"command": "gitlens.views.searchAndCompare.edit", "command": "gitlens.views.searchAndCompare.edit",
"when": "viewItem =~ /gitlens:search:results\\b/",
"when": "viewItem =~ /gitlens:search:results(?!:)\\b/",
"group": "1_gitlens_actions@1" "group": "1_gitlens_actions@1"
}, },
{ {
"command": "gitlens.openComparisonOnRemote",
"when": "viewItem =~ /gitlens:compare:results:commits\\b/",
"group": "inline@99",
"alt": "gitlens.copyRemoteComparisonUrl"
},
{
"command": "gitlens.openComparisonOnRemote",
"when": "viewItem =~ /gitlens:compare:results:commits\\b/",
"group": "3_gitlens_explore@0",
"alt": "gitlens.copyRemoteComparisonUrl"
},
{
"command": "gitlens.stashSave", "command": "gitlens.stashSave",
"when": "!gitlens:readonly && viewItem =~ /^gitlens:(stashes|status:files)$/", "when": "!gitlens:readonly && viewItem =~ /^gitlens:(stashes|status:files)$/",
"group": "inline@98" "group": "inline@98"
@ -7273,7 +7310,7 @@
}, },
{ {
"command": "gitlens.views.dismissNode", "command": "gitlens.views.dismissNode",
"when": "viewItem =~ /gitlens:(compare:picker:ref|(compare|search):results\\b(?!.*?\\b\\+pinned\\b))\\b(?!:(commits|files))/",
"when": "viewItem =~ /gitlens:(compare:picker:ref|(compare|search):results(?!:)\\b(?!.*?\\b\\+pinned\\b))\\b(?!:(commits|files))/",
"group": "8_gitlens_actions@98" "group": "8_gitlens_actions@98"
}, },
{ {

+ 1
- 0
src/commands.ts View File

@ -24,6 +24,7 @@ export * from './commands/openBranchesOnRemote';
export * from './commands/openBranchOnRemote'; export * from './commands/openBranchOnRemote';
export * from './commands/openChangedFiles'; export * from './commands/openChangedFiles';
export * from './commands/openCommitOnRemote'; export * from './commands/openCommitOnRemote';
export * from './commands/openComparisonOnRemote';
export * from './commands/openFileFromRemote'; export * from './commands/openFileFromRemote';
export * from './commands/openFileOnRemote'; export * from './commands/openFileOnRemote';
export * from './commands/openFileAtRevision'; export * from './commands/openFileAtRevision';

+ 2
- 0
src/commands/common.ts View File

@ -38,6 +38,7 @@ export enum Commands {
CopyRemoteBranchesUrl = 'gitlens.copyRemoteBranchesUrl', CopyRemoteBranchesUrl = 'gitlens.copyRemoteBranchesUrl',
CopyRemoteBranchUrl = 'gitlens.copyRemoteBranchUrl', CopyRemoteBranchUrl = 'gitlens.copyRemoteBranchUrl',
CopyRemoteCommitUrl = 'gitlens.copyRemoteCommitUrl', CopyRemoteCommitUrl = 'gitlens.copyRemoteCommitUrl',
CopyRemoteComparisonUrl = 'gitlens.copyRemoteComparisonUrl',
CopyRemoteFileUrl = 'gitlens.copyRemoteFileUrlToClipboard', CopyRemoteFileUrl = 'gitlens.copyRemoteFileUrlToClipboard',
CopyRemotePullRequestUrl = 'gitlens.copyRemotePullRequestUrl', CopyRemotePullRequestUrl = 'gitlens.copyRemotePullRequestUrl',
CopyRemoteRepositoryUrl = 'gitlens.copyRemoteRepositoryUrl', CopyRemoteRepositoryUrl = 'gitlens.copyRemoteRepositoryUrl',
@ -69,6 +70,7 @@ export enum Commands {
OpenBranchesOnRemote = 'gitlens.openBranchesOnRemote', OpenBranchesOnRemote = 'gitlens.openBranchesOnRemote',
OpenBranchOnRemote = 'gitlens.openBranchOnRemote', OpenBranchOnRemote = 'gitlens.openBranchOnRemote',
OpenCommitOnRemote = 'gitlens.openCommitOnRemote', OpenCommitOnRemote = 'gitlens.openCommitOnRemote',
OpenComparisonOnRemote = 'gitlens.openComparisonOnRemote',
OpenFileFromRemote = 'gitlens.openFileFromRemote', OpenFileFromRemote = 'gitlens.openFileFromRemote',
OpenFileOnRemote = 'gitlens.openFileOnRemote', OpenFileOnRemote = 'gitlens.openFileOnRemote',
OpenFileAtRevision = 'gitlens.openFileRevision', OpenFileAtRevision = 'gitlens.openFileRevision',

+ 63
- 0
src/commands/openComparisonOnRemote.ts View File

@ -0,0 +1,63 @@
'use strict';
import { window } from 'vscode';
import { Command, command, CommandContext, Commands, executeCommand } from './common';
import { RemoteResourceType } from '../git/git';
import { Logger } from '../logger';
import { OpenOnRemoteCommandArgs } from './openOnRemote';
import { ResultsCommitsNode } from '../views/nodes';
export interface OpenComparisonOnRemoteCommandArgs {
clipboard?: boolean;
ref1?: string;
ref2?: string;
notation?: '..' | '...';
repoPath?: string;
}
@command()
export class OpenComparisonOnRemoteCommand extends Command {
constructor() {
super([Commands.OpenComparisonOnRemote, Commands.CopyRemoteComparisonUrl]);
}
protected preExecute(context: CommandContext, args?: OpenComparisonOnRemoteCommandArgs) {
if (context.type === 'viewItem') {
if (context.node instanceof ResultsCommitsNode) {
args = {
...args,
repoPath: context.node.repoPath,
ref1: context.node.ref1,
ref2: context.node.ref2,
};
}
}
if (context.command === Commands.CopyRemoteBranchesUrl) {
args = { ...args, clipboard: true };
}
return this.execute(args);
}
async execute(args?: OpenComparisonOnRemoteCommandArgs) {
if (args?.repoPath == null || args.ref1 == null || args.ref2 == null) return;
try {
void (await executeCommand<OpenOnRemoteCommandArgs>(Commands.OpenOnRemote, {
resource: {
type: RemoteResourceType.Comparison,
ref1: args.ref1,
ref2: args.ref2,
notation: args.notation,
},
repoPath: args.repoPath,
clipboard: args?.clipboard,
}));
} catch (ex) {
Logger.error(ex, 'OpenComparisonOnRemoteCommand');
void window.showErrorMessage(
'Unable to open comparison on remote provider. See output channel for more details',
);
}
}
}

+ 1
- 0
src/config.ts View File

@ -388,6 +388,7 @@ export interface RemotesUrlsConfig {
branches: string; branches: string;
branch: string; branch: string;
commit: string; commit: string;
comparison?: string;
file: string; file: string;
fileInBranch: string; fileInBranch: string;
fileInCommit: string; fileInCommit: string;

+ 4
- 0
src/git/remotes/azure-devops.ts View File

@ -115,6 +115,10 @@ export class AzureDevOpsRemote extends RemoteProvider {
return `${this.baseUrl}/commit/${sha}`; return `${this.baseUrl}/commit/${sha}`;
} }
protected getUrlForComparison(ref1: string, ref2: string, _notation: '..' | '...'): string {
return `${this.baseUrl}/branchCompare?baseVersion=GB${ref1}&targetVersion=GB${ref2}`;
}
protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string {
let line; let line;
if (range != null) { if (range != null) {

+ 4
- 0
src/git/remotes/bitbucket-server.ts View File

@ -122,6 +122,10 @@ export class BitbucketServerRemote extends RemoteProvider {
return `${this.baseUrl}/commits/${sha}`; return `${this.baseUrl}/commits/${sha}`;
} }
protected getUrlForComparison(ref1: string, ref2: string, _notation: '..' | '...'): string {
return `${this.baseUrl}/branches/compare/${ref1}%0D${ref2}`;
}
protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string {
let line; let line;
if (range != null) { if (range != null) {

+ 4
- 0
src/git/remotes/bitbucket.ts View File

@ -115,6 +115,10 @@ export class BitbucketRemote extends RemoteProvider {
return `${this.baseUrl}/commits/${sha}`; return `${this.baseUrl}/commits/${sha}`;
} }
protected getUrlForComparison(ref1: string, ref2: string, _notation: '..' | '...'): string {
return `${this.baseUrl}/branches/compare/${ref1}%0D${ref2}`;
}
protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string {
let line; let line;
if (range != null) { if (range != null) {

+ 9
- 0
src/git/remotes/custom.ts View File

@ -40,6 +40,15 @@ export class CustomRemote extends RemoteProvider {
return Strings.interpolate(this.urls.commit, this.getContext({ id: sha })); return Strings.interpolate(this.urls.commit, this.getContext({ id: sha }));
} }
protected getUrlForComparison(ref1: string, ref2: string, notation: '..' | '...'): string | undefined {
if (this.urls.comparison == null) return undefined;
return Strings.interpolate(
this.urls.comparison,
this.getContext({ ref1: ref1, ref2: ref2, notation: notation }),
);
}
protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string {
let line; let line;
if (range != null) { if (range != null) {

+ 4
- 0
src/git/remotes/github.ts View File

@ -135,6 +135,10 @@ export class GitHubRemote extends RemoteProviderWithApi {
return `${this.baseUrl}/commit/${sha}`; return `${this.baseUrl}/commit/${sha}`;
} }
protected getUrlForComparison(ref1: string, ref2: string, notation: '..' | '...'): string {
return `${this.baseUrl}/compare/${ref1}${notation}${ref2}`;
}
protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string {
let line; let line;
if (range != null) { if (range != null) {

+ 4
- 0
src/git/remotes/gitlab.ts View File

@ -110,6 +110,10 @@ export class GitLabRemote extends RemoteProvider {
return `${this.baseUrl}/commit/${sha}`; return `${this.baseUrl}/commit/${sha}`;
} }
protected getUrlForComparison(ref1: string, ref2: string, notation: '..' | '...'): string {
return `${this.baseUrl}/-/compare/${ref1}${notation}${ref2}`;
}
protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string {
let line; let line;
if (range != null) { if (range != null) {

+ 18
- 1
src/git/remotes/provider.ts View File

@ -24,6 +24,7 @@ export enum RemoteResourceType {
Branch = 'branch', Branch = 'branch',
Branches = 'branches', Branches = 'branches',
Commit = 'commit', Commit = 'commit',
Comparison = 'comparison',
File = 'file', File = 'file',
Repo = 'repo', Repo = 'repo',
Revision = 'revision', Revision = 'revision',
@ -42,6 +43,12 @@ export type RemoteResource =
sha: string; sha: string;
} }
| { | {
type: RemoteResourceType.Comparison;
ref1: string;
ref2: string;
notation?: '..' | '...';
}
| {
type: RemoteResourceType.File; type: RemoteResourceType.File;
branch?: string; branch?: string;
fileName: string; fileName: string;
@ -67,6 +74,8 @@ export function getNameFromRemoteResource(resource: RemoteResource) {
return 'Branches'; return 'Branches';
case RemoteResourceType.Commit: case RemoteResourceType.Commit:
return 'Commit'; return 'Commit';
case RemoteResourceType.Comparison:
return 'Comparison';
case RemoteResourceType.File: case RemoteResourceType.File:
return 'File'; return 'File';
case RemoteResourceType.Repo: case RemoteResourceType.Repo:
@ -121,7 +130,7 @@ export abstract class RemoteProvider {
return; return;
} }
Logger.error(ex, 'CopyRemoteUrlToClipboardCommand');
Logger.error(ex, 'CopyRemoteUrlCommand');
void Messages.showGenericErrorMessage('Unable to copy remote url'); void Messages.showGenericErrorMessage('Unable to copy remote url');
} }
} }
@ -148,6 +157,12 @@ export abstract class RemoteProvider {
return this.getUrlForBranches(); return this.getUrlForBranches();
case RemoteResourceType.Commit: case RemoteResourceType.Commit:
return this.getUrlForCommit(encodeURIComponent(resource.sha)); return this.getUrlForCommit(encodeURIComponent(resource.sha));
case RemoteResourceType.Comparison:
return this.getUrlForComparison?.(
encodeURIComponent(resource.ref1),
encodeURIComponent(resource.ref2),
resource.notation ?? '...',
);
case RemoteResourceType.File: case RemoteResourceType.File:
return this.getUrlForFile( return this.getUrlForFile(
encodeURIComponent(resource.fileName), encodeURIComponent(resource.fileName),
@ -189,6 +204,8 @@ export abstract class RemoteProvider {
protected abstract getUrlForCommit(sha: string): string; protected abstract getUrlForCommit(sha: string): string;
protected getUrlForComparison?(ref1: string, ref2: string, notation: '..' | '...'): string | undefined;
protected abstract getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string; protected abstract getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string;
protected getUrlForRepository(): string { protected getUrlForRepository(): string {

+ 22
- 6
src/quickpicks/remoteProviderPicker.ts View File

@ -2,7 +2,14 @@
import { Disposable, window } from 'vscode'; import { Disposable, window } from 'vscode';
import { Commands, OpenOnRemoteCommandArgs } from '../commands'; import { Commands, OpenOnRemoteCommandArgs } from '../commands';
import { GlyphChars } from '../constants'; import { GlyphChars } from '../constants';
import { getNameFromRemoteResource, GitRemote, RemoteProvider, RemoteResource } from '../git/git';
import {
getNameFromRemoteResource,
GitBranch,
GitRemote,
RemoteProvider,
RemoteResource,
RemoteResourceType,
} from '../git/git';
import { Keys } from '../keyboard'; import { Keys } from '../keyboard';
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from '../quickpicks'; import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from '../quickpicks';
@ -19,9 +26,18 @@ export class CopyOrOpenRemoteCommandQuickPickItem extends CommandQuickPickItem {
} }
async execute(): Promise<void> { async execute(): Promise<void> {
void (await (this.clipboard
? this.remote.provider.copy(this.resource)
: this.remote.provider.open(this.resource)));
let resource = this.resource;
if (resource.type === RemoteResourceType.Comparison) {
if (GitBranch.getRemote(resource.ref1) === this.remote.name) {
resource = { ...resource, ref1: GitBranch.getNameWithoutRemote(resource.ref1) };
}
if (GitBranch.getRemote(resource.ref2) === this.remote.name) {
resource = { ...resource, ref2: GitBranch.getNameWithoutRemote(resource.ref2) };
}
}
void (await (this.clipboard ? this.remote.provider.copy(resource) : this.remote.provider.open(resource)));
} }
} }
@ -37,7 +53,7 @@ export class CopyRemoteResourceCommandQuickPickItem extends CommandQuickPickItem
`$(clippy) Copy ${providers?.length ? providers[0].name : 'Remote'} ${getNameFromRemoteResource( `$(clippy) Copy ${providers?.length ? providers[0].name : 'Remote'} ${getNameFromRemoteResource(
resource, resource,
)} Url${providers?.length === 1 ? '' : GlyphChars.Ellipsis}`, )} Url${providers?.length === 1 ? '' : GlyphChars.Ellipsis}`,
Commands.OpenInRemote,
Commands.OpenOnRemote,
[commandArgs], [commandArgs],
); );
} }
@ -62,7 +78,7 @@ export class OpenRemoteResourceCommandQuickPickItem extends CommandQuickPickItem
? providers[0].name ? providers[0].name
: `${providers?.length ? providers[0].name : 'Remote'}${GlyphChars.Ellipsis}` : `${providers?.length ? providers[0].name : 'Remote'}${GlyphChars.Ellipsis}`
}`, }`,
Commands.OpenInRemote,
Commands.OpenOnRemote,
[commandArgs], [commandArgs],
); );
} }

+ 35
- 16
src/views/nodes/compareBranchNode.ts View File

@ -46,16 +46,39 @@ export class CompareBranchNode extends ViewNode
} }
} }
get ahead(): { readonly ref1: string; readonly ref2: string } {
return {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
ref1: this._compareWith?.ref || 'HEAD',
ref2: this.branch.ref,
};
}
get behind(): { readonly ref1: string; readonly ref2: string } {
return {
ref1: this.branch.ref,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
ref2: this._compareWith?.ref || 'HEAD',
};
}
get id(): string { get id(): string {
return CompareBranchNode.getId(this.branch.repoPath, this.branch.name); return CompareBranchNode.getId(this.branch.repoPath, this.branch.name);
} }
get repoPath(): string {
return this.branch.repoPath;
}
async getChildren(): Promise<ViewNode[]> { async getChildren(): Promise<ViewNode[]> {
if (this._compareWith == null) return []; if (this._compareWith == null) return [];
if (this._children == null) { if (this._children == null) {
const aheadBehind = await Container.git.getAheadBehindCommitCount(this.branch.repoPath, [
GitRevision.createRange(this.branch.ref, this._compareWith.ref || 'HEAD', '...'),
const ahead = this.ahead;
const behind = this.behind;
const aheadBehindCounts = await Container.git.getAheadBehindCommitCount(this.branch.repoPath, [
GitRevision.createRange(behind.ref1, behind.ref2, '...'),
]); ]);
this._children = [ this._children = [
@ -65,18 +88,17 @@ export class CompareBranchNode extends ViewNode
this.uri.repoPath!, this.uri.repoPath!,
'Behind', 'Behind',
{ {
query: this.getCommitsQuery(
GitRevision.createRange(this.branch.ref, this._compareWith.ref || 'HEAD', '..'),
),
query: this.getCommitsQuery(GitRevision.createRange(behind.ref1, behind.ref2, '..')),
comparison: behind,
files: { files: {
ref1: this.compareWithWorkingTree ? '' : this.branch.ref,
ref2: this._compareWith.ref || 'HEAD',
ref1: this.compareWithWorkingTree ? '' : behind.ref1,
ref2: behind.ref2,
query: this.getBehindFilesQuery.bind(this), query: this.getBehindFilesQuery.bind(this),
}, },
}, },
{ {
id: 'behind', id: 'behind',
description: Strings.pluralize('commit', aheadBehind?.behind ?? 0),
description: Strings.pluralize('commit', aheadBehindCounts?.behind ?? 0),
expand: false, expand: false,
}, },
), ),
@ -87,21 +109,18 @@ export class CompareBranchNode extends ViewNode
'Ahead', 'Ahead',
{ {
query: this.getCommitsQuery( query: this.getCommitsQuery(
GitRevision.createRange(
this._compareWith.ref || 'HEAD',
this.compareWithWorkingTree ? '' : this.branch.ref,
'..',
),
GitRevision.createRange(ahead.ref1, this.compareWithWorkingTree ? '' : ahead.ref2, '..'),
), ),
comparison: ahead,
files: { files: {
ref1: this._compareWith.ref || 'HEAD',
ref2: this.compareWithWorkingTree ? '' : this.branch.ref,
ref1: ahead.ref1,
ref2: this.compareWithWorkingTree ? '' : ahead.ref2,
query: this.getAheadFilesQuery.bind(this), query: this.getAheadFilesQuery.bind(this),
}, },
}, },
{ {
id: 'ahead', id: 'ahead',
description: Strings.pluralize('commit', aheadBehind?.ahead ?? 0),
description: Strings.pluralize('commit', aheadBehindCounts?.ahead ?? 0),
expand: false, expand: false,
}, },
), ),

+ 29
- 14
src/views/nodes/compareResultsNode.ts View File

@ -38,6 +38,20 @@ export class CompareResultsNode extends ViewNode {
this._instanceId = instanceId++; this._instanceId = instanceId++;
} }
get ahead(): { readonly ref1: string; readonly ref2: string } {
return {
ref1: this._compareWith.ref || 'HEAD',
ref2: this._ref.ref,
};
}
get behind(): { readonly ref1: string; readonly ref2: string } {
return {
ref1: this._ref.ref,
ref2: this._compareWith.ref || 'HEAD',
};
}
get id(): string { get id(): string {
return CompareResultsNode.getId(this.repoPath, this._ref.ref, this._compareWith.ref, this._instanceId); return CompareResultsNode.getId(this.repoPath, this._ref.ref, this._compareWith.ref, this._instanceId);
} }
@ -57,8 +71,11 @@ export class CompareResultsNode extends ViewNode {
async getChildren(): Promise<ViewNode[]> { async getChildren(): Promise<ViewNode[]> {
if (this._children == null) { if (this._children == null) {
const aheadBehind = await Container.git.getAheadBehindCommitCount(this.repoPath, [
GitRevision.createRange(this._ref.ref || 'HEAD', this._compareWith.ref || 'HEAD', '...'),
const ahead = this.ahead;
const behind = this.behind;
const aheadBehindCounts = await Container.git.getAheadBehindCommitCount(this.repoPath, [
GitRevision.createRange(behind.ref1 || 'HEAD', behind.ref2, '...'),
]); ]);
this._children = [ this._children = [
@ -68,18 +85,17 @@ export class CompareResultsNode extends ViewNode {
this.uri.repoPath!, this.uri.repoPath!,
'Behind', 'Behind',
{ {
query: this.getCommitsQuery(
GitRevision.createRange(this._ref.ref, this._compareWith?.ref ?? 'HEAD', '..'),
),
query: this.getCommitsQuery(GitRevision.createRange(behind.ref1, behind.ref2, '..')),
comparison: behind,
files: { files: {
ref1: this._ref.ref,
ref2: this._compareWith.ref || 'HEAD',
ref1: behind.ref1,
ref2: behind.ref2,
query: this.getBehindFilesQuery.bind(this), query: this.getBehindFilesQuery.bind(this),
}, },
}, },
{ {
id: 'behind', id: 'behind',
description: Strings.pluralize('commit', aheadBehind?.behind ?? 0),
description: Strings.pluralize('commit', aheadBehindCounts?.behind ?? 0),
expand: false, expand: false,
}, },
), ),
@ -89,18 +105,17 @@ export class CompareResultsNode extends ViewNode {
this.uri.repoPath!, this.uri.repoPath!,
'Ahead', 'Ahead',
{ {
query: this.getCommitsQuery(
GitRevision.createRange(this._compareWith?.ref ?? 'HEAD', this._ref.ref, '..'),
),
query: this.getCommitsQuery(GitRevision.createRange(ahead.ref1, ahead.ref2, '..')),
comparison: ahead,
files: { files: {
ref1: this._compareWith.ref || 'HEAD',
ref2: this._ref.ref,
ref1: ahead.ref1,
ref2: ahead.ref2,
query: this.getAheadFilesQuery.bind(this), query: this.getAheadFilesQuery.bind(this),
}, },
}, },
{ {
id: 'ahead', id: 'ahead',
description: Strings.pluralize('commit', aheadBehind?.ahead ?? 0),
description: Strings.pluralize('commit', aheadBehindCounts?.ahead ?? 0),
expand: false, expand: false,
}, },
), ),

+ 11
- 1
src/views/nodes/resultsCommitsNode.ts View File

@ -28,6 +28,7 @@ export class ResultsCommitsNode
private _label: string, private _label: string,
private readonly _results: { private readonly _results: {
query: (limit: number | undefined) => Promise<CommitsQueryResults>; query: (limit: number | undefined) => Promise<CommitsQueryResults>;
comparison?: { ref1: string; ref2: string };
deferred?: boolean; deferred?: boolean;
files?: { files?: {
ref1: string; ref1: string;
@ -50,6 +51,14 @@ export class ResultsCommitsNode
this._options = { expand: true, ..._options }; this._options = { expand: true, ..._options };
} }
get ref1(): string | undefined {
return this._results.comparison?.ref1;
}
get ref2(): string | undefined {
return this._results.comparison?.ref2;
}
get id(): string { get id(): string {
return `${this.parent!.id}:results:commits${this._options.id ? `:${this._options.id}` : ''}`; return `${this.parent!.id}:results:commits${this._options.id ? `:${this._options.id}` : ''}`;
} }
@ -120,7 +129,8 @@ export class ResultsCommitsNode
} }
const item = new TreeItem(label ?? this._label, state); const item = new TreeItem(label ?? this._label, state);
item.contextValue = ContextValues.ResultsCommits;
item.contextValue =
this._results.comparison != null ? ContextValues.CompareResultsCommits : ContextValues.SearchResultsCommits;
item.description = this._options.description; item.description = this._options.description;
item.id = this.id; item.id = this.id;

+ 2
- 1
src/views/nodes/viewNode.ts View File

@ -21,6 +21,7 @@ export enum ContextValues {
ComparePicker = 'gitlens:compare:picker', ComparePicker = 'gitlens:compare:picker',
ComparePickerWithRef = 'gitlens:compare:picker:ref', ComparePickerWithRef = 'gitlens:compare:picker:ref',
CompareResults = 'gitlens:compare:results', CompareResults = 'gitlens:compare:results',
CompareResultsCommits = 'gitlens:compare:results:commits',
Contributor = 'gitlens:contributor', Contributor = 'gitlens:contributor',
Contributors = 'gitlens:contributors', Contributors = 'gitlens:contributors',
DateMarker = 'gitlens:date-marker', DateMarker = 'gitlens:date-marker',
@ -38,11 +39,11 @@ export enum ContextValues {
Repositories = 'gitlens:repositories', Repositories = 'gitlens:repositories',
Repository = 'gitlens:repository', Repository = 'gitlens:repository',
RepositoryFolder = 'gitlens:repo-folder', RepositoryFolder = 'gitlens:repo-folder',
ResultsCommits = 'gitlens:results:commits',
ResultsFile = 'gitlens:file:results', ResultsFile = 'gitlens:file:results',
ResultsFiles = 'gitlens:results:files', ResultsFiles = 'gitlens:results:files',
SearchAndCompare = 'gitlens:searchAndCompare', SearchAndCompare = 'gitlens:searchAndCompare',
SearchResults = 'gitlens:search:results', SearchResults = 'gitlens:search:results',
SearchResultsCommits = 'gitlens:search:results:commits',
Stash = 'gitlens:stash', Stash = 'gitlens:stash',
StashFile = 'gitlens:file:stash', StashFile = 'gitlens:file:stash',
Stashes = 'gitlens:stashes', Stashes = 'gitlens:stashes',

Loading…
Cancel
Save