diff --git a/src/commands/diffLineWithPrevious.ts b/src/commands/diffLineWithPrevious.ts index 9b15951..7290a14 100644 --- a/src/commands/diffLineWithPrevious.ts +++ b/src/commands/diffLineWithPrevious.ts @@ -21,7 +21,7 @@ export default class DiffLineWithPreviousCommand extends EditorCommand { } line = line || editor.selection.active.line; - const gitUri = GitUri.fromUri(uri, this.git); + let gitUri = GitUri.fromUri(uri, this.git); if (!commit || GitProvider.isUncommitted(commit.sha)) { const blameline = line - gitUri.offset; @@ -32,10 +32,10 @@ export default class DiffLineWithPreviousCommand extends EditorCommand { if (!blame) return window.showWarningMessage(`Unable to open diff. File is probably not under source control`); commit = blame.commit; - // If the current commit matches the blame, show the previous - if (gitUri.sha === commit.sha) { - commit = new GitCommit(commit.repoPath, commit.previousSha, commit.previousFileName, commit.author, commit.date, commit.message); - line = blame.line.line + 1 + gitUri.offset; + + // If we don't have a sha or the current commit matches the blame, show the previous + if (!gitUri.sha || gitUri.sha === commit.sha) { + return commands.executeCommand(Commands.DiffWithPrevious, new GitUri(uri, commit), undefined, line); } // If the line is uncommitted, find the previous commit and treat it as a DiffWithWorking @@ -53,11 +53,11 @@ export default class DiffLineWithPreviousCommand extends EditorCommand { } try { - const values = await Promise.all([ + const [rhs, lhs] = await Promise.all([ this.git.getVersionedFile(gitUri.fsPath, gitUri.repoPath, gitUri.sha), this.git.getVersionedFile(commit.uri.fsPath, commit.repoPath, commit.sha) ]); - await commands.executeCommand(BuiltInCommands.Diff, Uri.file(values[1]), Uri.file(values[0]), `${path.basename(commit.uri.fsPath)} (${commit.sha}) ↔ ${path.basename(gitUri.fsPath)} (${gitUri.sha})`); + await commands.executeCommand(BuiltInCommands.Diff, Uri.file(lhs), Uri.file(rhs), `${path.basename(commit.uri.fsPath)} (${commit.sha}) ↔ ${path.basename(gitUri.fsPath)} (${gitUri.sha})`); return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: line, at: 'center' }); } catch (ex) { diff --git a/src/commands/diffWithPrevious.ts b/src/commands/diffWithPrevious.ts index 64da5d6..d04093c 100644 --- a/src/commands/diffWithPrevious.ts +++ b/src/commands/diffWithPrevious.ts @@ -34,7 +34,7 @@ export default class DiffWithPreviousCommand extends EditorCommand { const gitUri = GitUri.fromUri(uri, this.git); try { - const log = await this.git.getLogForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath, rangeOrLine as Range); + const log = await this.git.getLogForFile(gitUri.fsPath, undefined, gitUri.repoPath, rangeOrLine as Range); if (!log) return window.showWarningMessage(`Unable to open diff. File is probably not under source control`); const sha = (commit && commit.sha) || gitUri.sha; @@ -51,38 +51,10 @@ export default class DiffWithPreviousCommand extends EditorCommand { } try { - let rhs: string; - try { - rhs = await this.git.getVersionedFile(commit.uri.fsPath, commit.repoPath, commit.sha); - } - catch (ex) { - if (ex.message.includes(`fatal: Path '${commit.originalFileName}' does not exist in '${commit.sha}'`)) { - try { - rhs = await this.git.getVersionedFile(commit.fileName, commit.repoPath, commit.sha); - } - catch (ex) { - Logger.error('[GitLens.DiffWithPreviousCommand]', 'getVersionedFile', ex); - return window.showErrorMessage(`Unable to open diff. See output channel for more details`); - } - } - } - - let lhs: string; - try { - lhs = await this.git.getVersionedFile(commit.previousUri.fsPath, commit.repoPath, commit.previousSha); - } - catch (ex) { - if (ex.message.includes(`fatal: Path '${commit.previousFileName}' does not exist in '${commit.previousSha}'`)) { - try { - lhs = await this.git.getVersionedFile(commit.uri.fsPath, commit.repoPath, commit.previousSha); - } - catch (ex) { - Logger.error('[GitLens.DiffWithPreviousCommand]', 'getVersionedFile', ex); - return window.showErrorMessage(`Unable to open diff. See output channel for more details`); - } - } - } - + const [rhs, lhs] = await Promise.all([ + this.git.getVersionedFile(commit.uri.fsPath, commit.repoPath, commit.sha), + this.git.getVersionedFile(commit.previousUri.fsPath, commit.repoPath, commit.previousSha) + ]); await commands.executeCommand(BuiltInCommands.Diff, Uri.file(lhs), Uri.file(rhs), `${path.basename(commit.previousUri.fsPath)} (${commit.previousSha}) ↔ ${path.basename(commit.uri.fsPath)} (${commit.sha})`); return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: line, at: 'center' }); } diff --git a/src/git/enrichers/logParserEnricher.ts b/src/git/enrichers/logParserEnricher.ts index 8485339..c798081 100644 --- a/src/git/enrichers/logParserEnricher.ts +++ b/src/git/enrichers/logParserEnricher.ts @@ -133,7 +133,7 @@ export class GitLogParserEnricher implements IGitEnricher { } else { // Try to get the repoPath from the most recent commit - repoPath = fileNameOrRepoPath.replace(`/${entry.fileName}`, ''); + repoPath = fileNameOrRepoPath.replace(fileNameOrRepoPath.startsWith('/') ? `/${entry.fileName}` : entry.fileName, ''); relativeFileName = path.relative(repoPath, fileNameOrRepoPath).replace(/\\/g, '/'); } } @@ -160,9 +160,7 @@ export class GitLogParserEnricher implements IGitEnricher { if (recentCommit) { recentCommit.previousSha = commit.sha; - if (!isRepoPath) { - recentCommit.previousFileName = commit.originalFileName || commit.fileName; - } + recentCommit.previousFileName = commit.originalFileName || commit.fileName; } recentCommit = commit; } diff --git a/src/git/git.ts b/src/git/git.ts index fcf1be9..dacc204 100644 --- a/src/git/git.ts +++ b/src/git/git.ts @@ -70,7 +70,7 @@ export default class Git { const params = [`blame`, `--root`, format]; if (sha) { - params.push(`${sha}^!`); + params.push(sha); } return gitCommand(root, ...params, `--`, file); @@ -81,7 +81,7 @@ export default class Git { const params = [`blame`, `--root`, format, `-L ${startLine},${endLine}`]; if (sha) { - params.push(`${sha}^!`); + params.push(sha); } return gitCommand(root, ...params, `--`, file); diff --git a/src/git/gitUri.ts b/src/git/gitUri.ts index 1f0fc49..4569cfe 100644 --- a/src/git/gitUri.ts +++ b/src/git/gitUri.ts @@ -42,6 +42,8 @@ export class GitUri extends Uri { } static fromUri(uri: Uri, git?: GitProvider) { + if (uri instanceof GitUri) return uri; + if (git) { const gitUri = git.getGitUriForFile(uri.fsPath); if (gitUri) return gitUri; diff --git a/src/gitProvider.ts b/src/gitProvider.ts index e36127f..0f889db 100644 --- a/src/gitProvider.ts +++ b/src/gitProvider.ts @@ -441,7 +441,7 @@ export default class GitProvider extends Disposable { Logger.log(`getLogForFile('${fileName}', ${sha}, ${repoPath}, ${range && `[${range.start.line}, ${range.end.line}]`}, ${maxCount})`); fileName = Git.normalizePath(fileName); - const useCaching = this.UseGitCaching && !range && !maxCount; + const useCaching = this.UseGitCaching && !sha && !range && !maxCount; let cacheKey: string; let entry: GitCacheEntry; @@ -464,7 +464,7 @@ export default class GitProvider extends Disposable { return (range ? Git.logRange(fileName, range.start.line + 1, range.end.line + 1, sha, repoPath, maxCount) : Git.log(fileName, sha, repoPath, maxCount)) - .then(data => new GitLogParserEnricher().enrich(data, fileName)) + .then(data => new GitLogParserEnricher().enrich(data, repoPath || fileName, !!repoPath)) .catch(ex => { // Trap and cache expected log errors if (useCaching) {