Adds new command to show quick commit info

This commit is contained in:
Eric Amodio
2017-02-10 04:09:00 -05:00
parent 615f55574b
commit e12ec7093c
8 changed files with 139 additions and 8 deletions

View File

@@ -341,6 +341,11 @@
"title": "Open File History Explorer", "title": "Open File History Explorer",
"category": "GitLens" "category": "GitLens"
}, },
{
"command": "gitlens.showQuickCommitDetails",
"title": "Show Commit Details",
"category": "GitLens"
},
{ {
"command": "gitlens.showQuickFileHistory", "command": "gitlens.showQuickFileHistory",
"title": "Show File History", "title": "Show File History",
@@ -450,6 +455,11 @@
"key": "shift+alt+h", "key": "shift+alt+h",
"mac": "shift+alt+h" "mac": "shift+alt+h"
}, },
{
"command": "gitlens.showQuickCommitDetails",
"key": "alt+c",
"mac": "alt+c"
},
{ {
"command": "gitlens.diffLineWithPrevious", "command": "gitlens.diffLineWithPrevious",
"key": "alt+p", "key": "alt+p",

View File

@@ -31,10 +31,12 @@ export class FileQuickPickItem implements QuickPickItem {
label: string; label: string;
description: string; description: string;
detail: string; detail: string;
sha: string;
uri: GitUri; uri: GitUri;
constructor(commit: GitCommit, public fileName: string) { constructor(commit: GitCommit, public fileName: string) {
this.label = fileName; this.label = fileName;
this.sha = commit.sha;
this.uri = GitUri.fromUri(Uri.file(path.resolve(commit.repoPath, fileName))); this.uri = GitUri.fromUri(Uri.file(path.resolve(commit.repoPath, fileName)));
} }
} }

View File

@@ -0,0 +1,112 @@
'use strict';
import { Iterables } from '../system';
import { commands, QuickPickOptions, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { EditorCommand } from './commands';
import { Commands } from '../constants';
import GitProvider, { GitUri } from '../gitProvider';
import { Logger } from '../logger';
import { BackQuickPickItem, CommitQuickPickItem, CompareQuickPickItem, FileQuickPickItem } from './quickPickItems';
import * as moment from 'moment';
export default class ShowQuickCommitDetailsCommand extends EditorCommand {
constructor(private git: GitProvider) {
super(Commands.ShowQuickCommitDetails);
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, sha?: string) {
if (!(uri instanceof Uri)) {
if (!editor.document) return undefined;
uri = editor.document.uri;
}
const gitUri = GitUri.fromUri(uri, this.git);
let repoPath = gitUri.repoPath;
let line = editor.selection.active.line;
if (!sha) {
const blameline = line - gitUri.offset;
if (blameline < 0) return undefined;
try {
const blame = await this.git.getBlameForLine(gitUri.fsPath, blameline, gitUri.sha, gitUri.repoPath);
if (!blame) return window.showWarningMessage(`Unable to show commit details. File is probably not under source control`);
sha = blame.commit.isUncommitted ? blame.commit.previousSha : blame.commit.sha;
repoPath = blame.commit.repoPath;
}
catch (ex) {
Logger.error('[GitLens.ShowQuickCommitDetails]', `getBlameForLine(${blameline})`, ex);
return window.showErrorMessage(`Unable to show commit details. See output channel for more details`);
}
}
try {
const log = await this.git.getLogForRepo(repoPath, sha, 0);
if (!log) return window.showWarningMessage(`Unable to show commit details`);
const commit = Iterables.first(log.commits.values());
const commitPick = new CommitQuickPickItem(commit, ` \u2014 ${commit.fileName}`);
const files = commitPick.commit.fileName
.split(', ')
.filter(_ => !!_)
.map(f => new FileQuickPickItem(commitPick.commit, f));
const filePick = await window.showQuickPick(files, {
matchOnDescription: true,
matchOnDetail: true,
placeHolder: `${commitPick.commit.sha} \u2022 ${commitPick.commit.author}, ${moment(commitPick.commit.date).fromNow()}`
} as QuickPickOptions);
if (filePick) {
// TODO need to make log for file -- go from commit to HEAD so we can get the current filename
const log = await this.git.getLogForFile(filePick.uri.fsPath, filePick.sha);
if (!log) return window.showWarningMessage(`Unable to open diff`);
const commit = Iterables.find(log.commits.values(), c => c.sha === commitPick.commit.sha);
let command: Commands | undefined = Commands.DiffWithWorking;
const items: CompareQuickPickItem[] = [
{
label: `Compare with Working Tree`,
description: `\u2022 ${commit.sha} $(git-compare) ${commit.fileName}`,
command: Commands.DiffWithWorking
}
];
if (commit.previousSha) {
items.push({
label: `Compare with Previous Commit`,
description: `\u2022 ${commit.previousSha} $(git-compare) ${commit.sha}`,
command: Commands.DiffWithPrevious
});
}
items.push({
label: `go back \u21A9`,
description: null,
command: Commands.ShowQuickCommitDetails
} as BackQuickPickItem);
const comparePick = await window.showQuickPick(items, {
matchOnDescription: true,
placeHolder: `${commit.fileName} \u2022 ${commit.sha} \u2022 ${commit.author}, ${moment(commit.date).fromNow()}`
} as QuickPickOptions);
command = comparePick ? comparePick.command : undefined;
if (command) {
if (command === Commands.ShowQuickCommitDetails) return commands.executeCommand(command, uri), sha;
return commands.executeCommand(command, commit.uri, commit);
}
}
return undefined;
}
catch (ex) {
Logger.error('[GitLens.ShowQuickCommitDetailsCommand]', ex);
return window.showErrorMessage(`Unable to show commit details. See output channel for more details`);
}
}
}

View File

@@ -43,7 +43,7 @@ export default class ShowQuickRepoHistoryCommand extends Command {
if (!repoPath) return window.showWarningMessage(`Unable to show repository history`); if (!repoPath) return window.showWarningMessage(`Unable to show repository history`);
const log = await this.git.getLogForRepo(repoPath, maxCount); const log = await this.git.getLogForRepo(repoPath, undefined, maxCount);
if (!log) return window.showWarningMessage(`Unable to show repository history`); if (!log) return window.showWarningMessage(`Unable to show repository history`);
const commits = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c, ` \u2014 ${c.fileName}`))) as QuickPickItem[]; const commits = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c, ` \u2014 ${c.fileName}`))) as QuickPickItem[];
@@ -93,7 +93,8 @@ export default class ShowQuickRepoHistoryCommand extends Command {
const filePick = pick as FileQuickPickItem; const filePick = pick as FileQuickPickItem;
if (filePick) { if (filePick) {
const log = await this.git.getLogForFile(filePick.uri.fsPath); // TODO need to make log for file -- go from commit to HEAD so we can get the current filename
const log = await this.git.getLogForFile(filePick.uri.fsPath, filePick.sha);
if (!log) return window.showWarningMessage(`Unable to open diff`); if (!log) return window.showWarningMessage(`Unable to open diff`);
const commit = Iterables.find(log.commits.values(), c => c.sha === commitPick.commit.sha); const commit = Iterables.find(log.commits.values(), c => c.sha === commitPick.commit.sha);

View File

@@ -14,7 +14,7 @@ export const BuiltInCommands = {
ToggleRenderWhitespace: 'editor.action.toggleRenderWhitespace' as BuiltInCommands ToggleRenderWhitespace: 'editor.action.toggleRenderWhitespace' as BuiltInCommands
}; };
export type Commands = 'gitlens.diffWithPrevious' | 'gitlens.diffLineWithPrevious' | 'gitlens.diffWithWorking' | 'gitlens.diffLineWithWorking' | 'gitlens.showBlame' | 'gitlens.showBlameHistory' | 'gitlens.showFileHistory' | 'gitlens.showQuickFileHistory' | 'gitlens.showQuickRepoHistory' | 'gitlens.toggleBlame' | 'gitlens.toggleCodeLens'; export type Commands = 'gitlens.diffWithPrevious' | 'gitlens.diffLineWithPrevious' | 'gitlens.diffWithWorking' | 'gitlens.diffLineWithWorking' | 'gitlens.showBlame' | 'gitlens.showBlameHistory' | 'gitlens.showFileHistory' | 'gitlens.showQuickCommitDetails' | 'gitlens.showQuickFileHistory' | 'gitlens.showQuickRepoHistory' | 'gitlens.toggleBlame' | 'gitlens.toggleCodeLens';
export const Commands = { export const Commands = {
DiffWithPrevious: 'gitlens.diffWithPrevious' as Commands, DiffWithPrevious: 'gitlens.diffWithPrevious' as Commands,
DiffLineWithPrevious: 'gitlens.diffLineWithPrevious' as Commands, DiffLineWithPrevious: 'gitlens.diffLineWithPrevious' as Commands,
@@ -23,6 +23,7 @@ export const Commands = {
ShowBlame: 'gitlens.showBlame' as Commands, ShowBlame: 'gitlens.showBlame' as Commands,
ShowBlameHistory: 'gitlens.showBlameHistory' as Commands, ShowBlameHistory: 'gitlens.showBlameHistory' as Commands,
ShowFileHistory: 'gitlens.showFileHistory' as Commands, ShowFileHistory: 'gitlens.showFileHistory' as Commands,
ShowQuickCommitDetails: 'gitlens.showQuickCommitDetails' as Commands,
ShowQuickFileHistory: 'gitlens.showQuickFileHistory' as Commands, ShowQuickFileHistory: 'gitlens.showQuickFileHistory' as Commands,
ShowQuickRepoHistory: 'gitlens.showQuickRepoHistory' as Commands, ShowQuickRepoHistory: 'gitlens.showQuickRepoHistory' as Commands,
ToggleBlame: 'gitlens.toggleBlame' as Commands, ToggleBlame: 'gitlens.toggleBlame' as Commands,

View File

@@ -10,6 +10,7 @@ import DiffWithWorkingCommand from './commands/diffWithWorking';
import ShowBlameCommand from './commands/showBlame'; import ShowBlameCommand from './commands/showBlame';
import ShowBlameHistoryCommand from './commands/showBlameHistory'; import ShowBlameHistoryCommand from './commands/showBlameHistory';
import ShowFileHistoryCommand from './commands/showFileHistory'; import ShowFileHistoryCommand from './commands/showFileHistory';
import ShowQuickCommitDetailsCommand from './commands/showQuickCommitDetails';
import ShowQuickFileHistoryCommand from './commands/showQuickFileHistory'; import ShowQuickFileHistoryCommand from './commands/showQuickFileHistory';
import ShowQuickRepoHistoryCommand from './commands/showQuickRepoHistory'; import ShowQuickRepoHistoryCommand from './commands/showQuickRepoHistory';
import ToggleBlameCommand from './commands/toggleBlame'; import ToggleBlameCommand from './commands/toggleBlame';
@@ -73,6 +74,7 @@ export async function activate(context: ExtensionContext) {
context.subscriptions.push(new ToggleBlameCommand(annotationController)); context.subscriptions.push(new ToggleBlameCommand(annotationController));
context.subscriptions.push(new ShowBlameHistoryCommand(git)); context.subscriptions.push(new ShowBlameHistoryCommand(git));
context.subscriptions.push(new ShowFileHistoryCommand(git)); context.subscriptions.push(new ShowFileHistoryCommand(git));
context.subscriptions.push(new ShowQuickCommitDetailsCommand(git));
context.subscriptions.push(new ShowQuickFileHistoryCommand(git)); context.subscriptions.push(new ShowQuickFileHistoryCommand(git));
context.subscriptions.push(new ShowQuickRepoHistoryCommand(git, repoPath)); context.subscriptions.push(new ShowQuickRepoHistoryCommand(git, repoPath));
context.subscriptions.push(new ToggleCodeLensCommand(git)); context.subscriptions.push(new ToggleCodeLensCommand(git));

View File

@@ -95,7 +95,7 @@ export default class Git {
params.push(`-n${maxCount}`); params.push(`-n${maxCount}`);
} }
if (sha) { if (sha) {
params.push(`origin..${sha}`); params.push(sha);
params.push(`--`); params.push(`--`);
} }
@@ -111,18 +111,21 @@ export default class Git {
} }
if (sha) { if (sha) {
params.push(`--follow`); params.push(`--follow`);
params.push(`origin..${sha}`); params.push(sha);
} }
params.push(`-L ${start},${end}:${file}`); params.push(`-L ${start},${end}:${file}`);
return gitCommand(root, ...params); return gitCommand(root, ...params);
} }
static logRepo(repoPath: string, maxCount?: number) { static logRepo(repoPath: string, sha?: string, maxCount?: number) {
const params = [...DefaultLogParams]; const params = [...DefaultLogParams];
if (maxCount) { if (maxCount) {
params.push(`-n${maxCount}`); params.push(`-n${maxCount}`);
} }
if (sha) {
params.push(`${sha}^!`);
}
return gitCommand(repoPath, ...params); return gitCommand(repoPath, ...params);
} }

View File

@@ -421,7 +421,7 @@ export default class GitProvider extends Disposable {
return locations; return locations;
} }
async getLogForRepo(repoPath: string, maxCount?: number): Promise<IGitLog | undefined> { async getLogForRepo(repoPath: string, sha?: string, maxCount?: number): Promise<IGitLog | undefined> {
Logger.log(`getLogForRepo('${repoPath}', ${maxCount})`); Logger.log(`getLogForRepo('${repoPath}', ${maxCount})`);
if (maxCount == null) { if (maxCount == null) {
@@ -429,7 +429,7 @@ export default class GitProvider extends Disposable {
} }
try { try {
const data = await Git.logRepo(repoPath, maxCount); const data = await Git.logRepo(repoPath, sha, maxCount);
return new GitLogParserEnricher().enrich(data, repoPath, true); return new GitLogParserEnricher().enrich(data, repoPath, true);
} }
catch (ex) { catch (ex) {