From 071bfdb82e95b79a9d63499ad9dcc2e1003b2734 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Mon, 1 May 2017 14:03:36 -0400 Subject: [PATCH] Adds better support for deleted files Will now open the file from the previous commit --- src/git/models/logCommit.ts | 7 ++++++- src/quickPicks/commitFileDetails.ts | 25 +++++++++++++++++-------- src/quickPicks/remotes.ts | 33 ++++++++++++++++++++++++++------- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/git/models/logCommit.ts b/src/git/models/logCommit.ts index 11995d8..8334fc0 100644 --- a/src/git/models/logCommit.ts +++ b/src/git/models/logCommit.ts @@ -11,6 +11,7 @@ export class GitLogCommit extends GitCommit { nextSha?: string; nextFileName?: string; parentShas: string[]; + status?: GitStatusFileStatus; constructor( type: GitCommitType, @@ -33,10 +34,14 @@ export class GitLogCommit extends GitCommit { if (fileStatuses) { this.fileStatuses = fileStatuses.filter(_ => !!_.fileName); - this.fileName = this.fileStatuses[0].fileName; + + const fileStatus = this.fileStatuses[0]; + this.fileName = fileStatus.fileName; + this.status = fileStatus.status; } else { this.fileStatuses = [{ status: status, fileName: fileName, originalFileName: originalFileName }]; + this.status = status; } } diff --git a/src/quickPicks/commitFileDetails.ts b/src/quickPicks/commitFileDetails.ts index 453d6c7..c43e24a 100644 --- a/src/quickPicks/commitFileDetails.ts +++ b/src/quickPicks/commitFileDetails.ts @@ -3,25 +3,34 @@ import { Arrays, Iterables } from '../system'; import { QuickPickItem, QuickPickOptions, Uri, window } from 'vscode'; import { Commands, Keyboard, KeyNoopCommand } from '../commands'; import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, KeyCommandQuickPickItem, OpenFileCommandQuickPickItem } from './common'; -import { GitCommit, GitLogCommit, GitService, GitUri, IGitLog } from '../gitService'; +import { GitLogCommit, GitService, GitUri, IGitLog } from '../gitService'; import { OpenRemotesCommandQuickPickItem } from './remotes'; import * as moment from 'moment'; import * as path from 'path'; export class OpenCommitFileCommandQuickPickItem extends OpenFileCommandQuickPickItem { - constructor(commit: GitCommit, item?: QuickPickItem) { - const uri = GitService.toGitContentUri(commit); + constructor(commit: GitLogCommit, item?: QuickPickItem) { + let description: string; + let uri: Uri; + if (commit.status === 'D') { + uri = GitService.toGitContentUri(commit.previousSha, commit.previousShortSha, commit.previousFileName, commit.repoPath, undefined); + description = `\u00a0 \u2014 \u00a0\u00a0 ${path.basename(commit.fileName)} in \u00a0$(git-commit) ${commit.previousShortSha} (deleted in \u00a0$(git-commit) ${commit.shortSha})`; + } + else { + uri = GitService.toGitContentUri(commit); + description = `\u00a0 \u2014 \u00a0\u00a0 ${path.basename(commit.fileName)} in \u00a0$(git-commit) ${commit.shortSha}`; + } super(uri, item || { label: `$(file-symlink-file) Open File`, - description: `\u00a0 \u2014 \u00a0\u00a0 ${path.basename(commit.fileName)} in \u00a0$(git-commit) ${commit.shortSha}` + description: description }); } } export class OpenCommitWorkingTreeFileCommandQuickPickItem extends OpenFileCommandQuickPickItem { - constructor(commit: GitCommit, item?: QuickPickItem) { + constructor(commit: GitLogCommit, item?: QuickPickItem) { const uri = Uri.file(path.resolve(commit.repoPath, commit.fileName)); super(uri, item || { label: `$(file-symlink-file) Open Working File`, @@ -80,16 +89,16 @@ export class CommitFileDetailsQuickPick { } items.push(new OpenCommitFileCommandQuickPickItem(commit)); - if (commit.workingFileName) { + if (commit.workingFileName && commit.status !== 'D') { items.push(new OpenCommitWorkingTreeFileCommandQuickPickItem(commit)); } const remotes = Arrays.uniqueBy(await git.getRemotes(commit.repoPath), _ => _.url, _ => !!_.provider); if (remotes.length) { if (!stash) { - items.push(new OpenRemotesCommandQuickPickItem(remotes, 'file', commit.fileName, undefined, commit.sha, currentCommand)); + items.push(new OpenRemotesCommandQuickPickItem(remotes, 'file', commit.fileName, undefined, commit, currentCommand)); } - if (commit.workingFileName) { + if (commit.workingFileName && commit.status !== 'D') { const branch = await git.getBranch(commit.repoPath || git.repoPath); items.push(new OpenRemotesCommandQuickPickItem(remotes, 'working-file', commit.workingFileName, branch.name, undefined, currentCommand)); } diff --git a/src/quickPicks/remotes.ts b/src/quickPicks/remotes.ts index 82ff745..b6a9728 100644 --- a/src/quickPicks/remotes.ts +++ b/src/quickPicks/remotes.ts @@ -2,7 +2,7 @@ import { QuickPickOptions, window } from 'vscode'; import { Commands } from '../commands'; import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from './common'; -import { getNameFromRemoteOpenType, GitRemote, RemoteOpenType } from '../gitService'; +import { getNameFromRemoteOpenType, GitLogCommit, GitRemote, RemoteOpenType } from '../gitService'; import * as path from 'path'; export class OpenRemoteCommandQuickPickItem extends CommandQuickPickItem { @@ -30,8 +30,9 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem { constructor(remotes: GitRemote[], type: 'branch', branch: string, goBackCommand?: CommandQuickPickItem); constructor(remotes: GitRemote[], type: 'commit', sha: string, goBackCommand?: CommandQuickPickItem); + constructor(remotes: GitRemote[], type: 'file', fileName: string, branch?: string, commit?: GitLogCommit, goBackCommand?: CommandQuickPickItem); constructor(remotes: GitRemote[], type: 'file' | 'working-file', fileName: string, branch?: string, sha?: string, goBackCommand?: CommandQuickPickItem); - constructor(remotes: GitRemote[], type: RemoteOpenType, branchOrShaOrFileName: string, goBackCommandOrFileBranch?: CommandQuickPickItem | string, fileSha?: string, goBackCommand?: CommandQuickPickItem) { + constructor(remotes: GitRemote[], type: RemoteOpenType, branchOrShaOrFileName: string, goBackCommandOrFileBranch?: CommandQuickPickItem | string, fileShaOrCommit?: string | GitLogCommit, goBackCommand?: CommandQuickPickItem) { let fileBranch: string; if (typeof goBackCommandOrFileBranch === 'string') { fileBranch = goBackCommandOrFileBranch; @@ -42,6 +43,7 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem { const name = getNameFromRemoteOpenType(type); + let fileSha: string; let description: string; let placeHolder: string; switch (type) { @@ -58,11 +60,28 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem { case 'file': case 'working-file': const fileName = path.basename(branchOrShaOrFileName); - const shortFileSha = (fileSha && fileSha.substring(0, 8)) || ''; - const shaSuffix = shortFileSha ? ` \u00a0\u2022\u00a0 ${shortFileSha}` : ''; - - description = `$(file-text) ${fileName}${shortFileSha ? ` in \u00a0$(git-commit) ${shortFileSha}` : ''}`; - placeHolder = `open ${branchOrShaOrFileName}${shaSuffix} in\u2026`; + if (fileShaOrCommit instanceof GitLogCommit) { + if (fileShaOrCommit.status === 'D') { + fileSha = fileShaOrCommit.previousSha; + + description = `$(file-text) ${fileName} in \u00a0$(git-commit) ${fileShaOrCommit.previousShortSha} (deleted in \u00a0$(git-commit) ${fileShaOrCommit.shortSha})`; + placeHolder = `open ${branchOrShaOrFileName} \u00a0\u2022\u00a0 ${fileShaOrCommit.previousShortSha} in\u2026`; + } + else { + fileSha = fileShaOrCommit.sha; + + description = `$(file-text) ${fileName} in \u00a0$(git-commit) ${fileShaOrCommit.shortSha}`; + placeHolder = `open ${branchOrShaOrFileName} \u00a0\u2022\u00a0 ${fileShaOrCommit.shortSha} in\u2026`; + } + } + else { + fileSha = fileShaOrCommit; + const shortFileSha = (fileSha && fileSha.substring(0, 8)) || ''; + const shaSuffix = shortFileSha ? ` \u00a0\u2022\u00a0 ${shortFileSha}` : ''; + + description = `$(file-text) ${fileName}${shortFileSha ? ` in \u00a0$(git-commit) ${shortFileSha}` : ''}`; + placeHolder = `open ${branchOrShaOrFileName}${shaSuffix} in\u2026`; + } break; }