mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-01-17 09:45:36 -05:00
Fixes failure when filename changes in history
Removes CodeLens from fields and single-line properties to reduce visual noise
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitlens",
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.5",
|
||||
"author": "Eric Amodio",
|
||||
"publisher": "eamodio",
|
||||
"engines": {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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[] = [];
|
||||
|
||||
@@ -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
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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]
|
||||
};
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user