mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-02-16 10:58:34 -05:00
Adds more protection for uncommitted lines
Adds better uncommitted hover message in blame annotations
This commit is contained in:
11
README.md
11
README.md
@@ -56,17 +56,22 @@ Must be using Git and it must be in your path.
|
|||||||
---
|
---
|
||||||
## Release Notes
|
## Release Notes
|
||||||
|
|
||||||
|
### 0.5.3
|
||||||
|
|
||||||
|
- Adds better uncommitted hover message in blame annotations
|
||||||
|
- Adds more protection for dealing with uncommitted lines
|
||||||
|
|
||||||
### 0.5.2
|
### 0.5.2
|
||||||
|
|
||||||
- Fixes loading issue on Linux
|
- Fixes loading issue on Linux
|
||||||
|
|
||||||
### 0.5.1
|
### 0.5.1
|
||||||
|
|
||||||
- Adds blame information in the statusBar
|
- Adds blame information in the statusBar
|
||||||
- Add new StatusBar settings -- see **Extension Settings** above for details
|
- Add new StatusBar settings -- see **Extension Settings** above for details
|
||||||
- Renames the `gitlens.codeLens.recentChange.command` & `gitlens.codeLens.authors.command` settings options (to align with command names)
|
- Renames the `gitlens.codeLens.recentChange.command` & `gitlens.codeLens.authors.command` settings options (to align with command names)
|
||||||
- Adds new `gitlens.diffWithPrevious` option to the `gitlens.codeLens.recentChange.command` & `gitlens.codeLens.authors.command` settings
|
- Adds new `gitlens.diffWithPrevious` option to the `gitlens.codeLens.recentChange.command` & `gitlens.codeLens.authors.command` settings
|
||||||
- Fixes Diff with Previous when the selection is uncommited
|
- Fixes Diff with Previous when the selection is uncommitted
|
||||||
- Removes `gitlens.blame.annotation.useCodeActions` setting and behavior
|
- Removes `gitlens.blame.annotation.useCodeActions` setting and behavior
|
||||||
|
|
||||||
### 0.3.3
|
### 0.3.3
|
||||||
@@ -111,7 +116,7 @@ Must be using Git and it must be in your path.
|
|||||||
### 0.0.5
|
### 0.0.5
|
||||||
|
|
||||||
- Fixes issues where filename changes in history would cause diffs to fails
|
- Fixes issues where filename changes in history would cause diffs to fails
|
||||||
- Fixes some issues with uncommited blames
|
- Fixes some issues with uncommitted blames
|
||||||
- Removes CodeLens from fields and single-line properties to reduce visual noise
|
- Removes CodeLens from fields and single-line properties to reduce visual noise
|
||||||
- Automatically turns off blame only when required now
|
- Automatically turns off blame only when required now
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gitlens",
|
"name": "gitlens",
|
||||||
"version": "0.5.2",
|
"version": "0.5.3",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Eric Amodio",
|
"name": "Eric Amodio",
|
||||||
"email": "eamodio@gmail.com"
|
"email": "eamodio@gmail.com"
|
||||||
|
|||||||
@@ -178,11 +178,17 @@ class EditorBlameAnnotationController extends Disposable {
|
|||||||
return blame.lines.map(l => {
|
return blame.lines.map(l => {
|
||||||
let color = l.previousSha ? '#999999' : '#6b6b6b';
|
let color = l.previousSha ? '#999999' : '#6b6b6b';
|
||||||
let commit = blame.commits.get(l.sha);
|
let commit = blame.commits.get(l.sha);
|
||||||
let hoverMessage: string | Array<string> = [`_${l.sha}_: ${commit.message}`, `${commit.author}, ${moment(commit.date).format('MMMM Do, YYYY hh:MM a')}`];
|
let hoverMessage: string | Array<string> = [`_${l.sha}_ - ${commit.message}`, `${commit.author}, ${moment(commit.date).format('MMMM Do, YYYY h:MM a')}`];
|
||||||
|
|
||||||
if (l.sha.startsWith('00000000')) {
|
if (commit.isUncommitted) {
|
||||||
color = 'rgba(0, 188, 242, 0.6)';
|
color = 'rgba(0, 188, 242, 0.6)';
|
||||||
hoverMessage = '';
|
|
||||||
|
let previous = blame.commits.get(commit.previousSha);
|
||||||
|
if (previous) {
|
||||||
|
hoverMessage = ['Uncommitted changes', `_${previous.sha}_ - ${previous.message}`, `${previous.author}, ${moment(previous.date).format('MMMM Do, YYYY h:MM a')}`];
|
||||||
|
} else {
|
||||||
|
hoverMessage = ['Uncommitted changes', `_${l.previousSha}_`];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let gutter = '';
|
let gutter = '';
|
||||||
@@ -212,7 +218,7 @@ class EditorBlameAnnotationController extends Disposable {
|
|||||||
|
|
||||||
return <DecorationOptions>{
|
return <DecorationOptions>{
|
||||||
range: this.editor.document.validateRange(new Range(l.line, 0, l.line, 0)),
|
range: this.editor.document.validateRange(new Range(l.line, 0, l.line, 0)),
|
||||||
hoverMessage: [`_${l.sha}_: ${commit.message}`, `${commit.author}, ${moment(commit.date).format('MMMM Do, YYYY hh:MM a')}`],
|
hoverMessage: hoverMessage,
|
||||||
renderOptions: { before: { color: color, contentText: gutter, width: '11em' } }
|
renderOptions: { before: { color: color, contentText: gutter, width: '11em' } }
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -243,11 +249,17 @@ class EditorBlameAnnotationController extends Disposable {
|
|||||||
return blame.lines.map(l => {
|
return blame.lines.map(l => {
|
||||||
let color = l.previousSha ? '#999999' : '#6b6b6b';
|
let color = l.previousSha ? '#999999' : '#6b6b6b';
|
||||||
let commit = blame.commits.get(l.sha);
|
let commit = blame.commits.get(l.sha);
|
||||||
let hoverMessage: string | Array<string> = [commit.message, `${commit.author}, ${moment(commit.date).format('MMMM Do, YYYY hh:MM a')}`];
|
let hoverMessage: string | Array<string> = [`_${l.sha}_ - ${commit.message}`, `${commit.author}, ${moment(commit.date).format('MMMM Do, YYYY h:MM a')}`];
|
||||||
|
|
||||||
if (l.sha.startsWith('00000000')) {
|
if (commit.isUncommitted) {
|
||||||
color = 'rgba(0, 188, 242, 0.6)';
|
color = 'rgba(0, 188, 242, 0.6)';
|
||||||
hoverMessage = '';
|
|
||||||
|
let previous = blame.commits.get(commit.previousSha);
|
||||||
|
if (previous) {
|
||||||
|
hoverMessage = ['Uncommitted changes', `_${previous.sha}_ - ${previous.message}`, `${previous.author}, ${moment(previous.date).format('MMMM Do, YYYY h:MM a')}`];
|
||||||
|
} else {
|
||||||
|
hoverMessage = ['Uncommitted changes', `_${l.previousSha}_`];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const gutter = this._getGutter(commit);
|
const gutter = this._getGutter(commit);
|
||||||
@@ -261,10 +273,11 @@ class EditorBlameAnnotationController extends Disposable {
|
|||||||
|
|
||||||
private _getAuthor(commit: IGitCommit, max: number = 17, force: boolean = false) {
|
private _getAuthor(commit: IGitCommit, max: number = 17, force: boolean = false) {
|
||||||
if (!force && !this._config.annotation.author) return '';
|
if (!force && !this._config.annotation.author) return '';
|
||||||
if (commit.author.length > max) {
|
let author = commit.isUncommitted ? 'Uncommitted': commit.author;
|
||||||
return `${commit.author.substring(0, max - 1)}\\2026`;
|
if (author.length > max) {
|
||||||
|
return `${author.substring(0, max - 1)}\\2026`;
|
||||||
}
|
}
|
||||||
return commit.author;
|
return author;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getDate(commit: IGitCommit, force?: boolean) {
|
private _getDate(commit: IGitCommit, force?: boolean) {
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ export class DiffWithPreviousCommand extends EditorCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, repoPath?: string, sha?: string, shaUri?: Uri, compareWithSha?: string, compareWithUri?: Uri, line?: number) {
|
execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, repoPath?: string, sha?: string, shaUri?: Uri, compareWithSha?: string, compareWithUri?: Uri, line?: number) {
|
||||||
line = line || editor.selection.active.line;
|
line = line || editor.selection.active.line + 1;
|
||||||
if (!sha) {
|
if (!sha || GitProvider.isUncommitted(sha)) {
|
||||||
if (!(uri instanceof Uri)) {
|
if (!(uri instanceof Uri)) {
|
||||||
if (!editor.document) return;
|
if (!editor.document) return;
|
||||||
uri = editor.document.uri;
|
uri = editor.document.uri;
|
||||||
@@ -56,8 +56,8 @@ export class DiffWithPreviousCommand extends EditorCommand {
|
|||||||
|
|
||||||
// If the line is uncommitted, find the previous commit
|
// If the line is uncommitted, find the previous commit
|
||||||
const commit = blame.commit;
|
const commit = blame.commit;
|
||||||
if (GitProvider.isUncommitted(commit.sha)) {
|
if (commit.isUncommitted) {
|
||||||
return this.git.getBlameForLine(commit.previousUri.fsPath, blame.line.originalLine, commit.previousSha, commit.repoPath)
|
return this.git.getBlameForLine(commit.previousUri.fsPath, blame.line.originalLine + 1, commit.previousSha, commit.repoPath)
|
||||||
.catch(ex => console.error('[GitLens.DiffWithPreviousCommand]', `getBlameForLine(${blame.line.originalLine}, ${commit.previousSha})`, ex))
|
.catch(ex => console.error('[GitLens.DiffWithPreviousCommand]', `getBlameForLine(${blame.line.originalLine}, ${commit.previousSha})`, ex))
|
||||||
.then(prevBlame => {
|
.then(prevBlame => {
|
||||||
if (!prevBlame) return;
|
if (!prevBlame) return;
|
||||||
@@ -87,8 +87,8 @@ export class DiffWithWorkingCommand extends EditorCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, repoPath?: string, sha?: string, shaUri?: Uri, line?: number) {
|
execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, repoPath?: string, sha?: string, shaUri?: Uri, line?: number) {
|
||||||
line = line || editor.selection.active.line;
|
line = line || editor.selection.active.line + 1;
|
||||||
if (!sha) {
|
if (!sha || GitProvider.isUncommitted(sha)) {
|
||||||
if (!(uri instanceof Uri)) {
|
if (!(uri instanceof Uri)) {
|
||||||
if (!editor.document) return;
|
if (!editor.document) return;
|
||||||
uri = editor.document.uri;
|
uri = editor.document.uri;
|
||||||
@@ -101,8 +101,8 @@ export class DiffWithWorkingCommand extends EditorCommand {
|
|||||||
|
|
||||||
const commit = blame.commit;
|
const commit = blame.commit;
|
||||||
// If the line is uncommitted, find the previous commit
|
// If the line is uncommitted, find the previous commit
|
||||||
if (GitProvider.isUncommitted(commit.sha)) {
|
if (commit.isUncommitted) {
|
||||||
return commands.executeCommand(Commands.DiffWithWorking, commit.uri, commit.repoPath, commit.previousSha, commit.previousUri, blame.line.line);
|
return commands.executeCommand(Commands.DiffWithWorking, commit.uri, commit.repoPath, commit.previousSha, commit.previousUri, blame.line.line + 1);
|
||||||
}
|
}
|
||||||
return commands.executeCommand(Commands.DiffWithWorking, commit.uri, commit.repoPath, commit.sha, commit.uri, line)
|
return commands.executeCommand(Commands.DiffWithWorking, commit.uri, commit.repoPath, commit.sha, commit.uri, line)
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {spawnPromise} from 'spawn-rx';
|
|||||||
export * from './gitEnrichment';
|
export * from './gitEnrichment';
|
||||||
export * from './enrichers/blameParserEnricher';
|
export * from './enrichers/blameParserEnricher';
|
||||||
|
|
||||||
const UncommitedRegex = /^[0]+$/;
|
const UncommittedRegex = /^[0]+$/;
|
||||||
|
|
||||||
function gitCommand(cwd: string, ...args) {
|
function gitCommand(cwd: string, ...args) {
|
||||||
return spawnPromise('git', args, { cwd: cwd })
|
return spawnPromise('git', args, { cwd: cwd })
|
||||||
@@ -99,10 +99,11 @@ 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`)));
|
||||||
return gitCommand(root, 'show', `${sha}:./${file}`);
|
return gitCommand(root, 'show', `${sha}:./${file}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isUncommitted(sha: string) {
|
static isUncommitted(sha: string) {
|
||||||
return UncommitedRegex.test(sha);
|
return UncommittedRegex.test(sha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
import {Uri} from 'vscode';
|
import {Uri} from 'vscode';
|
||||||
|
import Git from './git';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
export interface IGitEnricher<T> {
|
export interface IGitEnricher<T> {
|
||||||
@@ -46,6 +47,7 @@ export interface IGitCommit {
|
|||||||
previousSha?: string;
|
previousSha?: string;
|
||||||
previousFileName?: string;
|
previousFileName?: string;
|
||||||
|
|
||||||
|
readonly isUncommitted: boolean;
|
||||||
previousUri: Uri;
|
previousUri: Uri;
|
||||||
uri: Uri;
|
uri: Uri;
|
||||||
}
|
}
|
||||||
@@ -55,6 +57,7 @@ export class GitCommit implements IGitCommit {
|
|||||||
originalFileName?: string;
|
originalFileName?: string;
|
||||||
previousSha?: string;
|
previousSha?: string;
|
||||||
previousFileName?: string;
|
previousFileName?: string;
|
||||||
|
private _isUncommitted: boolean|undefined;
|
||||||
|
|
||||||
constructor(public repoPath: string, public sha: string, public fileName: string, public author: string, public date: Date, public message: string,
|
constructor(public repoPath: string, public sha: string, public fileName: string, public author: string, public date: Date, public message: string,
|
||||||
lines?: IGitCommitLine[], originalFileName?: string, previousSha?: string, previousFileName?: string) {
|
lines?: IGitCommitLine[], originalFileName?: string, previousSha?: string, previousFileName?: string) {
|
||||||
@@ -64,6 +67,13 @@ export class GitCommit implements IGitCommit {
|
|||||||
this.previousFileName = previousFileName;
|
this.previousFileName = previousFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isUncommitted(): boolean {
|
||||||
|
if (this._isUncommitted === undefined) {
|
||||||
|
this._isUncommitted = Git.isUncommitted(this.sha);
|
||||||
|
}
|
||||||
|
return this._isUncommitted;
|
||||||
|
}
|
||||||
|
|
||||||
get previousUri(): Uri {
|
get previousUri(): Uri {
|
||||||
return this.previousFileName ? Uri.file(path.join(this.repoPath, this.previousFileName)) : this.uri;
|
return this.previousFileName ? Uri.file(path.join(this.repoPath, this.previousFileName)) : this.uri;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,17 +51,19 @@ export default class GitBlameContentProvider implements TextDocumentContentProvi
|
|||||||
|
|
||||||
//const editor = this._findEditor(Uri.file(join(data.repoPath, data.file)));
|
//const editor = this._findEditor(Uri.file(join(data.repoPath, data.file)));
|
||||||
|
|
||||||
return this.git.getVersionedFileText(data.originalFileName || data.fileName, data.repoPath, data.sha).then(text => {
|
return this.git.getVersionedFileText(data.originalFileName || data.fileName, data.repoPath, data.sha)
|
||||||
this.update(uri);
|
.then(text => {
|
||||||
|
this.update(uri);
|
||||||
|
|
||||||
// TODO: This only works on the first load -- not after since it is cached
|
// TODO: This only works on the first load -- not after since it is cached
|
||||||
this._tryAddBlameDecorations(uri, data);
|
this._tryAddBlameDecorations(uri, data);
|
||||||
|
|
||||||
// TODO: This needs to move to selection somehow to show on the main file editor
|
// TODO: This needs to move to selection somehow to show on the main file editor
|
||||||
//this._addBlameDecorations(editor, data);
|
//this._addBlameDecorations(editor, data);
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
});
|
})
|
||||||
|
.catch(ex => console.error('[GitLens.GitBlameContentProvider]', 'getVersionedFileText', ex));
|
||||||
|
|
||||||
// return this.git.getVersionedFile(data.fileName, data.sha).then(dst => {
|
// return this.git.getVersionedFile(data.fileName, data.sha).then(dst => {
|
||||||
// let uri = Uri.parse(`file:${dst}`)
|
// let uri = Uri.parse(`file:${dst}`)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export default class GitContentProvider implements TextDocumentContentProvider {
|
|||||||
|
|
||||||
provideTextDocumentContent(uri: Uri): string | Thenable<string> {
|
provideTextDocumentContent(uri: Uri): string | Thenable<string> {
|
||||||
const data = GitProvider.fromGitUri(uri);
|
const data = GitProvider.fromGitUri(uri);
|
||||||
return this.git.getVersionedFileText(data.originalFileName || data.fileName, data.repoPath, data.sha);
|
return this.git.getVersionedFileText(data.originalFileName || data.fileName, data.repoPath, data.sha)
|
||||||
|
.catch(ex => console.error('[GitLens.GitContentProvider]', 'getVersionedFileText', ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,6 +306,8 @@ export default class GitProvider extends Disposable {
|
|||||||
const locations: Array<Location> = [];
|
const locations: Array<Location> = [];
|
||||||
Array.from(blame.commits.values())
|
Array.from(blame.commits.values())
|
||||||
.forEach((c, i) => {
|
.forEach((c, i) => {
|
||||||
|
if (c.isUncommitted) return;
|
||||||
|
|
||||||
const uri = GitProvider.toBlameUri(c, i + 1, commitCount, range);
|
const uri = GitProvider.toBlameUri(c, i + 1, commitCount, range);
|
||||||
c.lines.forEach(l => locations.push(new Location(c.originalFileName
|
c.lines.forEach(l => locations.push(new Location(c.originalFileName
|
||||||
? GitProvider.toBlameUri(c, i + 1, commitCount, range, c.originalFileName)
|
? GitProvider.toBlameUri(c, i + 1, commitCount, range, c.originalFileName)
|
||||||
|
|||||||
Reference in New Issue
Block a user