Skip to content

Commit 29b455d

Browse files
committed
Adds Open Revision... command
Fixes issues with commit paging in certain quick pick menus
1 parent b254d7f commit 29b455d

File tree

8 files changed

+126
-44
lines changed

8 files changed

+126
-44
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
77
## [Unreleased]
88
### Added
99
- Adds `Open Working File` command (`gitlens.openWorkingFile`) - opens the working file for the active file revision -- closes [#236](https://github.com/eamodio/vscode-gitlens/issues/236)
10+
- Adds `Open Revision...` command (`gitlens.openFileRevision`) - opens the selected revision for the active file
11+
12+
### Fixed
13+
- Fixes issues with commit paging in certain quick pick menus
1014

1115
## [7.1.0-beta] - 2017-12-20
1216
### Changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ While GitLens is highly customizable and provides many [configuration settings](
332332

333333
- Adds a `Open Working File"` command (`gitlens.openWorkingFile`) to open the working file for the active file revision
334334

335+
- Adds a `Open Revision...` command (`gitlens.openFileRevision`) to open the selected revision for the active file
336+
335337
- Adds a `Open Changes (with difftool)` command (`gitlens.externalDiff`) to the source control group and source control resource context menus to open the changes of a file or set of files with the configured git difftool
336338

337339
- Adds a `Open All Changes (with difftool)` command (`gitlens.externalDiffAll`) to open all working changes with the configured git difftool

package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,11 @@
13221322
"title": "Open File in Remote",
13231323
"category": "GitLens"
13241324
},
1325+
{
1326+
"command": "gitlens.openFileRevision",
1327+
"title": "Open Revision...",
1328+
"category": "GitLens"
1329+
},
13251330
{
13261331
"command": "gitlens.openRepoInRemote",
13271332
"title": "Open Repository in Remote",
@@ -1737,6 +1742,10 @@
17371742
"command": "gitlens.openFileInRemote",
17381743
"when": "gitlens:activeIsTracked && gitlens:activeHasRemote"
17391744
},
1745+
{
1746+
"command": "gitlens.openFileRevision",
1747+
"when": "gitlens:activeIsTracked"
1748+
},
17401749
{
17411750
"command": "gitlens.openRepoInRemote",
17421751
"when": "gitlens:activeHasRemote"

src/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export function configureCommands(
7979
context.subscriptions.push(new Commands.OpenBranchInRemoteCommand(git));
8080
context.subscriptions.push(new Commands.OpenCommitInRemoteCommand(git));
8181
context.subscriptions.push(new Commands.OpenFileInRemoteCommand(git));
82-
context.subscriptions.push(new Commands.OpenFileRevisionCommand(annotationController));
82+
context.subscriptions.push(new Commands.OpenFileRevisionCommand(annotationController, git));
8383
context.subscriptions.push(new Commands.OpenInRemoteCommand());
8484
context.subscriptions.push(new Commands.OpenRepoInRemoteCommand(git));
8585
context.subscriptions.push(new Commands.OpenWorkingFileCommand(annotationController, git));

src/commands/diffWithRevision.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use strict';
2-
import { Strings } from '../system';
2+
import { Iterables, Strings } from '../system';
33
import { commands, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
44
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
55
import { GlyphChars } from '../constants';
@@ -14,6 +14,7 @@ export interface DiffWithRevisionCommandArgs {
1414

1515
line?: number;
1616
showOptions?: TextDocumentShowOptions;
17+
nextPageCommand?: CommandQuickPickItem;
1718
}
1819

1920
export class DiffWithRevisionCommand extends ActiveEditorCommand {
@@ -42,14 +43,33 @@ export class DiffWithRevisionCommand extends ActiveEditorCommand {
4243

4344
if (progressCancellation.token.isCancellationRequested) return undefined;
4445

46+
let previousPageCommand: CommandQuickPickItem | undefined = undefined;
47+
48+
if (log.truncated) {
49+
const npc = new CommandQuickPickItem({
50+
label: `$(arrow-right) Show Next Commits`,
51+
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} newer commits`
52+
}, Commands.DiffWithRevision, [uri, { ...args } as DiffWithRevisionCommandArgs]);
53+
54+
const last = Iterables.last(log.commits.values());
55+
if (last != null) {
56+
previousPageCommand = new CommandQuickPickItem({
57+
label: `$(arrow-left) Show Previous Commits`,
58+
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} older commits`
59+
}, Commands.DiffWithRevision, [new GitUri(uri, last), { ...args, nextPageCommand: npc } as DiffWithRevisionCommandArgs]);
60+
}
61+
}
62+
4563
const label = `${gitUri.getFormattedPath()}${gitUri.sha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${gitUri.shortSha}` : ''}`;
4664
const pick = await FileHistoryQuickPick.show(this.git, log, gitUri, label, progressCancellation, {
4765
pickerOnly: true,
66+
nextPageCommand: args.nextPageCommand,
67+
previousPageCommand: previousPageCommand,
4868
showAllCommand: log !== undefined && log.truncated
4969
? new CommandQuickPickItem({
5070
label: `$(sync) Show All Commits`,
5171
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while`
52-
}, Commands.ShowQuickFileHistory, [uri, { ...args, maxCount: 0 }])
72+
}, Commands.DiffWithRevision, [uri, { ...args, maxCount: 0 }])
5373
: undefined
5474
});
5575
if (pick === undefined) return undefined;

src/commands/openFileRevision.ts

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
'use strict';
2+
import { Iterables, Strings } from '../system';
23
import { Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
34
import { AnnotationController, FileAnnotationType } from '../annotations/annotationController';
4-
import { ActiveEditorCommand, Commands, openEditor } from './common';
5+
import { ActiveEditorCommand, Commands, getCommandUri, openEditor } from './common';
6+
import { GlyphChars } from '../constants';
7+
import { GitService, GitUri } from '../gitService';
58
import { Logger } from '../logger';
9+
import { Messages } from '../messages';
10+
import { CommandQuickPickItem, FileHistoryQuickPick } from '../quickPicks';
611

712
export interface OpenFileRevisionCommandArgs {
813
uri?: Uri;
14+
maxCount?: number;
15+
916
line?: number;
1017
showOptions?: TextDocumentShowOptions;
1118
annotationType?: FileAnnotationType;
19+
nextPageCommand?: CommandQuickPickItem;
1220
}
1321

1422
export class OpenFileRevisionCommand extends ActiveEditorCommand {
@@ -34,7 +42,8 @@ export class OpenFileRevisionCommand extends ActiveEditorCommand {
3442
}
3543

3644
constructor(
37-
private readonly annotationController: AnnotationController
45+
private readonly annotationController: AnnotationController,
46+
private readonly git: GitService
3847
) {
3948
super(Commands.OpenFileRevision);
4049
}
@@ -46,6 +55,55 @@ export class OpenFileRevisionCommand extends ActiveEditorCommand {
4655
}
4756

4857
try {
58+
if (args.uri === undefined) {
59+
uri = getCommandUri(uri, editor);
60+
if (uri === undefined) return undefined;
61+
62+
const gitUri = await GitUri.fromUri(uri, this.git);
63+
64+
const progressCancellation = FileHistoryQuickPick.showProgress(gitUri);
65+
66+
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { maxCount: args.maxCount, ref: gitUri.sha });
67+
if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open history compare');
68+
69+
if (progressCancellation.token.isCancellationRequested) return undefined;
70+
71+
let previousPageCommand: CommandQuickPickItem | undefined = undefined;
72+
73+
if (log.truncated) {
74+
const npc = new CommandQuickPickItem({
75+
label: `$(arrow-right) Show Next Commits`,
76+
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} newer commits`
77+
}, Commands.OpenFileRevision, [uri, { ...args } as OpenFileRevisionCommandArgs]);
78+
79+
const last = Iterables.last(log.commits.values());
80+
if (last != null) {
81+
previousPageCommand = new CommandQuickPickItem({
82+
label: `$(arrow-left) Show Previous Commits`,
83+
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} older commits`
84+
}, Commands.OpenFileRevision, [new GitUri(uri, last), { ...args, nextPageCommand: npc } as OpenFileRevisionCommandArgs]);
85+
}
86+
}
87+
88+
const label = `${gitUri.getFormattedPath()}${gitUri.sha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${gitUri.shortSha}` : ''}`;
89+
const pick = await FileHistoryQuickPick.show(this.git, log, gitUri, label, progressCancellation, {
90+
pickerOnly: true,
91+
nextPageCommand: args.nextPageCommand,
92+
previousPageCommand: previousPageCommand,
93+
showAllCommand: log !== undefined && log.truncated
94+
? new CommandQuickPickItem({
95+
label: `$(sync) Show All Commits`,
96+
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while`
97+
}, Commands.OpenFileRevision, [uri, { ...args, maxCount: 0 } as OpenFileRevisionCommandArgs])
98+
: undefined
99+
});
100+
if (pick === undefined) return undefined;
101+
102+
if (pick instanceof CommandQuickPickItem) return pick.execute();
103+
104+
args.uri = GitUri.toRevisionUri(pick.commit.sha, pick.commit.uri.fsPath, pick.commit.repoPath);
105+
}
106+
49107
if (args.line !== undefined && args.line !== 0) {
50108
if (args.showOptions === undefined) {
51109
args.showOptions = {};
@@ -60,7 +118,7 @@ export class OpenFileRevisionCommand extends ActiveEditorCommand {
60118
}
61119
catch (ex) {
62120
Logger.error(ex, 'OpenFileRevisionCommand');
63-
return window.showErrorMessage(`Unable to open in file revision. See output channel for more details`);
121+
return window.showErrorMessage(`Unable to open file revision. See output channel for more details`);
64122
}
65123
}
66124
}

src/commands/showQuickFileHistory.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use strict';
2-
import { Strings } from '../system';
2+
import { Iterables, Strings } from '../system';
33
import { commands, Range, TextEditor, Uri, window } from 'vscode';
44
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
55
import { GlyphChars } from '../constants';
@@ -44,15 +44,33 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand {
4444

4545
if (progressCancellation.token.isCancellationRequested) return undefined;
4646

47+
let previousPageCommand: CommandQuickPickItem | undefined = undefined;
48+
49+
if (args.log.truncated) {
50+
const npc = new CommandQuickPickItem({
51+
label: `$(arrow-right) Show Next Commits`,
52+
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${args.log.maxCount} newer commits`
53+
}, Commands.ShowQuickFileHistory, [gitUri, { ...args, log: undefined } as ShowQuickFileHistoryCommandArgs]);
54+
55+
const last = Iterables.last(args.log.commits.values());
56+
if (last != null) {
57+
previousPageCommand = new CommandQuickPickItem({
58+
label: `$(arrow-left) Show Previous Commits`,
59+
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${args.log.maxCount} older commits`
60+
}, Commands.ShowQuickFileHistory, [new GitUri(uri, last), { ...args, log: undefined, nextPageCommand: npc } as ShowQuickFileHistoryCommandArgs]);
61+
}
62+
}
63+
4764
const label = `${gitUri.getFormattedPath()}${gitUri.sha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${gitUri.shortSha}` : ''}`;
4865
const pick = await FileHistoryQuickPick.show(this.git, args.log, gitUri, label, progressCancellation, {
4966
goBackCommand: args.goBackCommand,
5067
nextPageCommand: args.nextPageCommand,
68+
previousPageCommand: previousPageCommand,
5169
showAllCommand: args.log !== undefined && args.log.truncated
5270
? new CommandQuickPickItem({
5371
label: `$(sync) Show All Commits`,
5472
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while`
55-
}, Commands.ShowQuickFileHistory, [uri, { ...args, maxCount: 0 }])
73+
}, Commands.ShowQuickFileHistory, [uri, { ...args, log: undefined, maxCount: 0 }])
5674
: undefined,
5775
showInResultsExplorerCommand: args.log !== undefined
5876
? new ShowCommitsInResultsQuickPickItem(args.log, {

src/quickPicks/fileHistory.ts

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@ export class FileHistoryQuickPick {
2020
});
2121
}
2222

23-
static async show(git: GitService, log: GitLog, uri: GitUri, placeHolder: string, progressCancellation: CancellationTokenSource, options: { goBackCommand?: CommandQuickPickItem, nextPageCommand?: CommandQuickPickItem, pickerOnly?: boolean, showAllCommand?: CommandQuickPickItem, showInResultsExplorerCommand?: CommandQuickPickItem } = {}): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> {
23+
static async show(git: GitService, log: GitLog, uri: GitUri, placeHolder: string, progressCancellation: CancellationTokenSource, options: { goBackCommand?: CommandQuickPickItem, nextPageCommand?: CommandQuickPickItem, previousPageCommand?: CommandQuickPickItem, pickerOnly?: boolean, showAllCommand?: CommandQuickPickItem, showInResultsExplorerCommand?: CommandQuickPickItem } = {}): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> {
2424
options = { pickerOnly: false, ...options };
2525

2626
const items = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))) as (CommitQuickPickItem | CommandQuickPickItem)[];
2727

28-
let previousPageCommand: CommandQuickPickItem | undefined = undefined;
29-
3028
let index = 0;
3129

3230
if (options.showInResultsExplorerCommand !== undefined) {
@@ -39,7 +37,7 @@ export class FileHistoryQuickPick {
3937
index++;
4038
items.splice(0, 0, options.showAllCommand);
4139
}
42-
else {
40+
else if (!options.pickerOnly) {
4341
const workingFileName = await git.findWorkingFileName(log.repoPath, path.relative(log.repoPath, uri.fsPath));
4442
if (workingFileName) {
4543
index++;
@@ -66,41 +64,14 @@ export class FileHistoryQuickPick {
6664
}
6765
}
6866

69-
if (options.nextPageCommand) {
67+
if (options.nextPageCommand !== undefined) {
7068
index++;
7169
items.splice(0, 0, options.nextPageCommand);
7270
}
7371

74-
if (log.truncated) {
75-
const npc = new CommandQuickPickItem({
76-
label: `$(arrow-right) Show Next Commits`,
77-
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} newer commits`
78-
}, Commands.ShowQuickFileHistory, [
79-
uri,
80-
{
81-
maxCount: log.maxCount,
82-
goBackCommand: options.goBackCommand,
83-
nextPageCommand: options.nextPageCommand
84-
} as ShowQuickFileHistoryCommandArgs
85-
]);
86-
87-
const last = Iterables.last(log.commits.values());
88-
if (last != null) {
89-
previousPageCommand = new CommandQuickPickItem({
90-
label: `$(arrow-left) Show Previous Commits`,
91-
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} older commits`
92-
}, Commands.ShowQuickFileHistory, [
93-
new GitUri(uri, last),
94-
{
95-
maxCount: log.maxCount,
96-
goBackCommand: options.goBackCommand,
97-
nextPageCommand: npc
98-
} as ShowQuickFileHistoryCommandArgs
99-
]);
100-
101-
index++;
102-
items.splice(0, 0, previousPageCommand);
103-
}
72+
if (options.previousPageCommand !== undefined) {
73+
index++;
74+
items.splice(0, 0, options.previousPageCommand);
10475
}
10576
}
10677

@@ -159,7 +130,7 @@ export class FileHistoryQuickPick {
159130

160131
const scope = await Keyboard.instance.beginScope({
161132
left: options.goBackCommand,
162-
',': previousPageCommand,
133+
',': options.previousPageCommand,
163134
'.': options.nextPageCommand
164135
});
165136

0 commit comments

Comments
 (0)