From 2d0d2e64eca7cbfb72db82e694673ed83b414706 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Tue, 13 Oct 2020 04:04:22 -0400 Subject: [PATCH] Changes compare nodes to ahead/behind structure --- package.json | 66 ----------- src/constants.ts | 4 +- src/views/compareView.ts | 2 +- src/views/nodes/compareBranchNode.ts | 84 +++++++------- src/views/nodes/compareResultsNode.ts | 204 +++++++++++++++++++--------------- src/views/viewCommands.ts | 14 --- 6 files changed, 163 insertions(+), 211 deletions(-) diff --git a/package.json b/package.json index dfe54a1..e3a9f8e 100644 --- a/package.json +++ b/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" diff --git a/src/constants.ts b/src/constants.ts index 3184c65..b1efc2f 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -149,7 +149,7 @@ export const ImageMimetypes: Record = { export interface BranchComparison { ref: string; - notation: '...' | '..' | undefined; + notation: '..' | '...' | undefined; type: Exclude | undefined; } @@ -166,7 +166,7 @@ export interface PinnedComparison { path: string; ref1: NamedRef; ref2: NamedRef; - notation: '...' | '..' | undefined; + notation: '..' | '...' | undefined; } export interface PinnedComparisons { diff --git a/src/views/compareView.ts b/src/views/compareView.ts index 5c098a1..bc2c558 100644 --- a/src/views/compareView.ts +++ b/src/views/compareView.ts @@ -121,7 +121,7 @@ export class CompareView extends ViewBase { const pinned = Container.context.workspaceState.get(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) { diff --git a/src/views/nodes/compareBranchNode.ts b/src/views/nodes/compareBranchNode.ts index 51738c7..6283d87 100644 --- a/src/views/nodes/compareBranchNode.ts +++ b/src/views/nodes/compareBranchNode.ts @@ -55,7 +55,7 @@ export class CompareBranchNode extends ViewNode Promise { - const repoPath = this.uri.repoPath!; - return async (limit: number | undefined) => { - const log = await Container.git.getLog(repoPath, { - limit: limit, - ref: range, - }); - - const results: Mutable> = { - 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 { - 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 { 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 { + 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 { + const repoPath = this.uri.repoPath!; + return async (limit: number | undefined) => { + const log = await Container.git.getLog(repoPath, { + limit: limit, + ref: range, + }); + + const results: Mutable> = { + 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; diff --git a/src/views/nodes/compareResultsNode.ts b/src/views/nodes/compareResultsNode.ts index df0ccd7..95b591e 100644 --- a/src/views/nodes/compareResultsNode.ts +++ b/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 { - 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 { - 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 { + 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> = { - 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 { - let comparison; + private async getBehindFilesQuery(): Promise { + 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 { + const repoPath = this.repoPath; + return async (limit: number | undefined) => { + const log = await Container.git.getLog(repoPath, { + limit: limit, + ref: range, + }); + + const results: Mutable> = { + 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}`); } diff --git a/src/views/viewCommands.ts b/src/views/viewCommands.ts index 9b0d4d3..8368c27 100644 --- a/src/views/viewCommands.ts +++ b/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); }