mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-02-16 18:48:45 -05:00
Adds shortcut for gitlens.showQuickFileHistory
Adds shortcut for gitlens.showQuickRepoHistory Adds gitlens.advanced.maxQuickHistory to limit the number of quick history entries to show Adds gitlens.diffLineWithPrevious as alt context menu item for gitlens.diffWithPrevious Adds gitlens.diffLineWithWorking as alt context menu item for gitlens.diffWithWorking Adds gitlens.showFileHistory as alt context menu item for gitlens.showQuickFileHistory Removes context menu for gitlens.diffLineWithPrevious Removes context menu for gitlens.diffLineWithWorking Replaces gitlens.menus.fileDiff.enabled & gitlens.menus.lineDiff.enabled with gitlens.menus.diff.enabled
This commit is contained in:
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,6 +1,18 @@
|
|||||||
---
|
---
|
||||||
## Release Notes
|
## Release Notes
|
||||||
|
|
||||||
|
### 1.4.0
|
||||||
|
|
||||||
|
- Adds `alt+h` shortcut for the `gitlens.showQuickFileHistory` command
|
||||||
|
- Adds `shift+alt+h` shortcut for the `gitlens.showQuickRepoHistory` command
|
||||||
|
- Adds `gitlens.advanced.maxQuickHistory` to limit the number of quick history entries to show (for better performance); Defaults to 200
|
||||||
|
- Adds `gitlens.diffLineWithPrevious` as `alt` context menu item for `gitlens.diffWithPrevious`
|
||||||
|
- Adds `gitlens.diffLineWithWorking` as `alt` context menu item for `gitlens.diffWithWorking`
|
||||||
|
- Adds `gitlens.showFileHistory` as `alt` context menu item for `gitlens.showQuickFileHistory`
|
||||||
|
- Removes context menu for `gitlens.diffLineWithPrevious` -- since it is now the `alt` of `gitlens.diffWithPrevious`
|
||||||
|
- Removes context menu for `gitlens.diffLineWithWorking` -- since it is now the `alt` of `gitlens.diffWithWorking`
|
||||||
|
- Replaces `gitlens.menus.fileDiff.enabled` and `gitlens.menus.lineDiff.enabled` with `gitlens.menus.diff.enabled` -- since the switch between file and line diff is now controlled by the `alt` key
|
||||||
|
|
||||||
### 1.3.1
|
### 1.3.1
|
||||||
|
|
||||||
- Renames `Diff` commands for better clarity
|
- Renames `Diff` commands for better clarity
|
||||||
|
|||||||
@@ -38,13 +38,11 @@ Provides Git CodeLens information (most recent commit, # of authors), on-demand
|
|||||||
|`gitlens.codeLens.recentChange.command`|Specifies the command executed when the recent change CodeLens is clicked. `gitlens.toggleBlame` - toggles blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current checked-in file with the previous commit. `gitlens.showQuickFileHistory` - shows a file history picker
|
|`gitlens.codeLens.recentChange.command`|Specifies the command executed when the recent change CodeLens is clicked. `gitlens.toggleBlame` - toggles blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current checked-in file with the previous commit. `gitlens.showQuickFileHistory` - shows a file history picker
|
||||||
|`gitlens.codeLens.authors.enabled`|Specifies whether the authors CodeLens is shown
|
|`gitlens.codeLens.authors.enabled`|Specifies whether the authors CodeLens is shown
|
||||||
|`gitlens.codeLens.authors.command`|Specifies the command executed when the authors CodeLens is clicked. `gitlens.toggleBlame` - toggles blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current checked-in file with the previous commit. `gitlens.showQuickFileHistory` - shows a file history picker
|
|`gitlens.codeLens.authors.command`|Specifies the command executed when the authors CodeLens is clicked. `gitlens.toggleBlame` - toggles blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current checked-in file with the previous commit. `gitlens.showQuickFileHistory` - shows a file history picker
|
||||||
|`gitlens.menus.fileDiff.enabled`|Specifies whether file-based diff commands will be added to the context menus
|
|`gitlens.menus.diff.enabled`|Specifies whether diff commands will be added to the context menus
|
||||||
|`gitlens.menus.lineDiff.enabled`|Specifies whether line-based diff commands will be added to the context menus
|
|
||||||
|`gitlens.statusBar.enabled`|Specifies whether blame information is shown in the status bar
|
|`gitlens.statusBar.enabled`|Specifies whether blame information is shown in the status bar
|
||||||
|`gitlens.statusBar.command`|"Specifies the command executed when the blame status bar item is clicked. `gitlens.toggleBlame` - toggles blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current checked-in file with the previous commit. `gitlens.showQuickFileHistory` - shows a file history picker
|
|`gitlens.statusBar.command`|"Specifies the command executed when the blame status bar item is clicked. `gitlens.toggleBlame` - toggles blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current checked-in file with the previous commit. `gitlens.showQuickFileHistory` - shows a file history picker
|
||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
|
|
||||||
- Content in the **history explorers** disappears after a bit: [vscode issue](https://github.com/Microsoft/vscode/issues/16098)
|
|
||||||
- CodeLens aren't updated properly after a file is saved: [vscode issue](https://github.com/Microsoft/vscode/issues/11546)
|
- CodeLens aren't updated properly after a file is saved: [vscode issue](https://github.com/Microsoft/vscode/issues/11546)
|
||||||
- Visible whitespace causes issue with blame overlay (currently fixed with a hack, but infrequently and randomly fails): [vscode issue](https://github.com/Microsoft/vscode/issues/11485)
|
- Visible whitespace causes issue with blame overlay (currently fixed with a hack, but infrequently and randomly fails): [vscode issue](https://github.com/Microsoft/vscode/issues/11485)
|
||||||
|
|||||||
64
package.json
64
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gitlens",
|
"name": "gitlens",
|
||||||
"version": "1.3.1",
|
"version": "1.4.0",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Eric Amodio",
|
"name": "Eric Amodio",
|
||||||
"email": "eamodio@gmail.com"
|
"email": "eamodio@gmail.com"
|
||||||
@@ -201,15 +201,10 @@
|
|||||||
],
|
],
|
||||||
"description": "Specifies the command executed when the blame status bar item is clicked. `gitlens.toggleBlame` - toggles blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current checked-in file with the previous commit. `gitlens.showQuickFileHistory` - shows a file history picker"
|
"description": "Specifies the command executed when the blame status bar item is clicked. `gitlens.toggleBlame` - toggles blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current checked-in file with the previous commit. `gitlens.showQuickFileHistory` - shows a file history picker"
|
||||||
},
|
},
|
||||||
"gitlens.menus.fileDiff.enabled": {
|
"gitlens.menus.diff.enabled": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true,
|
"default": true,
|
||||||
"description": "Specifies whether file-based diff commands will be added to the context menus"
|
"description": "Specifies whether diff commands will be added to the context menus"
|
||||||
},
|
|
||||||
"gitlens.menus.lineDiff.enabled": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"description": "Specifies whether line-based diff commands will be added to the context menus"
|
|
||||||
},
|
},
|
||||||
"gitlens.advanced.caching.enabled": {
|
"gitlens.advanced.caching.enabled": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -231,6 +226,11 @@
|
|||||||
"default": null,
|
"default": null,
|
||||||
"description": "Specifies a git path to use"
|
"description": "Specifies a git path to use"
|
||||||
},
|
},
|
||||||
|
"gitlens.advanced.maxQuickHistory": {
|
||||||
|
"type": "number",
|
||||||
|
"default": 200,
|
||||||
|
"description": "Specifies the maximum number of QuickPick history entries to show"
|
||||||
|
},
|
||||||
"gitlens.advanced.output.level": {
|
"gitlens.advanced.output.level": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "silent",
|
"default": "silent",
|
||||||
@@ -304,12 +304,12 @@
|
|||||||
"explorer/context": [
|
"explorer/context": [
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffWithWorking",
|
"command": "gitlens.diffWithWorking",
|
||||||
"when": "config.gitlens.menus.fileDiff.enabled && config.git.enabled",
|
"when": "config.gitlens.menus.diff.enabled && config.git.enabled",
|
||||||
"group": "2_gitlens-file"
|
"group": "2_gitlens-file"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffWithPrevious",
|
"command": "gitlens.diffWithPrevious",
|
||||||
"when": "config.gitlens.menus.fileDiff.enabled && config.git.enabled",
|
"when": "config.gitlens.menus.diff.enabled && config.git.enabled",
|
||||||
"group": "2_gitlens-file"
|
"group": "2_gitlens-file"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -321,12 +321,12 @@
|
|||||||
"editor/title": [
|
"editor/title": [
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffWithWorking",
|
"command": "gitlens.diffWithWorking",
|
||||||
"when": "config.gitlens.menus.fileDiff.enabled && config.git.enabled",
|
"when": "config.gitlens.menus.diff.enabled && config.git.enabled",
|
||||||
"group": "2_gitlens"
|
"group": "2_gitlens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffWithPrevious",
|
"command": "gitlens.diffWithPrevious",
|
||||||
"when": "config.gitlens.menus.fileDiff.enabled && config.git.enabled",
|
"when": "config.gitlens.menus.diff.enabled && config.git.enabled",
|
||||||
"group": "2_gitlens"
|
"group": "2_gitlens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -344,27 +344,18 @@
|
|||||||
{
|
{
|
||||||
"command": "gitlens.diffWithWorking",
|
"command": "gitlens.diffWithWorking",
|
||||||
"alt": "gitlens.diffLineWithWorking",
|
"alt": "gitlens.diffLineWithWorking",
|
||||||
"when": "editorTextFocus && config.gitlens.menus.fileDiff.enabled && config.git.enabled",
|
"when": "editorTextFocus && config.gitlens.menus.diff.enabled && config.git.enabled",
|
||||||
"group": "2_gitlens@1.0"
|
"group": "2_gitlens@1.0"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"command": "gitlens.diffLineWithWorking",
|
|
||||||
"when": "editorTextFocus && config.gitlens.menus.lineDiff.enabled && config.git.enabled",
|
|
||||||
"group": "2_gitlens@1.1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffWithPrevious",
|
"command": "gitlens.diffWithPrevious",
|
||||||
"alt": "gitlens.diffLineWithPrevious",
|
"alt": "gitlens.diffLineWithPrevious",
|
||||||
"when": "editorTextFocus && config.gitlens.menus.fileDiff.enabled && config.git.enabled",
|
"when": "editorTextFocus && config.gitlens.menus.diff.enabled && config.git.enabled",
|
||||||
"group": "2_gitlens@1.2"
|
"group": "2_gitlens@1.1"
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.diffLineWithPrevious",
|
|
||||||
"when": "editorTextFocus && config.gitlens.menus.lineDiff.enabled && config.git.enabled",
|
|
||||||
"group": "2_gitlens@1.3"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.showQuickFileHistory",
|
"command": "gitlens.showQuickFileHistory",
|
||||||
|
"alt": "gitlens.showFileHistory",
|
||||||
"when": "config.git.enabled",
|
"when": "config.git.enabled",
|
||||||
"group": "3_gitlens"
|
"group": "3_gitlens"
|
||||||
},
|
},
|
||||||
@@ -382,6 +373,17 @@
|
|||||||
"mac": "alt+b",
|
"mac": "alt+b",
|
||||||
"when": "editorTextFocus"
|
"when": "editorTextFocus"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.showQuickFileHistory",
|
||||||
|
"key": "alt+h",
|
||||||
|
"mac": "alt+h",
|
||||||
|
"when": "editorTextFocus"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.showQuickRepoHistory",
|
||||||
|
"key": "shift+alt+h",
|
||||||
|
"mac": "shift+alt+h"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.toggleCodeLens",
|
"command": "gitlens.toggleCodeLens",
|
||||||
"key": "alt+shift+b",
|
"key": "alt+shift+b",
|
||||||
@@ -407,17 +409,17 @@
|
|||||||
"lodash.escaperegexp": "^4.1.2",
|
"lodash.escaperegexp": "^4.1.2",
|
||||||
"lodash.isequal": "^4.4.0",
|
"lodash.isequal": "^4.4.0",
|
||||||
"lodash.once": "^4.1.1",
|
"lodash.once": "^4.1.1",
|
||||||
"moment": "^2.17.0",
|
"moment": "^2.17.1",
|
||||||
"spawn-rx": "^2.0.6",
|
"spawn-rx": "^2.0.7",
|
||||||
"tmp": "^0.0.31"
|
"tmp": "^0.0.31"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^0.0.2",
|
"@types/node": "^6.0.55",
|
||||||
"@types/mocha": "^2.2.33",
|
"@types/mocha": "^2.2.35",
|
||||||
"@types/tmp": "^0.0.32",
|
"@types/tmp": "^0.0.32",
|
||||||
"mocha": "^3.2.0",
|
"mocha": "^3.2.0",
|
||||||
"tslint": "^4.0.2",
|
"tslint": "^4.2.0",
|
||||||
"typescript": "^2.0.10",
|
"typescript": "^2.1.4",
|
||||||
"vscode": "^1.0.3"
|
"vscode": "^1.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,3 +32,15 @@ export class FileQuickPickItem implements QuickPickItem {
|
|||||||
this.uri = GitUri.fromUri(Uri.file(path.resolve(commit.repoPath, fileName)));
|
this.uri = GitUri.fromUri(Uri.file(path.resolve(commit.repoPath, fileName)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ShowAllCommitsQuickPickItem implements QuickPickItem {
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
detail: string;
|
||||||
|
|
||||||
|
constructor(maxItems: number) {
|
||||||
|
this.label = `Show All Commits`;
|
||||||
|
this.description = `\u2014 Currently only showing the first ${maxItems} commits`;
|
||||||
|
this.detail = `This may take a while`;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,9 @@ export default class ShowBlameHistoryCommand extends EditorCommand {
|
|||||||
if (!(uri instanceof Uri)) {
|
if (!(uri instanceof Uri)) {
|
||||||
if (!editor.document) return undefined;
|
if (!editor.document) return undefined;
|
||||||
uri = editor.document.uri;
|
uri = editor.document.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (range == null || position == null) {
|
||||||
// If the command is executed manually -- treat it as a click on the root lens (i.e. show blame for the whole file)
|
// If the command is executed manually -- treat it as a click on the root lens (i.e. show blame for the whole file)
|
||||||
range = editor.document.validateRange(new Range(0, 0, 1000000, 1000000));
|
range = editor.document.validateRange(new Range(0, 0, 1000000, 1000000));
|
||||||
position = editor.document.validateRange(new Range(0, 0, 0, 1000000)).start;
|
position = editor.document.validateRange(new Range(0, 0, 0, 1000000)).start;
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ export default class ShowFileHistoryCommand extends EditorCommand {
|
|||||||
if (!(uri instanceof Uri)) {
|
if (!(uri instanceof Uri)) {
|
||||||
if (!editor.document) return undefined;
|
if (!editor.document) return undefined;
|
||||||
uri = editor.document.uri;
|
uri = editor.document.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position == null) {
|
||||||
// If the command is executed manually -- treat it as a click on the root lens (i.e. show blame for the whole file)
|
// If the command is executed manually -- treat it as a click on the root lens (i.e. show blame for the whole file)
|
||||||
position = editor.document.validateRange(new Range(0, 0, 0, 1000000)).start;
|
position = editor.document.validateRange(new Range(0, 0, 0, 1000000)).start;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Iterables } from '../system';
|
import { Iterables } from '../system';
|
||||||
import { commands, QuickPickOptions, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
|
import { commands, QuickPickItem, QuickPickOptions, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
|
||||||
import { EditorCommand } from './commands';
|
import { EditorCommand } from './commands';
|
||||||
import { Commands } from '../constants';
|
import { Commands } from '../constants';
|
||||||
import GitProvider, { GitUri } from '../gitProvider';
|
import GitProvider, { GitUri } from '../gitProvider';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { CommitQuickPickItem, CompareQuickPickItem } from './quickPickItems';
|
import { CommitQuickPickItem, CompareQuickPickItem, ShowAllCommitsQuickPickItem } from './quickPickItems';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
|
||||||
export default class ShowQuickFileHistoryCommand extends EditorCommand {
|
export default class ShowQuickFileHistoryCommand extends EditorCommand {
|
||||||
@@ -13,7 +13,7 @@ export default class ShowQuickFileHistoryCommand extends EditorCommand {
|
|||||||
super(Commands.ShowQuickFileHistory);
|
super(Commands.ShowQuickFileHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri) {
|
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, maxCount?: number) {
|
||||||
if (!(uri instanceof Uri)) {
|
if (!(uri instanceof Uri)) {
|
||||||
if (!editor.document) return undefined;
|
if (!editor.document) return undefined;
|
||||||
uri = editor.document.uri;
|
uri = editor.document.uri;
|
||||||
@@ -21,48 +21,62 @@ export default class ShowQuickFileHistoryCommand extends EditorCommand {
|
|||||||
|
|
||||||
const gitUri = GitUri.fromUri(uri, this.git);
|
const gitUri = GitUri.fromUri(uri, this.git);
|
||||||
|
|
||||||
|
if (maxCount == null) {
|
||||||
|
maxCount = this.git.config.advanced.maxQuickHistory;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const log = await this.git.getLogForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath);
|
const log = await this.git.getLogForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath, undefined, maxCount);
|
||||||
if (!log) return window.showWarningMessage(`Unable to show file history. File is probably not under source control`);
|
if (!log) return window.showWarningMessage(`Unable to show file history. File is probably not under source control`);
|
||||||
|
|
||||||
const items = Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c));
|
const commits = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))) as QuickPickItem[];
|
||||||
const commitPick = await window.showQuickPick(Array.from(items), <QuickPickOptions>{
|
let placeHolderSuffix = '';
|
||||||
|
if (maxCount !== 0 && commits.length === this.git.config.advanced.maxQuickHistory) {
|
||||||
|
placeHolderSuffix = ` \u2014 Only showing the first ${this.git.config.advanced.maxQuickHistory} commits`;
|
||||||
|
commits.push(new ShowAllCommitsQuickPickItem(this.git.config.advanced.maxQuickHistory));
|
||||||
|
}
|
||||||
|
|
||||||
|
const pick = await window.showQuickPick(commits, {
|
||||||
matchOnDescription: true,
|
matchOnDescription: true,
|
||||||
matchOnDetail: true,
|
matchOnDetail: true,
|
||||||
placeHolder: Iterables.first(log.commits.values()).fileName
|
placeHolder: `${Iterables.first(log.commits.values()).fileName}${placeHolderSuffix}`
|
||||||
});
|
} as QuickPickOptions);
|
||||||
|
|
||||||
if (commitPick) {
|
if (!pick) return undefined;
|
||||||
const commit = commitPick.commit;
|
if (pick instanceof ShowAllCommitsQuickPickItem) {
|
||||||
|
return commands.executeCommand(Commands.ShowQuickFileHistory, uri, 0);
|
||||||
|
}
|
||||||
|
|
||||||
let command: Commands | undefined = Commands.DiffWithWorking;
|
const commitPick = pick as CommitQuickPickItem;
|
||||||
if (commit.previousSha) {
|
const commit = commitPick.commit;
|
||||||
const items: CompareQuickPickItem[] = [
|
|
||||||
{
|
|
||||||
label: `Compare with Working Tree`,
|
|
||||||
description: `\u2022 ${commit.sha} $(git-compare) ${commit.fileName}`,
|
|
||||||
detail: null,
|
|
||||||
command: Commands.DiffWithWorking
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: `Compare with Previous Commit`,
|
|
||||||
description: `\u2022 ${commit.previousSha} $(git-compare) ${commit.sha}`,
|
|
||||||
detail: null,
|
|
||||||
command: Commands.DiffWithPrevious
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const comparePick = await window.showQuickPick(items, <QuickPickOptions>{
|
let command: Commands | undefined = Commands.DiffWithWorking;
|
||||||
matchOnDescription: true,
|
if (commit.previousSha) {
|
||||||
placeHolder: `${commit.fileName} \u2022 ${commit.sha} \u2022 ${commit.author}, ${moment(commit.date).fromNow()}`
|
const items: CompareQuickPickItem[] = [
|
||||||
});
|
{
|
||||||
|
label: `Compare with Working Tree`,
|
||||||
|
description: `\u2022 ${commit.sha} $(git-compare) ${commit.fileName}`,
|
||||||
|
detail: null,
|
||||||
|
command: Commands.DiffWithWorking
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: `Compare with Previous Commit`,
|
||||||
|
description: `\u2022 ${commit.previousSha} $(git-compare) ${commit.sha}`,
|
||||||
|
detail: null,
|
||||||
|
command: Commands.DiffWithPrevious
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
command = comparePick ? comparePick.command : undefined;
|
const comparePick = await window.showQuickPick(items, {
|
||||||
}
|
matchOnDescription: true,
|
||||||
|
placeHolder: `${commit.fileName} \u2022 ${commit.sha} \u2022 ${commit.author}, ${moment(commit.date).fromNow()}`
|
||||||
|
} as QuickPickOptions);
|
||||||
|
|
||||||
if (command) {
|
command = comparePick ? comparePick.command : undefined;
|
||||||
return commands.executeCommand(command, commit.uri, commit);
|
}
|
||||||
}
|
|
||||||
|
if (command) {
|
||||||
|
return commands.executeCommand(command, commit.uri, commit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Iterables } from '../system';
|
import { Iterables } from '../system';
|
||||||
import { commands, QuickPickOptions, Uri, window } from 'vscode';
|
import { commands, QuickPickItem, QuickPickOptions, Uri, window } from 'vscode';
|
||||||
import { Command } from './commands';
|
import { Command } from './commands';
|
||||||
import { Commands } from '../constants';
|
import { Commands } from '../constants';
|
||||||
import GitProvider, { GitUri } from '../gitProvider';
|
import GitProvider, { GitUri } from '../gitProvider';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { CommitQuickPickItem, CompareQuickPickItem, FileQuickPickItem } from './quickPickItems';
|
import { CommitQuickPickItem, CompareQuickPickItem, FileQuickPickItem, ShowAllCommitsQuickPickItem } from './quickPickItems';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
|
||||||
export default class ShowQuickRepoHistoryCommand extends Command {
|
export default class ShowQuickRepoHistoryCommand extends Command {
|
||||||
constructor(private git: GitProvider, public repoPath: string) {
|
constructor(private git: GitProvider, public repoPath: string) {
|
||||||
super(Commands.ShowQuickRepoHistory);
|
super(Commands.ShowQuickRepoHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(uri?: Uri) {
|
async execute(uri?: Uri, maxCount?: number) {
|
||||||
if (!(uri instanceof Uri)) {
|
if (!(uri instanceof Uri)) {
|
||||||
const document = window.activeTextEditor && window.activeTextEditor.document;
|
const document = window.activeTextEditor && window.activeTextEditor.document;
|
||||||
if (document) {
|
if (document) {
|
||||||
@@ -20,6 +21,10 @@ export default class ShowQuickRepoHistoryCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (maxCount == null) {
|
||||||
|
maxCount = this.git.config.advanced.maxQuickHistory;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let repoPath: string;
|
let repoPath: string;
|
||||||
if (uri instanceof Uri) {
|
if (uri instanceof Uri) {
|
||||||
@@ -37,57 +42,68 @@ 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);
|
const log = await this.git.getLogForRepo(repoPath, maxCount);
|
||||||
if (!log) return window.showWarningMessage(`Unable to show repository history`);
|
if (!log) return window.showWarningMessage(`Unable to show repository history`);
|
||||||
|
|
||||||
const items = Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c, ` \u2014 ${c.fileName}`));
|
const commits = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c, ` \u2014 ${c.fileName}`))) as QuickPickItem[];
|
||||||
const commitPick = await window.showQuickPick(Array.from(items), <QuickPickOptions>{
|
let placeHolder = '';
|
||||||
|
if (maxCount !== 0 && commits.length === this.git.config.advanced.maxQuickHistory) {
|
||||||
|
placeHolder = `Only showing the first ${this.git.config.advanced.maxQuickHistory} commits`;
|
||||||
|
commits.push(new ShowAllCommitsQuickPickItem(this.git.config.advanced.maxQuickHistory));
|
||||||
|
}
|
||||||
|
|
||||||
|
const pick = await window.showQuickPick(commits, {
|
||||||
matchOnDescription: true,
|
matchOnDescription: true,
|
||||||
matchOnDetail: true
|
matchOnDetail: true,
|
||||||
});
|
placeHolder: placeHolder
|
||||||
|
} as QuickPickOptions);
|
||||||
|
|
||||||
if (commitPick) {
|
if (!pick) return undefined;
|
||||||
const items = commitPick.commit.fileName.split(', ').map(f => new FileQuickPickItem(commitPick.commit, f));
|
if (pick instanceof ShowAllCommitsQuickPickItem) {
|
||||||
const filePick = await window.showQuickPick(items, <QuickPickOptions>{
|
return commands.executeCommand(Commands.ShowQuickRepoHistory, uri, 0);
|
||||||
matchOnDescription: true,
|
}
|
||||||
matchOnDetail: true,
|
|
||||||
placeHolder: `${commitPick.commit.sha} \u2022 ${commitPick.commit.author}, ${moment(commitPick.commit.date).fromNow()}`
|
|
||||||
});
|
|
||||||
|
|
||||||
if (filePick) {
|
const commitPick = pick as CommitQuickPickItem;
|
||||||
const log = await this.git.getLogForFile(filePick.uri.fsPath);
|
const files = commitPick.commit.fileName.split(', ').map(f => new FileQuickPickItem(commitPick.commit, f));
|
||||||
if (!log) return window.showWarningMessage(`Unable to open diff`);
|
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);
|
||||||
|
|
||||||
const commit = Iterables.find(log.commits.values(), c => c.sha === commitPick.commit.sha);
|
if (filePick) {
|
||||||
|
const log = await this.git.getLogForFile(filePick.uri.fsPath);
|
||||||
|
if (!log) return window.showWarningMessage(`Unable to open diff`);
|
||||||
|
|
||||||
let command: Commands | undefined = Commands.DiffWithWorking;
|
const commit = Iterables.find(log.commits.values(), c => c.sha === commitPick.commit.sha);
|
||||||
if (commit.previousSha) {
|
|
||||||
const items: CompareQuickPickItem[] = [
|
|
||||||
{
|
|
||||||
label: `Compare with Working Tree`,
|
|
||||||
description: `\u2022 ${commit.sha} $(git-compare) ${commit.fileName}`,
|
|
||||||
detail: null,
|
|
||||||
command: Commands.DiffWithWorking
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: `Compare with Previous Commit`,
|
|
||||||
description: `\u2022 ${commit.previousSha} $(git-compare) ${commit.sha}`,
|
|
||||||
detail: null,
|
|
||||||
command: Commands.DiffWithPrevious
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const comparePick = await window.showQuickPick(items, <QuickPickOptions>{
|
let command: Commands | undefined = Commands.DiffWithWorking;
|
||||||
matchOnDescription: true,
|
if (commit.previousSha) {
|
||||||
placeHolder: `${commit.fileName} \u2022 ${commit.sha} \u2022 ${commit.author}, ${moment(commit.date).fromNow()}`
|
const items: CompareQuickPickItem[] = [
|
||||||
});
|
{
|
||||||
|
label: `Compare with Working Tree`,
|
||||||
|
description: `\u2022 ${commit.sha} $(git-compare) ${commit.fileName}`,
|
||||||
|
detail: null,
|
||||||
|
command: Commands.DiffWithWorking
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: `Compare with Previous Commit`,
|
||||||
|
description: `\u2022 ${commit.previousSha} $(git-compare) ${commit.sha}`,
|
||||||
|
detail: null,
|
||||||
|
command: Commands.DiffWithPrevious
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
command = comparePick ? comparePick.command : undefined;
|
const comparePick = await window.showQuickPick(items, {
|
||||||
}
|
matchOnDescription: true,
|
||||||
|
placeHolder: `${commit.fileName} \u2022 ${commit.sha} \u2022 ${commit.author}, ${moment(commit.date).fromNow()}`
|
||||||
|
} as QuickPickOptions);
|
||||||
|
|
||||||
if (command) {
|
command = comparePick ? comparePick.command : undefined;
|
||||||
return commands.executeCommand(command, commit.uri, commit);
|
}
|
||||||
}
|
|
||||||
|
if (command) {
|
||||||
|
return commands.executeCommand(command, commit.uri, commit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ export interface IAdvancedConfig {
|
|||||||
};
|
};
|
||||||
debug: boolean;
|
debug: boolean;
|
||||||
git: string;
|
git: string;
|
||||||
|
maxQuickHistory: number;
|
||||||
output: {
|
output: {
|
||||||
level: OutputLevel;
|
level: OutputLevel;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ export * from './enrichers/logParserEnricher';
|
|||||||
let git: IGit;
|
let git: IGit;
|
||||||
const UncommittedRegex = /^[0]+$/;
|
const UncommittedRegex = /^[0]+$/;
|
||||||
|
|
||||||
|
const DefaultLogParams = [`log`, `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`];
|
||||||
|
|
||||||
async function gitCommand(cwd: string, ...args: any[]) {
|
async function gitCommand(cwd: string, ...args: any[]) {
|
||||||
try {
|
try {
|
||||||
const s = await spawnPromise(git.path, args, { cwd: cwd });
|
const s = await spawnPromise(git.path, args, { cwd: cwd });
|
||||||
@@ -65,68 +67,84 @@ export default class Git {
|
|||||||
static blame(format: GitBlameFormat, fileName: string, sha?: string, repoPath?: string) {
|
static blame(format: GitBlameFormat, fileName: string, sha?: string, repoPath?: string) {
|
||||||
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
||||||
|
|
||||||
|
const params = [`blame`, `--root`, format];
|
||||||
if (sha) {
|
if (sha) {
|
||||||
return gitCommand(root, 'blame', format, '--root', `${sha}^!`, '--', file);
|
params.push(`${sha}^!`);
|
||||||
}
|
}
|
||||||
return gitCommand(root, 'blame', format, '--root', '--', file);
|
|
||||||
|
return gitCommand(root, ...params, `--`, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static blameLines(format: GitBlameFormat, fileName: string, startLine: number, endLine: number, sha?: string, repoPath?: string) {
|
static blameLines(format: GitBlameFormat, fileName: string, startLine: number, endLine: number, sha?: string, repoPath?: string) {
|
||||||
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
||||||
|
|
||||||
|
const params = [`blame`, `--root`, format, `-L ${startLine},${endLine}`];
|
||||||
if (sha) {
|
if (sha) {
|
||||||
return gitCommand(root, 'blame', `-L ${startLine},${endLine}`, format, '--root', `${sha}^!`, '--', file);
|
params.push(`${sha}^!`);
|
||||||
}
|
}
|
||||||
return gitCommand(root, 'blame', `-L ${startLine},${endLine}`, format, '--root', '--', file);
|
|
||||||
|
return gitCommand(root, ...params, `--`, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static log(fileName: string, sha?: string, repoPath?: string) {
|
static log(fileName: string, sha?: string, repoPath?: string, maxCount?: number) {
|
||||||
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
||||||
|
|
||||||
if (sha) {
|
const params = [...DefaultLogParams, `--follow`];
|
||||||
return gitCommand(root, 'log', `--follow`, `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, `origin..${sha}`, '--', file);
|
if (maxCount) {
|
||||||
|
params.push(`-n${maxCount}`);
|
||||||
}
|
}
|
||||||
return gitCommand(root, 'log', `--follow`, `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, file);
|
if (sha) {
|
||||||
|
params.push(`origin..${sha}`);
|
||||||
|
params.push(`--`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gitCommand(root, ...params, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static logMostRecent(fileName: string, repoPath?: string) {
|
static logRange(fileName: string, start: number, end: number, sha?: string, repoPath?: string, maxCount?: number) {
|
||||||
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName, repoPath));
|
|
||||||
|
|
||||||
return gitCommand(root, 'log', `-n1`, `--follow`, `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
static logRange(fileName: string, start: number, end: number, sha?: string, repoPath?: string) {
|
|
||||||
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
||||||
|
|
||||||
if (sha) {
|
const params = [...DefaultLogParams];
|
||||||
return gitCommand(root, 'log', `--follow`, `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, `origin..${sha}`, `-L ${start},${end}:${file}`);
|
if (maxCount) {
|
||||||
|
params.push(`-n${maxCount}`);
|
||||||
}
|
}
|
||||||
return gitCommand(root, 'log', `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`, `-L ${start},${end}:${file}`);
|
if (sha) {
|
||||||
|
params.push(`--follow`);
|
||||||
|
params.push(`origin..${sha}`);
|
||||||
|
}
|
||||||
|
params.push(`-L ${start},${end}:${file}`);
|
||||||
|
|
||||||
|
return gitCommand(root, ...params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static logRepo(repoPath: string) {
|
static logRepo(repoPath: string, maxCount?: number) {
|
||||||
return gitCommand(repoPath, 'log', `--name-only`, `--no-merges`, `--date=iso8601-strict`, `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nsummary %s%nfilename ?`);
|
const params = [...DefaultLogParams];
|
||||||
|
if (maxCount) {
|
||||||
|
params.push(`-n${maxCount}`);
|
||||||
|
}
|
||||||
|
return gitCommand(repoPath, ...params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getVersionedFile(fileName: string, repoPath: string, sha: string) {
|
static getVersionedFile(fileName: string, repoPath: string, sha: string) {
|
||||||
return new Promise<string>((resolve, reject) => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
Git.getVersionedFileText(fileName, repoPath, sha).then(data => {
|
Git.getVersionedFileText(fileName, repoPath, sha).then(data => {
|
||||||
const ext = path.extname(fileName);
|
const ext = path.extname(fileName);
|
||||||
tmp.file({ prefix: `${path.basename(fileName, ext)}-${sha}__`, postfix: ext }, (err, destination, fd, cleanupCallback) => {
|
tmp.file({ prefix: `${path.basename(fileName, ext)}-${sha}__`, postfix: ext },
|
||||||
if (err) {
|
(err, destination, fd, cleanupCallback) => {
|
||||||
reject(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.log(`getVersionedFile(${fileName}, ${repoPath}, ${sha}); destination=${destination}`);
|
|
||||||
fs.appendFile(destination, data, err => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resolve(destination);
|
|
||||||
|
Logger.log(`getVersionedFile(${fileName}, ${repoPath}, ${sha}); destination=${destination}`);
|
||||||
|
fs.appendFile(destination, data, err => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(destination);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -135,7 +153,7 @@ export default class Git {
|
|||||||
const [file, root] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
const [file, root] = Git.splitPath(Git.normalizePath(fileName), repoPath);
|
||||||
sha = sha.replace('^', '');
|
sha = sha.replace('^', '');
|
||||||
|
|
||||||
if (Git.isUncommitted(sha)) return new Promise<string>((resolve, reject) => reject(new Error(`sha=${sha} is uncommitted`)));
|
if (Git.isUncommitted(sha)) return Promise.reject(new Error(`sha=${sha} is uncommitted`));
|
||||||
return gitCommand(root, 'show', `${sha}:./${file}`);
|
return gitCommand(root, 'show', `${sha}:./${file}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export default class GitProvider extends Disposable {
|
|||||||
private _cacheDisposable: Disposable | undefined;
|
private _cacheDisposable: Disposable | undefined;
|
||||||
private _uriCache: Map<string, UriCacheEntry> | undefined;
|
private _uriCache: Map<string, UriCacheEntry> | undefined;
|
||||||
|
|
||||||
private _config: IConfig;
|
config: IConfig;
|
||||||
private _disposable: Disposable;
|
private _disposable: Disposable;
|
||||||
private _codeLensProviderDisposable: Disposable | undefined;
|
private _codeLensProviderDisposable: Disposable | undefined;
|
||||||
private _gitignore: Promise<ignore.Ignore>;
|
private _gitignore: Promise<ignore.Ignore>;
|
||||||
@@ -105,8 +105,8 @@ export default class GitProvider extends Disposable {
|
|||||||
private _onConfigure() {
|
private _onConfigure() {
|
||||||
const config = workspace.getConfiguration().get<IConfig>('gitlens');
|
const config = workspace.getConfiguration().get<IConfig>('gitlens');
|
||||||
|
|
||||||
const codeLensChanged = !Objects.areEquivalent(config.codeLens, this._config && this._config.codeLens);
|
const codeLensChanged = !Objects.areEquivalent(config.codeLens, this.config && this.config.codeLens);
|
||||||
const advancedChanged = !Objects.areEquivalent(config.advanced, this._config && this._config.advanced);
|
const advancedChanged = !Objects.areEquivalent(config.advanced, this.config && this.config.advanced);
|
||||||
|
|
||||||
if (codeLensChanged || advancedChanged) {
|
if (codeLensChanged || advancedChanged) {
|
||||||
Logger.log('CodeLens config changed; resetting CodeLens provider');
|
Logger.log('CodeLens config changed; resetting CodeLens provider');
|
||||||
@@ -148,7 +148,7 @@ export default class GitProvider extends Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getCacheEntryKey(fileName: string) {
|
private _getCacheEntryKey(fileName: string) {
|
||||||
@@ -216,7 +216,7 @@ export default class GitProvider extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getRepoPathFromFile(fileName: string): Promise<string | undefined> {
|
async getRepoPathFromFile(fileName: string): Promise<string | undefined> {
|
||||||
const log = await this.getMostRecentLogForFile(fileName);
|
const log = await this.getLogForFile(fileName, undefined, undefined, undefined, 1);
|
||||||
return log && log.repoPath;
|
return log && log.repoPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ export default class GitProvider extends Disposable {
|
|||||||
const promise = this._gitignore.then(ignore => {
|
const promise = this._gitignore.then(ignore => {
|
||||||
if (ignore && !ignore.filter([fileName]).length) {
|
if (ignore && !ignore.filter([fileName]).length) {
|
||||||
Logger.log(`Skipping blame; '${fileName}' is gitignored`);
|
Logger.log(`Skipping blame; '${fileName}' is gitignored`);
|
||||||
return <Promise<IGitBlame>>GitProvider.EmptyPromise;
|
return GitProvider.EmptyPromise as Promise<IGitBlame>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Git.blame(GitProvider.BlameFormat, fileName, sha, repoPath)
|
return Git.blame(GitProvider.BlameFormat, fileName, sha, repoPath)
|
||||||
@@ -252,14 +252,14 @@ export default class GitProvider extends Disposable {
|
|||||||
const msg = ex && ex.toString();
|
const msg = ex && ex.toString();
|
||||||
Logger.log(`Replace blame cache with empty promise for '${cacheKey}'`);
|
Logger.log(`Replace blame cache with empty promise for '${cacheKey}'`);
|
||||||
|
|
||||||
entry.blame = <ICachedBlame>{
|
entry.blame = {
|
||||||
//date: new Date(),
|
//date: new Date(),
|
||||||
item: GitProvider.EmptyPromise,
|
item: GitProvider.EmptyPromise,
|
||||||
errorMessage: msg
|
errorMessage: msg
|
||||||
};
|
} as ICachedBlame;
|
||||||
|
|
||||||
this._gitCache.set(cacheKey, entry);
|
this._gitCache.set(cacheKey, entry);
|
||||||
return <Promise<IGitBlame>>GitProvider.EmptyPromise;
|
return GitProvider.EmptyPromise as Promise<IGitBlame>;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
@@ -268,10 +268,10 @@ export default class GitProvider extends Disposable {
|
|||||||
if (useCaching) {
|
if (useCaching) {
|
||||||
Logger.log(`Add blame cache for '${cacheKey}'`);
|
Logger.log(`Add blame cache for '${cacheKey}'`);
|
||||||
|
|
||||||
entry.blame = <ICachedBlame>{
|
entry.blame = {
|
||||||
//date: new Date(),
|
//date: new Date(),
|
||||||
item: promise
|
item: promise
|
||||||
};
|
} as ICachedBlame;
|
||||||
|
|
||||||
this._gitCache.set(cacheKey, entry);
|
this._gitCache.set(cacheKey, entry);
|
||||||
}
|
}
|
||||||
@@ -288,11 +288,11 @@ export default class GitProvider extends Disposable {
|
|||||||
if (!blameLine) return undefined;
|
if (!blameLine) return undefined;
|
||||||
|
|
||||||
const commit = blame.commits.get(blameLine.sha);
|
const commit = blame.commits.get(blameLine.sha);
|
||||||
return <IGitBlameLine>{
|
return {
|
||||||
author: Object.assign({}, blame.authors.get(commit.author), { lineCount: commit.lines.length }),
|
author: Object.assign({}, blame.authors.get(commit.author), { lineCount: commit.lines.length }),
|
||||||
commit: commit,
|
commit: commit,
|
||||||
line: blameLine
|
line: blameLine
|
||||||
};
|
} as IGitBlameLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileName = Git.normalizePath(fileName);
|
fileName = Git.normalizePath(fileName);
|
||||||
@@ -306,11 +306,11 @@ export default class GitProvider extends Disposable {
|
|||||||
if (repoPath) {
|
if (repoPath) {
|
||||||
commit.repoPath = repoPath;
|
commit.repoPath = repoPath;
|
||||||
}
|
}
|
||||||
return <IGitBlameLine>{
|
return {
|
||||||
author: Iterables.first(blame.authors.values()),
|
author: Iterables.first(blame.authors.values()),
|
||||||
commit: commit,
|
commit: commit,
|
||||||
line: blame.lines[line]
|
line: blame.lines[line]
|
||||||
};
|
} as IGitBlameLine;
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -364,12 +364,12 @@ export default class GitProvider extends Disposable {
|
|||||||
.sort((a, b) => b.lineCount - a.lineCount)
|
.sort((a, b) => b.lineCount - a.lineCount)
|
||||||
.forEach(a => sortedAuthors.set(a.name, a));
|
.forEach(a => sortedAuthors.set(a.name, a));
|
||||||
|
|
||||||
return <IGitBlameLines>{
|
return {
|
||||||
authors: sortedAuthors,
|
authors: sortedAuthors,
|
||||||
commits: commits,
|
commits: commits,
|
||||||
lines: lines,
|
lines: lines,
|
||||||
allLines: blame.lines
|
allLines: blame.lines
|
||||||
};
|
} as IGitBlameLines;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBlameLocations(fileName: string, range: Range, sha?: string, repoPath?: string, selectedSha?: string, line?: number): Promise<Location[] | undefined> {
|
async getBlameLocations(fileName: string, range: Range, sha?: string, repoPath?: string, selectedSha?: string, line?: number): Promise<Location[] | undefined> {
|
||||||
@@ -395,10 +395,15 @@ export default class GitProvider extends Disposable {
|
|||||||
return locations;
|
return locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLogForRepo(repoPath: string): Promise<IGitLog | undefined> {
|
async getLogForRepo(repoPath: string, maxCount?: number): Promise<IGitLog | undefined> {
|
||||||
Logger.log(`getLogForRepo('${repoPath}')`);
|
Logger.log(`getLogForRepo('${repoPath}', ${maxCount})`);
|
||||||
|
|
||||||
|
if (maxCount == null) {
|
||||||
|
maxCount = this.config.advanced.maxQuickHistory || 0;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await Git.logRepo(repoPath);
|
const data = await Git.logRepo(repoPath, maxCount);
|
||||||
return new GitLogParserEnricher().enrich(data, repoPath, true);
|
return new GitLogParserEnricher().enrich(data, repoPath, true);
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
@@ -406,24 +411,11 @@ export default class GitProvider extends Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMostRecentLogForFile(fileName: string): Promise<IGitLog | undefined> {
|
getLogForFile(fileName: string, sha?: string, repoPath?: string, range?: Range, maxCount?: number): Promise<IGitLog | undefined> {
|
||||||
Logger.log(`getMostRecentLogForFile('${fileName}')`);
|
Logger.log(`getLogForFile('${fileName}', ${sha}, ${repoPath}, ${range && `[${range.start.line}, ${range.end.line}]`}, ${maxCount})`);
|
||||||
fileName = Git.normalizePath(fileName);
|
fileName = Git.normalizePath(fileName);
|
||||||
|
|
||||||
try {
|
const useCaching = this.UseGitCaching && !range && !maxCount;
|
||||||
const data = await Git.logMostRecent(fileName);
|
|
||||||
return new GitLogParserEnricher().enrich(data, fileName);
|
|
||||||
}
|
|
||||||
catch (ex) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getLogForFile(fileName: string, sha?: string, repoPath?: string, range?: Range): Promise<IGitLog | undefined> {
|
|
||||||
Logger.log(`getLogForFile('${fileName}', ${sha}, ${repoPath}, ${range && `[${range.start.line}, ${range.end.line}]`})`);
|
|
||||||
fileName = Git.normalizePath(fileName);
|
|
||||||
|
|
||||||
const useCaching = this.UseGitCaching && !range;
|
|
||||||
|
|
||||||
let cacheKey: string;
|
let cacheKey: string;
|
||||||
let entry: GitCacheEntry;
|
let entry: GitCacheEntry;
|
||||||
@@ -440,12 +432,12 @@ export default class GitProvider extends Disposable {
|
|||||||
const promise = this._gitignore.then(ignore => {
|
const promise = this._gitignore.then(ignore => {
|
||||||
if (ignore && !ignore.filter([fileName]).length) {
|
if (ignore && !ignore.filter([fileName]).length) {
|
||||||
Logger.log(`Skipping log; '${fileName}' is gitignored`);
|
Logger.log(`Skipping log; '${fileName}' is gitignored`);
|
||||||
return <Promise<IGitLog>>GitProvider.EmptyPromise;
|
return GitProvider.EmptyPromise as Promise<IGitLog>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (range
|
return (range
|
||||||
? Git.logRange(fileName, range.start.line + 1, range.end.line + 1, sha, repoPath)
|
? Git.logRange(fileName, range.start.line + 1, range.end.line + 1, sha, repoPath, maxCount)
|
||||||
: Git.log(fileName, sha, repoPath))
|
: Git.log(fileName, sha, repoPath, maxCount))
|
||||||
.then(data => new GitLogParserEnricher().enrich(data, fileName))
|
.then(data => new GitLogParserEnricher().enrich(data, fileName))
|
||||||
.catch(ex => {
|
.catch(ex => {
|
||||||
// Trap and cache expected log errors
|
// Trap and cache expected log errors
|
||||||
@@ -453,14 +445,14 @@ export default class GitProvider extends Disposable {
|
|||||||
const msg = ex && ex.toString();
|
const msg = ex && ex.toString();
|
||||||
Logger.log(`Replace log cache with empty promise for '${cacheKey}'`);
|
Logger.log(`Replace log cache with empty promise for '${cacheKey}'`);
|
||||||
|
|
||||||
entry.log = <ICachedLog>{
|
entry.log = {
|
||||||
//date: new Date(),
|
//date: new Date(),
|
||||||
item: GitProvider.EmptyPromise,
|
item: GitProvider.EmptyPromise,
|
||||||
errorMessage: msg
|
errorMessage: msg
|
||||||
};
|
} as ICachedLog;
|
||||||
|
|
||||||
this._gitCache.set(cacheKey, entry);
|
this._gitCache.set(cacheKey, entry);
|
||||||
return <Promise<IGitLog>>GitProvider.EmptyPromise;
|
return GitProvider.EmptyPromise as Promise<IGitLog>;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
@@ -469,10 +461,10 @@ export default class GitProvider extends Disposable {
|
|||||||
if (useCaching) {
|
if (useCaching) {
|
||||||
Logger.log(`Add log cache for '${cacheKey}'`);
|
Logger.log(`Add log cache for '${cacheKey}'`);
|
||||||
|
|
||||||
entry.log = <ICachedLog>{
|
entry.log = {
|
||||||
//date: new Date(),
|
//date: new Date(),
|
||||||
item: promise
|
item: promise
|
||||||
};
|
} as ICachedLog;
|
||||||
|
|
||||||
this._gitCache.set(cacheKey, entry);
|
this._gitCache.set(cacheKey, entry);
|
||||||
}
|
}
|
||||||
@@ -521,8 +513,8 @@ export default class GitProvider extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleCodeLens(editor: TextEditor) {
|
toggleCodeLens(editor: TextEditor) {
|
||||||
if (this._config.codeLens.visibility !== CodeLensVisibility.OnDemand ||
|
if (this.config.codeLens.visibility !== CodeLensVisibility.OnDemand ||
|
||||||
(!this._config.codeLens.recentChange.enabled && !this._config.codeLens.authors.enabled)) return;
|
(!this.config.codeLens.recentChange.enabled && !this.config.codeLens.authors.enabled)) return;
|
||||||
|
|
||||||
Logger.log(`toggleCodeLens(${editor})`);
|
Logger.log(`toggleCodeLens(${editor})`);
|
||||||
|
|
||||||
@@ -595,7 +587,7 @@ export class GitUri extends Uri {
|
|||||||
super();
|
super();
|
||||||
if (!uri) return;
|
if (!uri) return;
|
||||||
|
|
||||||
const base = <any>this;
|
const base = this as any;
|
||||||
base._scheme = uri.scheme;
|
base._scheme = uri.scheme;
|
||||||
base._authority = uri.authority;
|
base._authority = uri.authority;
|
||||||
base._path = uri.path;
|
base._path = uri.path;
|
||||||
|
|||||||
Reference in New Issue
Block a user