瀏覽代碼

Changes compare nodes to ahead/behind structure

main
Eric Amodio 4 年之前
父節點
當前提交
2d0d2e64ec
共有 6 個檔案被更改,包括 163 行新增211 行删除
  1. +0
    -66
      package.json
  2. +2
    -2
      src/constants.ts
  3. +1
    -1
      src/views/compareView.ts
  4. +43
    -41
      src/views/nodes/compareBranchNode.ts
  5. +117
    -87
      src/views/nodes/compareResultsNode.ts
  6. +0
    -14
      src/views/viewCommands.ts

+ 0
- 66
package.json 查看文件

@ -3502,24 +3502,6 @@
}
},
{
"command": "gitlens.views.setComparisonToTwoDot",
"title": "Toggle Comparison Type (Two-dot)",
"category": "GitLens",
"icon": {
"dark": "images/dark/icon-compare-twodot.svg",
"light": "images/light/icon-compare-twodot.svg"
}
},
{
"command": "gitlens.views.setComparisonToThreeDot",
"title": "Toggle Comparison Type (Three-dot)",
"category": "GitLens",
"icon": {
"dark": "images/dark/icon-compare-threedot.svg",
"light": "images/light/icon-compare-threedot.svg"
}
},
{
"command": "gitlens.views.cherryPick",
"title": "Cherry Pick Commit...",
"category": "GitLens"
@ -4919,14 +4901,6 @@
"when": "false"
},
{
"command": "gitlens.views.setComparisonToTwoDot",
"when": "false"
},
{
"command": "gitlens.views.setComparisonToThreeDot",
"when": "false"
},
{
"command": "gitlens.views.createBranch",
"when": "false"
},
@ -7188,16 +7162,6 @@
"group": "inline@99"
},
{
"command": "gitlens.views.setComparisonToTwoDot",
"when": "viewItem =~ /gitlens:compare:branch\\b(?=.*?\\b\\+comparing\\b)(?=.*?\\b\\+threedot\\b)/",
"group": "inline@1"
},
{
"command": "gitlens.views.setComparisonToThreeDot",
"when": "viewItem =~ /gitlens:compare:branch\\b(?=.*?\\b\\+comparing\\b)(?=.*?\\b\\+twodot\\b)/",
"group": "inline@1"
},
{
"command": "gitlens.views.clearNode",
"when": "viewItem =~ /gitlens:compare:branch\\b(?=.*?\\b\\+comparing\\b)/",
"group": "inline@99"
@ -7213,16 +7177,6 @@
"group": "inline@2"
},
{
"command": "gitlens.views.setComparisonToTwoDot",
"when": "viewItem =~ /gitlens:compare:branch\\b(?=.*?\\b\\+comparing\\b)(?=.*?\\b\\+threedot\\b)/",
"group": "1_gitlens@1"
},
{
"command": "gitlens.views.setComparisonToThreeDot",
"when": "viewItem =~ /gitlens:compare:branch\\b(?=.*?\\b\\+comparing\\b)(?=.*?\\b\\+twodot\\b)/",
"group": "1_gitlens@1"
},
{
"command": "gitlens.views.setBranchComparisonToWorking",
"when": "viewItem =~ /gitlens:compare:branch\\b(?=.*?\\b\\+comparing\\b)(?=.*?\\b\\+current\\b)(?=.*?\\b\\+branch\\b)/",
"group": "1_gitlens@2"
@ -7248,16 +7202,6 @@
"group": "9_gitlens@1"
},
{
"command": "gitlens.views.setComparisonToTwoDot",
"when": "viewItem =~ /gitlens:compare:results\\b(?=.*?\\b\\+threedot\\b)/",
"group": "inline@2"
},
{
"command": "gitlens.views.setComparisonToThreeDot",
"when": "viewItem =~ /gitlens:compare:results\\b(?=.*?\\b\\+twodot\\b)/",
"group": "inline@2"
},
{
"command": "gitlens.views.compare.swapComparison",
"when": "viewItem =~ /gitlens:compare:results\\b/",
"group": "inline@3"
@ -7283,16 +7227,6 @@
"group": "2_gitlens_quickopen@1"
},
{
"command": "gitlens.views.setComparisonToTwoDot",
"when": "viewItem =~ /gitlens:compare:results\\b(?=.*?\\b\\+threedot\\b)/",
"group": "1_gitlens_actions@1"
},
{
"command": "gitlens.views.setComparisonToThreeDot",
"when": "viewItem =~ /gitlens:compare:results\\b(?=.*?\\b\\+twodot\\b)/",
"group": "1_gitlens_actions@1"
},
{
"command": "gitlens.views.compare.swapComparison",
"when": "viewItem =~ /gitlens:compare:results\\b/",
"group": "1_gitlens_actions@2"

+ 2
- 2
src/constants.ts 查看文件

@ -149,7 +149,7 @@ export const ImageMimetypes: Record = {
export interface BranchComparison {
ref: string;
notation: '...' | '..' | undefined;
notation: '..' | '...' | undefined;
type: Exclude<ViewShowBranchComparison, false> | undefined;
}
@ -166,7 +166,7 @@ export interface PinnedComparison {
path: string;
ref1: NamedRef;
ref2: NamedRef;
notation: '...' | '..' | undefined;
notation: '..' | '...' | undefined;
}
export interface PinnedComparisons {

+ 1
- 1
src/views/compareView.ts 查看文件

@ -121,7 +121,7 @@ export class CompareView extends ViewBase {
const pinned = Container.context.workspaceState.get<PinnedComparisons>(WorkspaceState.PinnedComparisons);
if (pinned == null) return [];
return Object.values(pinned).map(p => new CompareResultsNode(this, p.path, p.ref1, p.ref2, true, p.notation));
return Object.values(pinned).map(p => new CompareResultsNode(this, p.path, p.ref1, p.ref2, true));
}
async updatePinnedComparison(id: string, pin?: PinnedComparison) {

+ 43
- 41
src/views/nodes/compareBranchNode.ts 查看文件

@ -55,7 +55,7 @@ export class CompareBranchNode extends ViewNode
if (this._children == null) {
const aheadBehind = await Container.git.getAheadBehindCommitCount(this.branch.repoPath, [
GitRevision.createRange(this.branch.ref || 'HEAD', this._compareWith.ref || 'HEAD', '...'),
GitRevision.createRange(this.branch.ref, this._compareWith.ref || 'HEAD', '...'),
]);
this._children = [
@ -63,9 +63,9 @@ export class CompareBranchNode extends ViewNode
this.view,
this,
this.uri.repoPath!,
'Behind', //`Behind (${aheadBehind?.behind})`,
'Behind',
this.getCommitsQuery(
GitRevision.createRange(this.branch.ref, this._compareWith?.ref ?? 'HEAD', '..'),
GitRevision.createRange(this.branch.ref, this._compareWith.ref || 'HEAD', '..'),
),
{
id: 'behind',
@ -83,10 +83,10 @@ export class CompareBranchNode extends ViewNode
this.view,
this,
this.uri.repoPath!,
'Ahead', //`Ahead (${aheadBehind?.ahead})`,
'Ahead',
this.getCommitsQuery(
GitRevision.createRange(
this._compareWith?.ref ?? 'HEAD',
this._compareWith.ref || 'HEAD',
this.compareWithWorkingTree ? '' : this.branch.ref,
'..',
),
@ -209,45 +209,11 @@ export class CompareBranchNode extends ViewNode
this.view.triggerNodeChange(this);
}
private getCommitsQuery(range: string): (limit: number | undefined) => Promise<CommitsQueryResults> {
const repoPath = this.uri.repoPath!;
return async (limit: number | undefined) => {
const log = await Container.git.getLog(repoPath, {
limit: limit,
ref: range,
});
const results: Mutable<Partial<CommitsQueryResults>> = {
log: log,
hasMore: log?.hasMore ?? true,
};
if (results.hasMore) {
results.more = async (limit: number | undefined) => {
results.log = (await results.log?.more?.(limit)) ?? results.log;
results.hasMore = results.log?.hasMore ?? true;
};
}
return results as CommitsQueryResults;
};
}
private async getBehindFilesQuery(): Promise<FilesQueryResults> {
const diff = await Container.git.getDiffStatus(
this.uri.repoPath!,
GitRevision.createRange(this.branch.ref, this._compareWith?.ref ?? 'HEAD', '...'),
);
return {
label: `${Strings.pluralize('file', diff !== undefined ? diff.length : 0, { zero: 'No' })} changed`,
files: diff,
};
}
private async getAheadFilesQuery(): Promise<FilesQueryResults> {
let files = await Container.git.getDiffStatus(
this.uri.repoPath!,
GitRevision.createRange(this._compareWith?.ref ?? 'HEAD', this.branch.ref, '...'),
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
GitRevision.createRange(this._compareWith?.ref || 'HEAD', this.branch.ref, '...'),
);
if (this.compareWithWorkingTree) {
@ -274,6 +240,42 @@ export class CompareBranchNode extends ViewNode
};
}
private async getBehindFilesQuery(): Promise<FilesQueryResults> {
const files = await Container.git.getDiffStatus(
this.uri.repoPath!,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
GitRevision.createRange(this.branch.ref, this._compareWith?.ref || 'HEAD', '...'),
);
return {
label: `${Strings.pluralize('file', files?.length ?? 0, { zero: 'No' })} changed`,
files: files,
};
}
private getCommitsQuery(range: string): (limit: number | undefined) => Promise<CommitsQueryResults> {
const repoPath = this.uri.repoPath!;
return async (limit: number | undefined) => {
const log = await Container.git.getLog(repoPath, {
limit: limit,
ref: range,
});
const results: Mutable<Partial<CommitsQueryResults>> = {
log: log,
hasMore: log?.hasMore ?? true,
};
if (results.hasMore) {
results.more = async (limit: number | undefined) => {
results.log = (await results.log?.more?.(limit)) ?? results.log;
results.hasMore = results.log?.hasMore ?? true;
};
}
return results as CommitsQueryResults;
};
}
private async updateCompareWith(compareWith: BranchComparison | undefined) {
this._compareWith = compareWith;

+ 117
- 87
src/views/nodes/compareResultsNode.ts 查看文件

@ -7,7 +7,7 @@ import { GitUri } from '../../git/gitUri';
import { debug, gate, log, Strings } from '../../system';
import { CompareView } from '../compareView';
import { CommitsQueryResults, ResultsCommitsNode } from './resultsCommitsNode';
import { FilesQueryResults, ResultsFilesNode } from './resultsFilesNode';
import { FilesQueryResults } from './resultsFilesNode';
import { ContextValues, ViewNode } from './viewNode';
import { RepositoryNode } from './repositoryNode';
import { TreeViewNodeCollapsibleStateChangeEvent } from '../viewBase';
@ -30,7 +30,6 @@ export class CompareResultsNode extends ViewNode implements Disposa
private _ref: NamedRef,
private _compareWith: NamedRef,
private _pinned: boolean = false,
private _comparisonNotation?: '...' | '..',
) {
super(GitUri.fromRepoPath(repoPath), view);
this._instanceId = instanceId++;
@ -58,22 +57,52 @@ export class CompareResultsNode extends ViewNode implements Disposa
}
async getChildren(): Promise<ViewNode[]> {
if (this._children === undefined) {
const [ref1, ref2] = await this.getDiffRefs();
if (this._children == null) {
const aheadBehind = await Container.git.getAheadBehindCommitCount(this.repoPath, [
GitRevision.createRange(this._ref.ref || 'HEAD', this._compareWith.ref || 'HEAD', '...'),
]);
this._children = [
new ResultsCommitsNode(
this.view,
this,
this.uri.repoPath!,
'commits',
this.getCommitsQuery.bind(this),
'Behind',
this.getCommitsQuery(
GitRevision.createRange(this._ref.ref, this._compareWith?.ref ?? 'HEAD', '..'),
),
{
id: 'behind',
description: Strings.pluralize('commit', aheadBehind?.behind ?? 0),
expand: false,
includeRepoName: true,
files: {
ref1: this._ref.ref,
ref2: this._compareWith.ref || 'HEAD',
query: this.getBehindFilesQuery.bind(this),
},
},
),
new ResultsCommitsNode(
this.view,
this,
this.uri.repoPath!,
'Ahead',
this.getCommitsQuery(
GitRevision.createRange(this._compareWith?.ref ?? 'HEAD', this._ref.ref, '..'),
),
{
id: 'ahead',
description: Strings.pluralize('commit', aheadBehind?.ahead ?? 0),
expand: false,
includeRepoName: true,
files: {
ref1: this._compareWith.ref || 'HEAD',
ref2: this._ref.ref,
query: this.getAheadFilesQuery.bind(this),
},
},
),
new ResultsFilesNode(this.view, this, this.uri.repoPath!, ref1, ref2, this.getFilesQuery.bind(this)),
];
}
return this._children;
@ -95,13 +124,7 @@ export class CompareResultsNode extends ViewNode implements Disposa
}`,
this._collapsibleState ?? TreeItemCollapsibleState.Collapsed,
);
item.contextValue = `${ContextValues.CompareResults}+${
this.comparisonNotation === '..' ? 'twodot' : 'threedot'
}`;
if (this._pinned) {
item.contextValue += '+pinned';
}
item.contextValue = `${ContextValues.CompareResults}${this._pinned ? '+pinned' : ''}`;
item.description = description;
if (this._pinned) {
item.iconPath = {
@ -117,16 +140,17 @@ export class CompareResultsNode extends ViewNode implements Disposa
return !this._pinned;
}
// eslint-disable-next-line @typescript-eslint/require-await
@gate()
@debug()
async getDiffRefs(): Promise<[string, string]> {
if (this.comparisonNotation === '..') {
return [
(await Container.git.getMergeBase(this.repoPath, this._compareWith.ref, this._ref.ref)) ??
this._compareWith.ref,
this._ref.ref,
];
}
// if (this.comparisonNotation === '..') {
// return [
// (await Container.git.getMergeBase(this.repoPath, this._compareWith.ref, this._ref.ref)) ??
// this._compareWith.ref,
// this._ref.ref,
// ];
// }
return [this._compareWith.ref, this._ref.ref];
}
@ -139,7 +163,7 @@ export class CompareResultsNode extends ViewNode implements Disposa
path: this.repoPath,
ref1: this._ref,
ref2: this._compareWith,
notation: this._comparisonNotation,
notation: undefined,
});
this._pinned = true;
@ -155,23 +179,6 @@ export class CompareResultsNode extends ViewNode implements Disposa
}
@log()
async setComparisonNotation(comparisonNotation: '...' | '..') {
this._comparisonNotation = comparisonNotation;
if (this._pinned) {
await this.view.updatePinnedComparison(this.getPinnableId(), {
path: this.repoPath,
ref1: this._ref,
ref2: this._compareWith,
notation: this._comparisonNotation,
});
}
this._children = undefined;
this.view.triggerNodeChange(this);
}
@log()
async swap() {
// Save the current id so we can update it later
const currentId = this.getPinnableId();
@ -187,7 +194,7 @@ export class CompareResultsNode extends ViewNode implements Disposa
path: this.repoPath,
ref1: this._ref,
ref2: this._compareWith,
notation: this._comparisonNotation,
notation: undefined,
});
}
@ -205,66 +212,89 @@ export class CompareResultsNode extends ViewNode implements Disposa
void this.triggerChange();
}
private get comparisonNotation() {
return this._comparisonNotation ?? (Container.config.advanced.useSymmetricDifferenceNotation ? '...' : '..');
}
private get diffComparisonNotation() {
// In git diff the range syntax doesn't mean the same thing as with git log -- since git diff is about comparing endpoints not ranges
// see https://git-scm.com/docs/git-diff#Documentation/git-diff.txt-emgitdiffemltoptionsgtltcommitgtltcommitgt--ltpathgt82308203
// So inverting the range syntax should be about equivalent for the behavior we want
return this.comparisonNotation === '...' ? '..' : '...';
}
private async getCommitsQuery(limit: number | undefined): Promise<CommitsQueryResults> {
const log = await Container.git.getLog(this.uri.repoPath!, {
limit: limit,
ref: `${this._compareWith.ref || 'HEAD'}${this.comparisonNotation}${this._ref.ref || 'HEAD'}`,
});
private async getAheadFilesQuery(): Promise<FilesQueryResults> {
let files = await Container.git.getDiffStatus(
this.repoPath,
GitRevision.createRange(this._compareWith?.ref || 'HEAD', this._ref.ref || 'HEAD', '...'),
);
const count = log?.count ?? 0;
const results: Mutable<Partial<CommitsQueryResults>> = {
label: Strings.pluralize('commit', count, {
number: log?.hasMore ?? false ? `${count}+` : undefined,
zero: 'No',
}),
log: log,
hasMore: log?.hasMore ?? true,
};
if (results.hasMore) {
results.more = async (limit: number | undefined) => {
results.log = (await results.log?.more?.(limit)) ?? results.log;
const count = results.log?.count ?? 0;
results.label = Strings.pluralize('commit', count, {
number: results.log?.hasMore ?? false ? `${count}+` : undefined,
zero: 'No',
});
results.hasMore = results.log?.hasMore ?? true;
};
if (this._ref.ref === '') {
const workingFiles = await Container.git.getDiffStatus(this.repoPath, 'HEAD');
if (workingFiles != null) {
if (files != null) {
for (const wf of workingFiles) {
const index = files.findIndex(f => f.fileName === wf.fileName);
if (index !== -1) {
files.splice(index, 1, wf);
} else {
files.push(wf);
}
}
} else {
files = workingFiles;
}
}
}
return results as CommitsQueryResults;
return {
label: `${Strings.pluralize('file', files?.length ?? 0, { zero: 'No' })} changed`,
files: files,
};
}
private async getFilesQuery(): Promise<FilesQueryResults> {
let comparison;
private async getBehindFilesQuery(): Promise<FilesQueryResults> {
let files = await Container.git.getDiffStatus(
this.repoPath,
GitRevision.createRange(this._ref.ref || 'HEAD', this._compareWith.ref || 'HEAD', '...'),
);
if (this._compareWith.ref === '') {
comparison = this._ref.ref;
} else if (this._ref.ref === '') {
comparison = this._compareWith.ref;
} else {
comparison = `${this._compareWith.ref}${this.diffComparisonNotation}${this._ref.ref}`;
const workingFiles = await Container.git.getDiffStatus(this.repoPath, 'HEAD');
if (workingFiles != null) {
if (files != null) {
for (const wf of workingFiles) {
const index = files.findIndex(f => f.fileName === wf.fileName);
if (index !== -1) {
files.splice(index, 1, wf);
} else {
files.push(wf);
}
}
} else {
files = workingFiles;
}
}
}
const files = await Container.git.getDiffStatus(this.uri.repoPath!, comparison);
return {
label: `${Strings.pluralize('file', files !== undefined ? files.length : 0, { zero: 'No' })} changed`,
label: `${Strings.pluralize('file', files?.length ?? 0, { zero: 'No' })} changed`,
files: files,
};
}
private getCommitsQuery(range: string): (limit: number | undefined) => Promise<CommitsQueryResults> {
const repoPath = this.repoPath;
return async (limit: number | undefined) => {
const log = await Container.git.getLog(repoPath, {
limit: limit,
ref: range,
});
const results: Mutable<Partial<CommitsQueryResults>> = {
log: log,
hasMore: log?.hasMore ?? true,
};
if (results.hasMore) {
results.more = async (limit: number | undefined) => {
results.log = (await results.log?.more?.(limit)) ?? results.log;
results.hasMore = results.log?.hasMore ?? true;
};
}
return results as CommitsQueryResults;
};
}
private getPinnableId() {
return Strings.sha1(`${this.repoPath}|${this._ref.ref}|${this._compareWith.ref}`);
}

+ 0
- 14
src/views/viewCommands.ts 查看文件

@ -22,7 +22,6 @@ import {
CommitFileNode,
CommitNode,
CompareBranchNode,
CompareResultsNode,
ContributorNode,
ContributorsNode,
FileHistoryNode,
@ -169,12 +168,6 @@ export class ViewCommands {
commands.registerCommand('gitlens.views.selectFileForCompare', this.selectFileForCompare, this);
commands.registerCommand('gitlens.views.compareWithWorking', this.compareWithWorking, this);
commands.registerCommand('gitlens.views.setComparisonToTwoDot', n => this.setComparisonNotation(n, '..'), this);
commands.registerCommand(
'gitlens.views.setComparisonToThreeDot',
n => this.setComparisonNotation(n, '...'),
this,
);
commands.registerCommand(
'gitlens.views.setBranchComparisonToWorking',
n => this.setBranchComparison(n, ViewShowBranchComparison.Working),
@ -494,13 +487,6 @@ export class ViewCommands {
}
@debug()
private setComparisonNotation(node: ViewNode, comparisonNotation: '...' | '..') {
if (!(node instanceof CompareResultsNode)) return Promise.resolve();
return node.setComparisonNotation(comparisonNotation);
}
@debug()
private setShowRelativeDateMarkers(enabled: boolean) {
return configuration.updateEffective('views', 'showRelativeDateMarkers', enabled);
}

Loading…
取消
儲存