From d2b87f98c604e590263b2bdf58748f4ab269dcba Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Thu, 2 May 2019 03:53:34 -0400 Subject: [PATCH] Fixes branch commit quickpick nav --- src/commands/showQuickCommitDetails.ts | 12 +- src/git/git.ts | 5 + src/git/gitService.ts | 75 +++++----- src/git/models/blameCommit.ts | 6 - src/git/models/commit.ts | 48 ++----- src/git/models/logCommit.ts | 19 +-- src/git/models/stashCommit.ts | 35 +---- src/git/parsers/logParser.ts | 2 +- src/quickpicks/commitFileQuickPick.ts | 10 +- src/quickpicks/commitQuickPick.ts | 244 +++++++++++++++------------------ src/system/iterable.ts | 4 +- 11 files changed, 179 insertions(+), 281 deletions(-) diff --git a/src/commands/showQuickCommitDetails.ts b/src/commands/showQuickCommitDetails.ts index c4ca9f8..34ba129 100644 --- a/src/commands/showQuickCommitDetails.ts +++ b/src/commands/showQuickCommitDetails.ts @@ -156,13 +156,11 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand { [args.commit.toGitUri(), args] ); - const pick = await CommitQuickPick.show( - args.commit as GitLogCommit, - uri, - args.goBackCommand, - currentCommand, - args.repoLog - ); + const pick = await new CommitQuickPick(repoPath).show(args.commit as GitLogCommit, uri, { + currentCommand: currentCommand, + goBackCommand: args.goBackCommand, + repoLog: args.repoLog + }); if (pick === undefined) return undefined; if (!(pick instanceof CommitWithFileStatusQuickPickItem)) return pick.execute(); diff --git a/src/git/git.ts b/src/git/git.ts index 57882e7..70184b2 100644 --- a/src/git/git.ts +++ b/src/git/git.ts @@ -204,6 +204,7 @@ export class Git { static deletedOrMissingSha = '0000000000000000000000000000000000000000-'; static shaLikeRegex = /(^[0-9a-f]{40}([\^@~:]\S*)?$)|(^[0]{40}(:|-)$)/; static shaRegex = /(^[0-9a-f]{40}$)|(^[0]{40}(:|-)$)/; + static shaParentRegex = /^[0-9a-f]{40}\^[0-3]?$/; static shaShortenRegex = /^(.*?)([\^@~:].*)?$/; static stagedUncommittedRegex = /^[0]{40}([\^@~]\S*)?:$/; static stagedUncommittedSha = '0000000000000000000000000000000000000000:'; @@ -242,6 +243,10 @@ export class Git { return Git.shaLikeRegex.test(ref); } + static isShaParent(ref: string) { + return Git.shaParentRegex.test(ref); + } + static isStagedUncommitted(ref: string | undefined): boolean { return ref ? Git.stagedUncommittedRegex.test(ref) : false; } diff --git a/src/git/gitService.ts b/src/git/gitService.ts index 9a5efbf..c1e89cb 100644 --- a/src/git/gitService.ts +++ b/src/git/gitService.ts @@ -139,6 +139,18 @@ export class GitService implements Disposable { this._disposable && this._disposable.dispose(); } + @log() + static async initialize(): Promise { + // Try to use the same git as the built-in vscode git extension + let gitPath; + const gitApi = await GitService.getBuiltInGitApi(); + if (gitApi !== undefined) { + gitPath = gitApi.git.path; + } + + await Git.setOrFindGitPath(gitPath || workspace.getConfiguration('git').get('path')); + } + get useCaching() { return Container.config.advanced.caching.enabled; } @@ -2386,23 +2398,17 @@ export class GitService implements Disposable { return Git.stash_push(repoPath, pathspecs, message); } - static getEncoding(repoPath: string, fileName: string): string; - static getEncoding(uri: Uri): string; - static getEncoding(repoPathOrUri: string | Uri, fileName?: string): string { - const uri = typeof repoPathOrUri === 'string' ? GitUri.resolveToUri(fileName!, repoPathOrUri) : repoPathOrUri; - return Git.getEncoding(workspace.getConfiguration('files', uri).get('encoding')); + static compareGitVersion(version: string) { + return Versions.compare(Versions.fromString(this.getGitVersion()), Versions.fromString(version)); } - @log() - static async initialize(): Promise { - // Try to use the same git as the built-in vscode git extension - let gitPath; - const gitApi = await GitService.getBuiltInGitApi(); - if (gitApi !== undefined) { - gitPath = gitApi.git.path; + static ensureGitVersion(version: string, feature: string): void { + const gitVersion = this.getGitVersion(); + if (Versions.compare(Versions.fromString(gitVersion), Versions.fromString(version)) === -1) { + throw new Error( + `${feature} requires a newer version of Git (>= ${version}) than is currently installed (${gitVersion}). Please install a more recent version of Git to use this GitLens feature.` + ); } - - await Git.setOrFindGitPath(gitPath || workspace.getConfiguration('git').get('path')); } @log() @@ -2420,25 +2426,19 @@ export class GitService implements Disposable { return undefined; } - static getGitPath(): string { - return Git.getGitPath(); - } - - static getGitVersion(): string { - return Git.getGitVersion(); - } - - static isShaLike(ref: string): boolean { - return Git.isShaLike(ref); + static getEncoding(repoPath: string, fileName: string): string; + static getEncoding(uri: Uri): string; + static getEncoding(repoPathOrUri: string | Uri, fileName?: string): string { + const uri = typeof repoPathOrUri === 'string' ? GitUri.resolveToUri(fileName!, repoPathOrUri) : repoPathOrUri; + return Git.getEncoding(workspace.getConfiguration('files', uri).get('encoding')); } - static isStagedUncommitted(ref: string | undefined): boolean { - return Git.isStagedUncommitted(ref); - } - - static isUncommitted(ref: string | undefined): boolean { - return Git.isUncommitted(ref); - } + static getGitPath = Git.getGitPath; + static getGitVersion = Git.getGitVersion; + static isShaLike = Git.isShaLike; + static isShaParent = Git.isShaParent; + static isStagedUncommitted = Git.isStagedUncommitted; + static isUncommitted = Git.isUncommitted; static shortenSha( ref: string | undefined, @@ -2453,17 +2453,4 @@ export class GitService implements Disposable { return Git.isShaLike(ref) || Git.isStagedUncommitted(ref) ? Git.shortenSha(ref, strings) : ref; } - - static compareGitVersion(version: string) { - return Versions.compare(Versions.fromString(this.getGitVersion()), Versions.fromString(version)); - } - - static ensureGitVersion(version: string, feature: string): void { - const gitVersion = this.getGitVersion(); - if (Versions.compare(Versions.fromString(gitVersion), Versions.fromString(version)) === -1) { - throw new Error( - `${feature} requires a newer version of Git (>= ${version}) than is currently installed (${gitVersion}). Please install a more recent version of Git to use this GitLens feature.` - ); - } - } } diff --git a/src/git/models/blameCommit.ts b/src/git/models/blameCommit.ts index 000eeb4..96d9218 100644 --- a/src/git/models/blameCommit.ts +++ b/src/git/models/blameCommit.ts @@ -32,12 +32,6 @@ export class GitBlameCommit extends GitCommit { ); } - get previousFileSha(): string { - if (this._resolvedPreviousFileSha !== undefined) return this._resolvedPreviousFileSha; - - return `${this.sha}^`; - } - with(changes: { sha?: string; fileName?: string; diff --git a/src/git/models/commit.ts b/src/git/models/commit.ts index 21ca01d..c02adb4 100644 --- a/src/git/models/commit.ts +++ b/src/git/models/commit.ts @@ -42,21 +42,8 @@ export const CommitFormatting = { }; export abstract class GitCommit { - readonly type: GitCommitType; - readonly originalFileName: string | undefined; - previousFileName: string | undefined; - - protected readonly _fileName: string; - protected _previousSha: string | undefined; - - private _authorDateFormatter: Dates.DateFormatter | undefined; - private _committerDateFormatter: Dates.DateFormatter | undefined; - private _isStagedUncommitted: boolean | undefined; - private _isUncommitted: boolean | undefined; - private _shortSha: string | undefined; - constructor( - type: GitCommitType, + public readonly type: GitCommitType, public readonly repoPath: string, public readonly sha: string, public readonly author: string, @@ -65,17 +52,14 @@ export abstract class GitCommit { public readonly committerDate: Date, public readonly message: string, fileName: string, - originalFileName?: string, - previousSha?: string, - previousFileName?: string + public readonly originalFileName: string | undefined, + public previousSha: string | undefined, + public previousFileName: string | undefined ) { - this.type = type; this._fileName = fileName || ''; - this.originalFileName = originalFileName; - this._previousSha = previousSha; - this.previousFileName = previousFileName; } + private readonly _fileName: string; get fileName() { // If we aren't a single-file commit, return an empty file name (makes it default to the repoPath) return this.isFile ? this._fileName : ''; @@ -91,6 +75,7 @@ export abstract class GitCommit { : this.formatDateFromNow(); } + private _shortSha: string | undefined; get shortSha() { if (this._shortSha === undefined) { this._shortSha = Git.shortenSha(this.sha); @@ -110,6 +95,7 @@ export abstract class GitCommit { return this.type === GitCommitType.Stash || this.type === GitCommitType.StashFile; } + private _isStagedUncommitted: boolean | undefined; get isStagedUncommitted(): boolean { if (this._isStagedUncommitted === undefined) { this._isStagedUncommitted = Git.isStagedUncommitted(this.sha); @@ -117,6 +103,7 @@ export abstract class GitCommit { return this._isStagedUncommitted; } + private _isUncommitted: boolean | undefined; get isUncommitted(): boolean { if (this._isUncommitted === undefined) { this._isUncommitted = Git.isUncommitted(this.sha); @@ -124,21 +111,8 @@ export abstract class GitCommit { return this._isUncommitted; } - abstract get previousFileSha(): string; - protected _resolvedPreviousFileSha: string | undefined; - - get previousFileShortSha(): string { - return Git.shortenSha(this.previousFileSha)!; - } - - get previousSha(): string | undefined { - return this._previousSha; - } - set previousSha(value: string | undefined) { - if (value === this._previousSha) return; - - this._previousSha = value; - this._resolvedPreviousFileSha = undefined; + get previousFileSha(): string { + return `${this.sha}^`; } get previousShortSha() { @@ -162,6 +136,7 @@ export abstract class GitCommit { return this._workingUriPromise; } + private _authorDateFormatter: Dates.DateFormatter | undefined; private get authorDateFormatter(): Dates.DateFormatter { if (this._authorDateFormatter === undefined) { this._authorDateFormatter = Dates.toFormatter(this.authorDate); @@ -169,6 +144,7 @@ export abstract class GitCommit { return this._authorDateFormatter; } + private _committerDateFormatter: Dates.DateFormatter | undefined; private get committerDateFormatter(): Dates.DateFormatter { if (this._committerDateFormatter === undefined) { this._committerDateFormatter = Dates.toFormatter(this.committerDate); diff --git a/src/git/models/logCommit.ts b/src/git/models/logCommit.ts index a25ac68..c44d076 100644 --- a/src/git/models/logCommit.ts +++ b/src/git/models/logCommit.ts @@ -2,7 +2,6 @@ import * as paths from 'path'; import { Uri } from 'vscode'; import { Strings } from '../../system'; -import { Git } from '../git'; import { GitUri } from '../gitUri'; import { GitCommit, GitCommitType } from './commit'; import { GitFile, GitFileStatus } from './file'; @@ -22,10 +21,10 @@ export class GitLogCommit extends GitCommit { message: string, fileName: string, public readonly files: GitFile[], - public readonly status: GitFileStatus | undefined, - originalFileName: string | undefined, - previousSha: string | undefined, - previousFileName: string | undefined, + public readonly status?: GitFileStatus | undefined, + originalFileName?: string | undefined, + previousSha?: string | undefined, + previousFileName?: string | undefined, public readonly parentShas?: string[] ) { super( @@ -39,7 +38,7 @@ export class GitLogCommit extends GitCommit { message, fileName, originalFileName, - previousSha, + previousSha || `${sha}^`, previousFileName ); } @@ -48,18 +47,12 @@ export class GitLogCommit extends GitCommit { return this.parentShas && this.parentShas.length > 1; } - get nextShortSha() { - return this.nextSha && Git.shortenSha(this.nextSha); - } - get nextUri(): Uri { return this.nextFileName ? GitUri.resolveToUri(this.nextFileName, this.repoPath) : this.uri; } get previousFileSha(): string { - if (this._resolvedPreviousFileSha !== undefined) return this._resolvedPreviousFileSha; - - return this.isFile && this.previousSha ? this.previousSha : `${this.sha}^`; + return this.isFile ? this.previousSha! : `${this.sha}^`; } private _diff?: { diff --git a/src/git/models/stashCommit.ts b/src/git/models/stashCommit.ts index 19d2c1e..cf05085 100644 --- a/src/git/models/stashCommit.ts +++ b/src/git/models/stashCommit.ts @@ -1,6 +1,6 @@ 'use strict'; import { GitCommitType } from './commit'; -import { GitFile, GitFileStatus } from './file'; +import { GitFile } from './file'; import { GitLogCommit } from './logCommit'; export class GitStashCommit extends GitLogCommit { @@ -17,28 +17,9 @@ export class GitStashCommit extends GitLogCommit { committedDate: Date, message: string, fileName: string, - files: GitFile[], - status?: GitFileStatus | undefined, - originalFileName?: string | undefined, - previousSha?: string | undefined, - previousFileName?: string | undefined + files: GitFile[] ) { - super( - type, - repoPath, - sha, - 'You', - undefined, - authorDate, - committedDate, - message, - fileName, - files, - status, - originalFileName, - previousSha === undefined ? `${sha}^` : previousSha, - previousFileName - ); + super(type, repoPath, sha, 'You', undefined, authorDate, committedDate, message, fileName, files); } get shortSha() { @@ -52,10 +33,6 @@ export class GitStashCommit extends GitLogCommit { authorDate?: Date; committedDate?: Date; message?: string; - originalFileName?: string | null; - previousFileName?: string | null; - previousSha?: string | null; - status?: GitFileStatus; files?: GitFile[] | null; }): GitLogCommit { return new GitStashCommit( @@ -67,11 +44,7 @@ export class GitStashCommit extends GitLogCommit { changes.committedDate || this.committerDate, changes.message || this.message, changes.fileName || this.fileName, - this.getChangedValue(changes.files, this.files) || [], - changes.status || this.status, - this.getChangedValue(changes.originalFileName, this.originalFileName), - this.getChangedValue(changes.previousSha, this.previousSha), - this.getChangedValue(changes.previousFileName, this.previousFileName) + this.getChangedValue(changes.files, this.files) || [] ); } } diff --git a/src/git/parsers/logParser.ts b/src/git/parsers/logParser.ts index 4b285f4..3280110 100644 --- a/src/git/parsers/logParser.ts +++ b/src/git/parsers/logParser.ts @@ -354,7 +354,7 @@ export class GitLogParser { entry.files || [], entry.status, originalFileName, - `${entry.ref!}^`, + type === GitCommitType.Branch ? entry.parentShas![0] : undefined, undefined, entry.parentShas! ); diff --git a/src/quickpicks/commitFileQuickPick.ts b/src/quickpicks/commitFileQuickPick.ts index e84ccfe..6a4e140 100644 --- a/src/quickpicks/commitFileQuickPick.ts +++ b/src/quickpicks/commitFileQuickPick.ts @@ -14,7 +14,7 @@ import { } from '../commands'; import { GlyphChars } from '../constants'; import { Container } from '../container'; -import { GitLog, GitLogCommit, GitUri, RemoteResourceType } from '../git/gitService'; +import { GitLog, GitLogCommit, GitService, GitUri, RemoteResourceType } from '../git/gitService'; import { KeyCommand, KeyNoopCommand } from '../keyboard'; import { Strings } from '../system'; import { @@ -115,7 +115,7 @@ export class CommitFileQuickPick { items.push(new ApplyCommitFileChangesCommandQuickPickItem(commit)); } - if (commit.previousFileShortSha) { + if (commit.previousFileSha) { const commandArgs: DiffWithPreviousCommandArgs = { commit: commit }; @@ -123,9 +123,9 @@ export class CommitFileQuickPick { new CommandQuickPickItem( { label: '$(git-compare) Open Changes', - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${ - commit.previousFileShortSha - } ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}` + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${GitService.shortenSha( + commit.previousFileSha + )} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}` }, Commands.DiffWithPrevious, [commit.uri, commandArgs] diff --git a/src/quickpicks/commitQuickPick.ts b/src/quickpicks/commitQuickPick.ts index b809fb4..ff81115 100644 --- a/src/quickpicks/commitQuickPick.ts +++ b/src/quickpicks/commitQuickPick.ts @@ -18,11 +18,12 @@ import { GitFileStatus, GitLog, GitLogCommit, + GitService, GitStashCommit, GitUri, RemoteResourceType } from '../git/gitService'; -import { KeyCommand, KeyNoopCommand, Keys } from '../keyboard'; +import { KeyNoopCommand, Keys } from '../keyboard'; import { Arrays, Iterables, Strings } from '../system'; import { CommandQuickPickItem, @@ -106,14 +107,105 @@ export class OpenCommitFileRevisionsCommandQuickPickItem extends OpenFilesComman } } +export interface CommitQuickPickOptions { + currentCommand?: CommandQuickPickItem; + goBackCommand?: CommandQuickPickItem; + repoLog?: GitLog; +} + export class CommitQuickPick { - static async show( + constructor(public readonly repoPath: string | undefined) {} + + async show( commit: GitLogCommit, uri: Uri, - goBackCommand?: CommandQuickPickItem, - currentCommand?: CommandQuickPickItem, - repoLog?: GitLog + options: CommitQuickPickOptions = {} ): Promise { + let previousCommand: (() => Promise) | undefined = undefined; + let nextCommand: (() => Promise) | undefined = undefined; + if (!commit.isStash) { + previousCommand = async () => { + const previousRef = + commit.previousSha === undefined || GitService.isShaParent(commit.previousSha) + ? await Container.git.resolveReference(commit.repoPath, commit.previousSha || `${commit.sha}`) + : commit.previousSha; + if (previousRef === undefined) return KeyNoopCommand; + + const previousCommandArgs: ShowQuickCommitDetailsCommandArgs = { + repoLog: options.repoLog, + sha: previousRef, + goBackCommand: options.goBackCommand + }; + return new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [ + Uri.file(commit.repoPath), + previousCommandArgs + ]); + }; + + nextCommand = async () => { + let log = options.repoLog; + let c = log && log.commits.get(commit.sha); + + // If we can't find the commit or the next commit isn't available (since it isn't trustworthy) + if (c === undefined || c.nextSha === undefined) { + log = undefined; + c = undefined; + + // Try to find the next commit + const nextLog = await Container.git.getLog(commit.repoPath, { + maxCount: 1, + reverse: true, + ref: commit.sha + }); + + const next = nextLog && Iterables.first(nextLog.commits.values()); + if (next !== undefined && next.sha !== commit.sha) { + c = commit; + c.nextSha = next.sha; + } + } + + if (c === undefined || c.nextSha === undefined) return KeyNoopCommand; + + const nextCommandArgs: ShowQuickCommitDetailsCommandArgs = { + repoLog: log, + sha: c.nextSha, + goBackCommand: options.goBackCommand + }; + return new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [ + Uri.file(commit.repoPath), + nextCommandArgs + ]); + }; + } + + const scope = await Container.keyboard.beginScope({ + left: options.goBackCommand, + ',': previousCommand, + '.': nextCommand + }); + + const pick = await window.showQuickPick(this.getItems(commit, uri, options), { + matchOnDescription: true, + matchOnDetail: true, + placeHolder: `${commit.shortSha} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${ + commit.author ? `${commit.author}, ` : '' + }${commit.formattedDate} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getShortMessage()}`, + ignoreFocusOut: getQuickPickIgnoreFocusOut(), + onDidSelectItem: (item: QuickPickItem) => { + void scope.setKeyCommand('right', item); + if (typeof item.onDidSelect === 'function') { + item.onDidSelect(); + } + } + }); + + await scope.dispose(); + + return pick; + } + + private async getItems(commit: GitLogCommit, uri: Uri, options: CommitQuickPickOptions = {}) { const items: (CommitWithFileStatusQuickPickItem | CommandQuickPickItem)[] = commit.files.map( fs => new CommitWithFileStatusQuickPickItem(commit, fs) ); @@ -127,7 +219,7 @@ export class CommitQuickPick { confirm: true, deleteAfter: false, stashItem: commit as GitStashCommit, - goBackCommand: currentCommand + goBackCommand: options.currentCommand }; items.splice( index++, @@ -145,7 +237,7 @@ export class CommitQuickPick { const stashDeleteCommmandArgs: StashDeleteCommandArgs = { confirm: true, stashItem: commit as GitStashCommit, - goBackCommand: currentCommand + goBackCommand: options.currentCommand }; items.splice( index++, @@ -176,7 +268,7 @@ export class CommitQuickPick { type: RemoteResourceType.Commit, sha: commit.sha }, - currentCommand + options.currentCommand ) ); } @@ -195,9 +287,9 @@ export class CommitQuickPick { new CommandQuickPickItem( { label: '$(git-compare) Open Directory Compare with Previous Revision', - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.previousFileShortSha} ${ - GlyphChars.Space - } $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}` + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${GitService.shortenSha( + commit.previousFileSha + )} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}` }, Commands.DiffDirectory, [commit.uri, diffDirectoryCommmandArgs] @@ -259,9 +351,9 @@ export class CommitQuickPick { const commitDetailsCommandArgs: ShowQuickCommitDetailsCommandArgs = { commit: commit, - repoLog: repoLog, + repoLog: options.repoLog, sha: commit.sha, - goBackCommand: goBackCommand + goBackCommand: options.goBackCommand }; items.splice( index++, @@ -276,130 +368,10 @@ export class CommitQuickPick { ) ); - if (goBackCommand) { - items.splice(0, 0, goBackCommand); + if (options.goBackCommand) { + items.splice(0, 0, options.goBackCommand); } - let previousCommand: KeyCommand | (() => Promise) | undefined = undefined; - let nextCommand: KeyCommand | (() => Promise) | undefined = undefined; - if (!stash) { - // If we have the full history, we are good - if (repoLog !== undefined && !repoLog.truncated && repoLog.sha === undefined) { - const previousCommandArgs: ShowQuickCommitDetailsCommandArgs = { - repoLog: repoLog, - sha: commit.previousSha, - goBackCommand: goBackCommand - }; - previousCommand = - commit.previousSha === undefined - ? undefined - : new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [ - commit.previousUri, - previousCommandArgs - ]); - - const nextCommandArgs: ShowQuickCommitDetailsCommandArgs = { - repoLog: repoLog, - sha: commit.nextSha, - goBackCommand: goBackCommand - }; - nextCommand = - commit.nextSha === undefined - ? undefined - : new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [ - commit.nextUri, - nextCommandArgs - ]); - } - else { - previousCommand = async () => { - let log = repoLog; - let c = log && log.commits.get(commit.sha); - - // If we can't find the commit or the previous commit isn't available (since it isn't trustworthy) - if (c === undefined || c.previousSha === undefined) { - log = await Container.git.getLog(commit.repoPath, { - maxCount: Container.config.advanced.maxListItems, - ref: commit.sha - }); - c = log && log.commits.get(commit.sha); - - if (c) { - // Copy over next info, since it is trustworthy at this point - c.nextSha = commit.nextSha; - } - } - - if (c === undefined || c.previousSha === undefined) return KeyNoopCommand; - - const previousCommandArgs: ShowQuickCommitDetailsCommandArgs = { - repoLog: log, - sha: c.previousSha, - goBackCommand: goBackCommand - }; - return new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [ - c.previousUri, - previousCommandArgs - ]); - }; - - nextCommand = async () => { - let log = repoLog; - let c = log && log.commits.get(commit.sha); - - // If we can't find the commit or the next commit isn't available (since it isn't trustworthy) - if (c === undefined || c.nextSha === undefined) { - log = undefined; - c = undefined; - - // Try to find the next commit - const nextLog = await Container.git.getLog(commit.repoPath, { - maxCount: 1, - reverse: true, - ref: commit.sha - }); - const next = nextLog && Iterables.first(nextLog.commits.values()); - if (next !== undefined && next.sha !== commit.sha) { - c = commit; - c.nextSha = next.sha; - } - } - - if (c === undefined || c.nextSha === undefined) return KeyNoopCommand; - - const nextCommandArgs: ShowQuickCommitDetailsCommandArgs = { - repoLog: log, - sha: c.nextSha, - goBackCommand: goBackCommand - }; - return new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [c.nextUri, nextCommandArgs]); - }; - } - } - - const scope = await Container.keyboard.beginScope({ - left: goBackCommand, - ',': previousCommand, - '.': nextCommand - }); - - const pick = await window.showQuickPick(items, { - matchOnDescription: true, - matchOnDetail: true, - placeHolder: `${commit.shortSha} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${ - commit.author ? `${commit.author}, ` : '' - }${commit.formattedDate} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getShortMessage()}`, - ignoreFocusOut: getQuickPickIgnoreFocusOut(), - onDidSelectItem: (item: QuickPickItem) => { - void scope.setKeyCommand('right', item); - if (typeof item.onDidSelect === 'function') { - item.onDidSelect(); - } - } - }); - - await scope.dispose(); - - return pick; + return items; } } diff --git a/src/system/iterable.ts b/src/system/iterable.ts index 06c0c99..5b0c3a1 100644 --- a/src/system/iterable.ts +++ b/src/system/iterable.ts @@ -112,8 +112,8 @@ export namespace Iterables { return value; } - export function last(source: Iterable): T | null { - let item: T | null = null; + export function last(source: Iterable): T | undefined { + let item: T | undefined; for (item of source) { /* noop */ }