From 5f147f6262c642aeb573d0c080659c15b5d4bfc6 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Mon, 13 Feb 2017 13:19:55 -0500 Subject: [PATCH] Attempted fix for bad filename to diff w/ working Tried to find the most recent filename given a commit, but git doesn't seem to want to cooperate --- src/commands/showQuickCommitDetails.ts | 8 +++++--- src/commands/showQuickRepoHistory.ts | 8 +++++--- src/git/enrichers/logParserEnricher.ts | 7 +++++-- src/git/git.ts | 9 +++++++-- src/gitProvider.ts | 32 ++++++++++++++++++++++++++++---- 5 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/commands/showQuickCommitDetails.ts b/src/commands/showQuickCommitDetails.ts index 2bef041..ece6905 100644 --- a/src/commands/showQuickCommitDetails.ts +++ b/src/commands/showQuickCommitDetails.ts @@ -60,8 +60,10 @@ export default class ShowQuickCommitDetailsCommand extends EditorCommand { } as QuickPickOptions); if (filePick) { - // TODO need to make log for file -- go from commit to HEAD so we can get the current filename - const log = await this.git.getLogForFile(filePick.uri.fsPath, filePick.sha); + // Get the most recent commit -- so that we can find the real working filename if there was a rename + const workingCommit = await this.git.findMostRecentCommitForFile(filePick.uri.fsPath, filePick.sha); + + const log = await this.git.getLogForFile(filePick.uri.fsPath, filePick.sha, undefined, undefined, 2); if (!log) return window.showWarningMessage(`Unable to open diff`); const commit = Iterables.find(log.commits.values(), c => c.sha === commitPick.commit.sha); @@ -70,7 +72,7 @@ export default class ShowQuickCommitDetailsCommand extends EditorCommand { const items: CompareQuickPickItem[] = [ { label: `Compare with Working Tree`, - description: `\u2022 ${commit.sha} $(git-compare) ${commit.fileName}`, + description: `\u2022 ${commit.sha} $(git-compare) ${(workingCommit || commit).fileName}`, command: Commands.DiffWithWorking } ]; diff --git a/src/commands/showQuickRepoHistory.ts b/src/commands/showQuickRepoHistory.ts index a3cec8c..1a14d8b 100644 --- a/src/commands/showQuickRepoHistory.ts +++ b/src/commands/showQuickRepoHistory.ts @@ -93,8 +93,10 @@ export default class ShowQuickRepoHistoryCommand extends Command { const filePick = pick as FileQuickPickItem; if (filePick) { - // TODO need to make log for file -- go from commit to HEAD so we can get the current filename - const log = await this.git.getLogForFile(filePick.uri.fsPath, filePick.sha); + // Get the most recent commit -- so that we can find the real working filename if there was a rename + const workingCommit = await this.git.findMostRecentCommitForFile(filePick.uri.fsPath, filePick.sha); + + const log = await this.git.getLogForFile(filePick.uri.fsPath, filePick.sha, undefined, undefined, 2); if (!log) return window.showWarningMessage(`Unable to open diff`); const commit = Iterables.find(log.commits.values(), c => c.sha === commitPick.commit.sha); @@ -103,7 +105,7 @@ export default class ShowQuickRepoHistoryCommand extends Command { const items: CompareQuickPickItem[] = [ { label: `Compare with Working Tree`, - description: `\u2022 ${commit.sha} $(git-compare) ${commit.fileName}`, + description: `\u2022 ${commit.sha} $(git-compare) ${(workingCommit || commit).fileName}`, command: Commands.DiffWithWorking } ]; diff --git a/src/git/enrichers/logParserEnricher.ts b/src/git/enrichers/logParserEnricher.ts index c798081..d9b67ee 100644 --- a/src/git/enrichers/logParserEnricher.ts +++ b/src/git/enrichers/logParserEnricher.ts @@ -109,7 +109,7 @@ export class GitLogParserEnricher implements IGitEnricher { return entries; } - enrich(data: string, fileNameOrRepoPath: string, isRepoPath: boolean = false): IGitLog { + enrich(data: string, type: 'file' | 'repo', fileNameOrRepoPath: string, isRepoPath: boolean = false): IGitLog { const entries = this._parseEntries(data, isRepoPath); if (!entries) return undefined; @@ -160,7 +160,10 @@ export class GitLogParserEnricher implements IGitEnricher { if (recentCommit) { recentCommit.previousSha = commit.sha; - recentCommit.previousFileName = commit.originalFileName || commit.fileName; + // Only add a filename if this is a file log + if (type === 'file') { + recentCommit.previousFileName = commit.originalFileName || commit.fileName; + } } recentCommit = commit; } diff --git a/src/git/git.ts b/src/git/git.ts index dacc204..bedd200 100644 --- a/src/git/git.ts +++ b/src/git/git.ts @@ -87,7 +87,7 @@ export default class Git { return gitCommand(root, ...params, `--`, file); } - static log(fileName: string, sha?: string, repoPath?: string, maxCount?: number) { + static log(fileName: string, sha?: string, repoPath?: string, maxCount?: number, reverse: boolean = false) { const [file, root]: [string, string] = Git.splitPath(Git.normalizePath(fileName), repoPath); const params = [...DefaultLogParams, `--follow`]; @@ -95,7 +95,12 @@ export default class Git { params.push(`-n${maxCount}`); } if (sha) { - params.push(sha); + if (reverse) { + params.push(`${sha}..HEAD`); + } + else { + params.push(sha); + } params.push(`--`); } diff --git a/src/gitProvider.ts b/src/gitProvider.ts index 0f889db..4b080d3 100644 --- a/src/gitProvider.ts +++ b/src/gitProvider.ts @@ -229,6 +229,30 @@ export default class GitProvider extends Disposable { return this._uriCache.has(cacheKey); } + async findMostRecentCommitForFile(fileName: string, sha?: string): Promise { + const exists = await new Promise((resolve, reject) => fs.exists(fileName, e => resolve(e))); + if (exists) return null; + + return undefined; + + // TODO: Get this to work -- for some reason a reverse log won't return the renamed file + // Not sure how else to figure this out + + // let log: IGitLog; + // let commit: GitCommit; + // while (true) { + // // Go backward from the current commit to head to find the latest filename + // log = await this.getLogForFile(fileName, sha, undefined, undefined, undefined, true); + // if (!log) break; + + // commit = Iterables.first(log.commits.values()); + // sha = commit.sha; + // fileName = commit.fileName; + // } + + // return commit; + } + getGitUriForFile(fileName: string) { if (!this.UseUriCaching) return undefined; @@ -430,14 +454,14 @@ export default class GitProvider extends Disposable { try { const data = await Git.logRepo(repoPath, sha, maxCount); - return new GitLogParserEnricher().enrich(data, repoPath, true); + return new GitLogParserEnricher().enrich(data, 'repo', repoPath, true); } catch (ex) { return undefined; } } - getLogForFile(fileName: string, sha?: string, repoPath?: string, range?: Range, maxCount?: number): Promise { + getLogForFile(fileName: string, sha?: string, repoPath?: string, range?: Range, maxCount?: number, reverse: boolean = false): Promise { Logger.log(`getLogForFile('${fileName}', ${sha}, ${repoPath}, ${range && `[${range.start.line}, ${range.end.line}]`}, ${maxCount})`); fileName = Git.normalizePath(fileName); @@ -463,8 +487,8 @@ 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, repoPath || fileName, !!repoPath)) + : Git.log(fileName, sha, repoPath, maxCount, reverse)) + .then(data => new GitLogParserEnricher().enrich(data, 'file', repoPath || fileName, !!repoPath)) .catch(ex => { // Trap and cache expected log errors if (useCaching) {