Fixes failure when filename changes in history

Removes CodeLens from fields and single-line properties to reduce visual noise
This commit is contained in:
Eric Amodio
2016-09-07 12:28:00 -04:00
parent 67e1a6b78f
commit 26ce5f7d53
7 changed files with 111 additions and 82 deletions

View File

@@ -29,6 +29,11 @@ None yet.
## Release Notes
### 0.0.5
Fixes issues where filename changes in history would cause diffs to fails
Removes CodeLens from fields and single-line properties to reduce visual noise
### 0.0.4
Candidate for preview release on the vscode marketplace.

View File

@@ -1,6 +1,6 @@
{
"name": "gitlens",
"version": "0.0.4",
"version": "0.0.5",
"author": "Eric Amodio",
"publisher": "eamodio",
"engines": {

View File

@@ -41,26 +41,22 @@ export class DiffWithPreviousCommand extends EditorCommand {
super(Commands.DiffWithPrevious);
}
execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, sha?: string, compareWithSha?: string, line?: number) {
execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, sha?: string, shaUri?: Uri, compareWithSha?: string, compareWithUri?: Uri, line?: number) {
line = line || editor.selection.active.line;
if (!sha) {
return this.git.getBlameForLine(uri.path, line)
.then(blame => commands.executeCommand(Commands.DiffWithPrevious, uri, blame.commit.sha, blame.commit.previousSha));
return this.git.getBlameForLine(uri.fsPath, line)
.then(blame => commands.executeCommand(Commands.DiffWithPrevious, uri, blame.commit.sha, blame.commit.toUri(), blame.commit.previousSha, blame.commit.toPreviousUri(), line));
}
if (!compareWithSha) {
return window.showInformationMessage(`Commit ${sha} has no previous commit`);
}
return Promise.all([this.git.getVersionedFile(uri.path, sha), this.git.getVersionedFile(uri.path, compareWithSha)])
.then(values => {
const [source, compare] = values;
const fileName = basename(uri.path);
return commands.executeCommand(BuiltInCommands.Diff, Uri.file(compare), Uri.file(source), `${fileName} (${compareWithSha}) ↔ ${fileName} (${sha})`)
// TODO: Moving doesn't always seem to work -- or more accurately it seems like it moves down that number of lines from the current line
// which for a diff could be the first difference
.then(() => commands.executeCommand(BuiltInCommands.CursorMove, { to: 'down', value: line }));
});
// TODO: Moving doesn't always seem to work -- or more accurately it seems like it moves down that number of lines from the current line
// which for a diff could be the first difference
return Promise.all([this.git.getVersionedFile(uri.fsPath, sha), this.git.getVersionedFile(uri.fsPath, compareWithSha)])
.then(values => commands.executeCommand(BuiltInCommands.Diff, Uri.file(values[1]), Uri.file(values[0]), `${basename(compareWithUri.fsPath)} (${compareWithSha}) ↔ ${basename(shaUri.fsPath)} (${sha})`)
.then(() => commands.executeCommand(BuiltInCommands.CursorMove, { to: 'down', value: line })));
}
}
@@ -69,20 +65,18 @@ export class DiffWithWorkingCommand extends EditorCommand {
super(Commands.DiffWithWorking);
}
execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, sha?: string, line?: number) {
execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, sha?: string, shaUri?: Uri, line?: number) {
line = line || editor.selection.active.line;
if (!sha) {
return this.git.getBlameForLine(uri.path, line)
.then(blame => commands.executeCommand(Commands.DiffWithWorking, uri, blame.commit.sha));
return this.git.getBlameForLine(uri.fsPath, line)
.then(blame => commands.executeCommand(Commands.DiffWithWorking, uri, blame.commit.sha, blame.commit.toUri(), line));
};
return this.git.getVersionedFile(uri.path, sha).then(compare => {
const fileName = basename(uri.path);
return commands.executeCommand(BuiltInCommands.Diff, Uri.file(compare), uri, `${fileName} (${sha}) ↔ ${fileName} (index)`)
// TODO: Moving doesn't always seem to work -- or more accurately it seems like it moves down that number of lines from the current line
// which for a diff could be the first difference
.then(() => commands.executeCommand(BuiltInCommands.CursorMove, { to: 'down', value: line }));
});
// TODO: Moving doesn't always seem to work -- or more accurately it seems like it moves down that number of lines from the current line
// which for a diff could be the first difference
return this.git.getVersionedFile(shaUri.fsPath, sha)
.then(compare => commands.executeCommand(BuiltInCommands.Diff, Uri.file(compare), uri, `${basename(shaUri.fsPath)} (${sha}) ↔ ${basename(uri.fsPath)} (index)`)
.then(() => commands.executeCommand(BuiltInCommands.CursorMove, { to: 'down', value: line })));
}
}
@@ -120,7 +114,7 @@ export class ShowBlameHistoryCommand extends EditorCommand {
if (!uri) return;
}
return this.git.getBlameLocations(uri.path, range).then(locations => {
return this.git.getBlameLocations(uri.fsPath, range).then(locations => {
return commands.executeCommand(BuiltInCommands.ShowReferences, uri, position, locations);
});
}

View File

@@ -9,7 +9,7 @@ import * as moment from 'moment';
const blameDecoration: TextEditorDecorationType = window.createTextEditorDecorationType({
before: {
color: '#5a5a5a',
margin: '0 1em 0 0',
margin: '0 1.75em 0 0',
width: '5em'
},
});
@@ -95,7 +95,7 @@ class GitBlameEditorController extends Disposable {
constructor(private context: ExtensionContext, private git: GitProvider, public editor: TextEditor) {
super(() => this.dispose());
const fileName = this.editor.document.uri.path;
const fileName = this.editor.document.uri.fsPath;
this._blame = this.git.getBlameForFile(fileName);
const subscriptions: Disposable[] = [];

View File

@@ -21,7 +21,11 @@ export default class GitCodeActionProvider implements CodeActionProvider {
actions.push({
title: `GitLens: Diff ${blame.commit.sha} with working tree`,
command: Commands.DiffWithWorking,
arguments: [Uri.file(document.fileName), blame.commit.sha, blame.line.line]
arguments: [
Uri.file(document.fileName),
blame.commit.sha, blame.commit.toUri(),
blame.line.line
]
});
}
@@ -29,7 +33,12 @@ export default class GitCodeActionProvider implements CodeActionProvider {
actions.push({
title: `GitLens: Diff ${blame.commit.sha} with previous ${blame.commit.previousSha}`,
command: Commands.DiffWithPrevious,
arguments: [Uri.file(document.fileName), blame.commit.sha, blame.commit.previousSha, blame.line.line]
arguments: [
Uri.file(document.fileName),
blame.commit.sha, blame.commit.toUri(),
blame.commit.previousSha, blame.commit.toPreviousUri(),
blame.line.line
]
});
}

View File

@@ -5,7 +5,7 @@ import GitProvider, {IGitBlame, IGitBlameLines, IGitCommit} from './gitProvider'
import * as moment from 'moment';
export class GitRecentChangeCodeLens extends CodeLens {
constructor(private git: GitProvider, public fileName: string, public blameRange: Range, range: Range) {
constructor(private git: GitProvider, public fileName: string, public symbolKind: SymbolKind, public blameRange: Range, range: Range) {
super(range);
}
@@ -15,7 +15,7 @@ export class GitRecentChangeCodeLens extends CodeLens {
}
export class GitBlameCodeLens extends CodeLens {
constructor(private git: GitProvider, public fileName: string, public blameRange: Range, range: Range) {
constructor(private git: GitProvider, public fileName: string, public symbolKind: SymbolKind, public blameRange: Range, range: Range) {
super(range);
}
@@ -54,8 +54,8 @@ export default class GitCodeLensProvider implements CodeLensProvider {
// Check if we have a lens for the whole document -- if not add one
if (!lenses.find(l => l.range.start.line === 0 && l.range.end.line === 0)) {
const blameRange = document.validateRange(new Range(0, 1000000, 1000000, 1000000));
lenses.push(new GitRecentChangeCodeLens(this.git, fileName, blameRange, new Range(0, 0, 0, blameRange.start.character)));
lenses.push(new GitBlameCodeLens(this.git, fileName, blameRange, new Range(0, 1, 0, blameRange.start.character)));
lenses.push(new GitRecentChangeCodeLens(this.git, fileName, SymbolKind.File, blameRange, new Range(0, 0, 0, blameRange.start.character)));
lenses.push(new GitBlameCodeLens(this.git, fileName, SymbolKind.File, blameRange, new Range(0, 1, 0, blameRange.start.character)));
// if (this.hasGitHistoryExtension) {
// lenses.push(new GitHistoryCodeLens(this.git.repoPath, fileName, new Range(0, 1, 0, blameRange.start.character)));
// }
@@ -65,6 +65,8 @@ export default class GitCodeLensProvider implements CodeLensProvider {
});
}
foo: string; bar: number;
private _provideCodeLens(fileName: string, document: TextDocument, symbol: SymbolInformation, lenses: CodeLens[]): void {
let multiline = false;
switch (symbol.kind) {
@@ -76,19 +78,19 @@ export default class GitCodeLensProvider implements CodeLensProvider {
case SymbolKind.Method:
case SymbolKind.Function:
case SymbolKind.Enum:
multiline = true;
// HACK for Omnisharp, since it doesn't return full ranges
multiline = fileName.endsWith('.cs') || (symbol.location.range.end.line - symbol.location.range.start.line) > 1;
break;
case SymbolKind.Property:
multiline = (symbol.location.range.end.line - symbol.location.range.start.line) > 1;
break;
case SymbolKind.Field:
multiline = false;
if (!multiline) return;
break;
default:
return;
}
const line = document.lineAt(symbol.location.range.start);
// Make sure there is only 1 lense per line
if (lenses.length && lenses[lenses.length - 1].range.start.line === line.lineNumber) {
return;
}
@@ -100,10 +102,10 @@ export default class GitCodeLensProvider implements CodeLensProvider {
startChar += Math.floor(symbol.name.length / 2);
}
lenses.push(new GitRecentChangeCodeLens(this.git, fileName, symbol.location.range, line.range.with(new Position(line.range.start.line, startChar))));
lenses.push(new GitRecentChangeCodeLens(this.git, fileName, symbol.kind, symbol.location.range, line.range.with(new Position(line.range.start.line, startChar))));
startChar++;
if (multiline) {
lenses.push(new GitBlameCodeLens(this.git, fileName, symbol.location.range, line.range.with(new Position(line.range.start.line, startChar))));
lenses.push(new GitBlameCodeLens(this.git, fileName, symbol.kind, symbol.location.range, line.range.with(new Position(line.range.start.line, startChar))));
startChar++;
}
// if (this.hasGitHistoryExtension) {
@@ -121,7 +123,7 @@ export default class GitCodeLensProvider implements CodeLensProvider {
return lens.getBlame().then(blame => {
const recentCommit = blame.commits.values().next().value;
lens.command = {
title: `${recentCommit.author}, ${moment(recentCommit.date).fromNow()}`, // - lines(${lens.blameRange.start.line + 1}-${lens.blameRange.end.line + 1})`,
title: `${recentCommit.author}, ${moment(recentCommit.date).fromNow()}`, // - ${SymbolKind[lens.symbolKind]}(${lens.blameRange.start.line + 1}-${lens.blameRange.end.line + 1})`,
command: Commands.ShowBlameHistory,
arguments: [Uri.file(lens.fileName), lens.blameRange, lens.range.start]
};

View File

@@ -3,7 +3,7 @@ import {Disposable, ExtensionContext, languages, Location, Position, Range, Uri,
import {DocumentSchemes, WorkspaceState} from './constants';
import GitCodeLensProvider from './gitCodeLensProvider';
import Git from './git';
import {basename, dirname, extname} from 'path';
import {basename, dirname, extname, join} from 'path';
import * as moment from 'moment';
import * as _ from 'lodash';
@@ -97,14 +97,7 @@ export default class GitProvider extends Disposable {
authors.set(authorName, author);
}
commit = {
sha,
fileName: fileName,
author: authorName,
date: moment(`${m[7]} ${m[8]}`, 'X Z').toDate(),
message: m[13],
lines: []
};
commit = new GitCommit(this.repoPath, sha, fileName, authorName, moment(`${m[7]} ${m[8]}`, 'X Z').toDate(), m[13]);
const originalFileName = m[16];
if (!fileName.toLowerCase().endsWith(originalFileName.toLowerCase())) {
@@ -231,9 +224,9 @@ export default class GitProvider extends Disposable {
const locations: Array<Location> = [];
Array.from(blame.commits.values())
.forEach((c, i) => {
const uri = this.toBlameUri(c, i + 1, commitCount, range);
const uri = c.toBlameUri(i + 1, commitCount, range);
c.lines.forEach(l => locations.push(new Location(c.originalFileName
? this.toBlameUri(c, i + 1, commitCount, range, c.originalFileName)
? c.toBlameUri(i + 1, commitCount, range, c.originalFileName)
: uri,
new Position(l.originalLine, 0))));
});
@@ -299,38 +292,6 @@ export default class GitProvider extends Disposable {
private _fromGitUri<T extends IGitUriData>(uri: Uri): T {
return JSON.parse(uri.query) as T;
}
toBlameUri(commit: IGitCommit, index: number, commitCount: number, range: Range, originalFileName?: string) {
return this._toGitUri(DocumentSchemes.GitBlame, commit, commitCount, this._toGitBlameUriData(commit, index, range, originalFileName));
}
toGitUri(commit: IGitCommit, index: number, commitCount: number, originalFileName?: string) {
return this._toGitUri(DocumentSchemes.Git, commit, commitCount, this._toGitUriData(commit, index, originalFileName));
}
private _toGitUri(scheme: DocumentSchemes, commit: IGitCommit, commitCount: number, data: IGitUriData | IGitBlameUriData) {
const pad = n => ("0000000" + n).slice(-("" + commitCount).length);
const ext = extname(data.fileName);
const path = `${dirname(data.fileName)}/${commit.sha}: ${basename(data.fileName, ext)}${ext}`;
// NOTE: Need to specify an index here, since I can't control the sort order -- just alphabetic or by file location
return Uri.parse(`${scheme}:${pad(data.index)}. ${commit.author}, ${moment(commit.date).format('MMM D, YYYY hh:MM a')} - ${path}?${JSON.stringify(data)}`);
}
private _toGitUriData<T extends IGitUriData>(commit: IGitCommit, index: number, originalFileName?: string): T {
const fileName = originalFileName || commit.fileName;
const data = { fileName: commit.fileName, sha: commit.sha, index: index } as T;
if (originalFileName) {
data.originalFileName = originalFileName;
}
return data;
}
private _toGitBlameUriData(commit: IGitCommit, index: number, range: Range, originalFileName?: string) {
const data = this._toGitUriData<IGitBlameUriData>(commit, index, originalFileName);
data.range = range;
return data;
}
}
export interface IGitBlame {
@@ -370,6 +331,64 @@ export interface IGitCommit {
originalFileName?: string;
previousSha?: string;
previousFileName?: string;
toPreviousUri(): Uri;
toUri(): Uri;
toBlameUri(index: number, commitCount: number, range: Range, originalFileName?: string);
toGitUri(index: number, commitCount: number, originalFileName?: string);
}
class GitCommit implements IGitCommit {
lines: IGitCommitLine[];
originalFileName?: string;
previousSha?: string;
previousFileName?: string;
constructor(private repoPath: string, public sha: string, public fileName: string, public author: string, public date: Date, public message: string) {
this.lines = [];
}
toPreviousUri(): Uri {
return this.previousFileName ? Uri.file(join(this.repoPath, this.previousFileName)) : this.toUri();
}
toUri(): Uri {
return Uri.file(join(this.repoPath, this.originalFileName || this.fileName));
}
toBlameUri(index: number, commitCount: number, range: Range, originalFileName?: string) {
return this._toGitUri(DocumentSchemes.GitBlame, commitCount, this._toGitBlameUriData(index, range, originalFileName));
}
toGitUri(index: number, commitCount: number, originalFileName?: string) {
return this._toGitUri(DocumentSchemes.Git, commitCount, this._toGitUriData(index, originalFileName));
}
private _toGitUri(scheme: DocumentSchemes, commitCount: number, data: IGitUriData | IGitBlameUriData) {
const pad = n => ("0000000" + n).slice(-("" + commitCount).length);
const ext = extname(data.fileName);
// const path = `${dirname(data.fileName)}/${commit.sha}: ${basename(data.fileName, ext)}${ext}`;
const path = `${dirname(data.fileName)}/${this.sha}${ext}`;
// NOTE: Need to specify an index here, since I can't control the sort order -- just alphabetic or by file location
return Uri.parse(`${scheme}:${pad(data.index)}. ${this.author}, ${moment(this.date).format('MMM D, YYYY hh:MM a')} - ${path}?${JSON.stringify(data)}`);
}
private _toGitUriData<T extends IGitUriData>(index: number, originalFileName?: string): T {
const fileName = originalFileName || this.fileName;
const data = { fileName: this.fileName, sha: this.sha, index: index } as T;
if (originalFileName) {
data.originalFileName = originalFileName;
}
return data;
}
private _toGitBlameUriData(index: number, range: Range, originalFileName?: string) {
const data = this._toGitUriData<IGitBlameUriData>(index, originalFileName);
data.range = range;
return data;
}
}
export interface IGitCommitLine {