From 74845f979bc42bd48af6a9fd633226ca1845959b Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Wed, 1 Mar 2017 01:26:27 -0500 Subject: [PATCH] Fixes #34 - Open file should open the selected version of the file Renames current Open File command to Open Working File Renames current Open Files command to Open Working Files Adds new Open File command to open the commit version of the file Adds new Open Files command to open the commit version of the files --- src/git/gitUri.ts | 8 ++++---- src/gitContentProvider.ts | 2 +- src/gitProvider.ts | 43 ++++++++++++++++++++++++++++++----------- src/quickPicks.ts | 2 +- src/quickPicks/commitDetails.ts | 36 +++++++++++++++++++++++++++++----- 5 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/git/gitUri.ts b/src/git/gitUri.ts index 327f0cf..c37e2e3 100644 --- a/src/git/gitUri.ts +++ b/src/git/gitUri.ts @@ -23,7 +23,7 @@ export class GitUri extends Uri { this.offset = 0; if (uri.scheme === DocumentSchemes.Git) { - const data = GitProvider.fromGitUri(uri); + const data = GitProvider.fromGitContentUri(uri); base._fsPath = data.originalFileName || data.fileName; this.offset = (data.decoration && data.decoration.split('\n').length) || 0; @@ -72,10 +72,10 @@ export interface IGitCommitInfo { } export interface IGitUriData { - repoPath: string; + sha: string; fileName: string; + repoPath: string; originalFileName?: string; - sha: string; - index: number; + index?: number; decoration?: string; } \ No newline at end of file diff --git a/src/gitContentProvider.ts b/src/gitContentProvider.ts index 91f7010..838b79f 100644 --- a/src/gitContentProvider.ts +++ b/src/gitContentProvider.ts @@ -12,7 +12,7 @@ export default class GitContentProvider implements TextDocumentContentProvider { constructor(context: ExtensionContext, private git: GitProvider) { } async provideTextDocumentContent(uri: Uri): Promise { - const data = GitProvider.fromGitUri(uri); + const data = GitProvider.fromGitContentUri(uri); const fileName = data.originalFileName || data.fileName; try { let text = await this.git.getVersionedFileText(fileName, data.repoPath, data.sha) as string; diff --git a/src/gitProvider.ts b/src/gitProvider.ts index 6a042fb..a6552ea 100644 --- a/src/gitProvider.ts +++ b/src/gitProvider.ts @@ -450,7 +450,7 @@ export default class GitProvider extends Disposable { if (c.isUncommitted) return; const decoration = `\u2937 ${c.author}, ${moment(c.date).format('MMMM Do, YYYY h:MMa')}`; - const uri = GitProvider.toGitUri(c, i + 1, commitCount, c.originalFileName, decoration); + const uri = GitProvider.toReferenceGitContentUri(c, i + 1, commitCount, c.originalFileName, decoration); locations.push(new Location(uri, new Position(0, 0))); if (c.sha === selectedSha) { locations.push(new Location(uri, new Position(line + 1, 0))); @@ -550,7 +550,7 @@ export default class GitProvider extends Disposable { if (c.isUncommitted) return; const decoration = `\u2937 ${c.author}, ${moment(c.date).format('MMMM Do, YYYY h:MMa')}`; - const uri = GitProvider.toGitUri(c, i + 1, commitCount, c.originalFileName, decoration); + const uri = GitProvider.toReferenceGitContentUri(c, i + 1, commitCount, c.originalFileName, decoration); locations.push(new Location(uri, new Position(0, 0))); if (c.sha === selectedSha) { locations.push(new Location(uri, new Position(line + 1, 0))); @@ -614,20 +614,41 @@ export default class GitProvider extends Disposable { return Git.isUncommitted(sha); } - static fromGitUri(uri: Uri): IGitUriData { + static fromGitContentUri(uri: Uri): IGitUriData { if (uri.scheme !== DocumentSchemes.Git) throw new Error(`fromGitUri(uri=${uri}) invalid scheme`); - return GitProvider._fromGitUri(uri); + return GitProvider._fromGitContentUri(uri); } - private static _fromGitUri(uri: Uri): T { + private static _fromGitContentUri(uri: Uri): T { return JSON.parse(uri.query) as T; } - static toGitUri(commit: GitCommit, index: number, commitCount: number, originalFileName?: string, decoration?: string) { - return GitProvider._toGitUri(commit, DocumentSchemes.Git, commitCount, GitProvider._toGitUriData(commit, index, originalFileName, decoration)); + static toGitContentUri(sha: string, fileName: string, repoPath: string, originalFileName: string): Uri; + static toGitContentUri(commit: GitCommit): Uri; + static toGitContentUri(shaOrcommit: string | GitCommit, fileName?: string, repoPath?: string, originalFileName?: string): Uri { + let data: IGitUriData; + if (typeof shaOrcommit === 'string') { + data = GitProvider._toGitUriData({ + sha: shaOrcommit, + fileName: fileName, + repoPath: repoPath, + originalFileName: originalFileName + }); + } + else { + data = GitProvider._toGitUriData(shaOrcommit, undefined, shaOrcommit.originalFileName); + fileName = shaOrcommit.fileName; + } + + const extension = path.extname(fileName); + return Uri.parse(`${DocumentSchemes.Git}:${path.basename(fileName, extension)}:${data.sha}${extension}?${JSON.stringify(data)}`); + } + + static toReferenceGitContentUri(commit: GitCommit, index: number, commitCount: number, originalFileName?: string, decoration?: string): Uri { + return GitProvider._toReferenceGitContentUri(commit, DocumentSchemes.Git, commitCount, GitProvider._toGitUriData(commit, index, originalFileName, decoration)); } - private static _toGitUri(commit: GitCommit, scheme: DocumentSchemes, commitCount: number, data: IGitUriData) { + private static _toReferenceGitContentUri(commit: GitCommit, scheme: DocumentSchemes, commitCount: number, data: IGitUriData) { const pad = (n: number) => ('0000000' + n).slice(-('' + commitCount).length); const ext = path.extname(data.fileName); const uriPath = `${path.relative(commit.repoPath, data.fileName.slice(0, -ext.length))}/${commit.sha}${ext}`; @@ -641,11 +662,11 @@ export default class GitProvider extends Disposable { return Uri.parse(`${scheme}:${pad(data.index)} \u2022 ${encodeURIComponent(message)} \u2022 ${moment(commit.date).format('MMM D, YYYY hh:MMa')} \u2022 ${encodeURIComponent(uriPath)}?${JSON.stringify(data)}`); } - private static _toGitUriData(commit: GitCommit, index: number, originalFileName?: string, decoration?: string): T { - const fileName = Git.normalizePath(path.join(commit.repoPath, commit.fileName)); + private static _toGitUriData(commit: IGitUriData, index?: number, originalFileName?: string, decoration?: string): T { + const fileName = Git.normalizePath(path.resolve(commit.repoPath, commit.fileName)); const data = { repoPath: commit.repoPath, fileName: fileName, sha: commit.sha, index: index } as T; if (originalFileName) { - data.originalFileName = Git.normalizePath(path.join(commit.repoPath, originalFileName)); + data.originalFileName = Git.normalizePath(path.resolve(commit.repoPath, originalFileName)); } if (decoration) { data.decoration = decoration; diff --git a/src/quickPicks.ts b/src/quickPicks.ts index 368b697..f07d8f9 100644 --- a/src/quickPicks.ts +++ b/src/quickPicks.ts @@ -1,7 +1,7 @@ 'use strict'; export { CommandQuickPickItem, OpenFileCommandQuickPickItem, OpenFilesCommandQuickPickItem } from './quickPicks/quickPicks'; export { CommitQuickPickItem, CommitWithFileStatusQuickPickItem } from './quickPicks/gitQuickPicks'; -export { OpenCommitFileCommandQuickPickItem, OpenCommitFilesCommandQuickPickItem, CommitDetailsQuickPick, CommitFileDetailsQuickPick } from './quickPicks/commitDetails'; +export { OpenCommitFileCommandQuickPickItem, OpenCommitWorkingTreeFileCommandQuickPickItem, OpenCommitFilesCommandQuickPickItem, OpenCommitWorkingTreeFilesCommandQuickPickItem, CommitDetailsQuickPick, CommitFileDetailsQuickPick } from './quickPicks/commitDetails'; export { FileHistoryQuickPick } from './quickPicks/fileHistory'; export { RepoHistoryQuickPick } from './quickPicks/repoHistory'; export { OpenStatusFileCommandQuickPickItem, OpenStatusFilesCommandQuickPickItem, RepoStatusQuickPick } from './quickPicks/repoStatus'; diff --git a/src/quickPicks/commitDetails.ts b/src/quickPicks/commitDetails.ts index e0fcbbb..0935c28 100644 --- a/src/quickPicks/commitDetails.ts +++ b/src/quickPicks/commitDetails.ts @@ -13,9 +13,20 @@ export { CommandQuickPickItem, CommitWithFileStatusQuickPickItem }; export class OpenCommitFileCommandQuickPickItem extends OpenFileCommandQuickPickItem { constructor(commit: GitCommit, item?: QuickPickItem) { + const uri = GitProvider.toGitContentUri(commit); + super(uri, item || { + label: `$(file-symlink-file) Open File`, + description: `\u00a0 \u2014 \u00a0\u00a0 as of \u00a0 $(git-commit) \u00a0 ${commit.sha} \u00a0\u2022\u00a0 ${commit.getFormattedPath()}` + }); + } +} + +export class OpenCommitWorkingTreeFileCommandQuickPickItem extends OpenFileCommandQuickPickItem { + + constructor(commit: GitCommit, item?: QuickPickItem) { const uri = Uri.file(path.resolve(commit.repoPath, commit.fileName)); super(uri, item || { - label: `$(file-symlink-file) Open Working Tree File`, + label: `$(file-symlink-file) Open Working File`, description: `\u00a0 \u2014 \u00a0\u00a0 ${commit.getFormattedPath()}` }); } @@ -25,11 +36,24 @@ export class OpenCommitFilesCommandQuickPickItem extends OpenFilesCommandQuickPi constructor(commit: GitLogCommit, item?: QuickPickItem) { const repoPath = commit.repoPath; + const uris = commit.fileStatuses.map(_ => GitProvider.toGitContentUri(commit.sha, _.fileName, repoPath, commit.originalFileName)); + super(uris, item || { + label: `$(file-symlink-file) Open Files`, + description: `\u00a0 \u2014 \u00a0\u00a0 as of \u00a0 $(git-commit) \u00a0 ${commit.sha}` + //detail: `Opens all of the changed files in $(git-commit) ${commit.sha}` + }); + } +} + +export class OpenCommitWorkingTreeFilesCommandQuickPickItem extends OpenFilesCommandQuickPickItem { + + constructor(commit: GitLogCommit, versioned: boolean = false, item?: QuickPickItem) { + const repoPath = commit.repoPath; const uris = commit.fileStatuses.map(_ => Uri.file(path.resolve(repoPath, _.fileName))); super(uris, item || { - label: `$(file-symlink-file) Open Working Tree Files`, - description: undefined, - detail: `Opens all of the files in commit $(git-commit) ${commit.sha}` + label: `$(file-symlink-file) Open Working Files`, + description: undefined + //detail: `Opens all of the changed file in the working tree` }); } } @@ -49,7 +73,8 @@ export class CommitDetailsQuickPick { description: `\u00a0 \u2014 \u00a0\u00a0 $(git-commit) ${commit.message}` }, Commands.CopyMessageToClipboard, [uri, commit.sha, commit.message])); - items.splice(2, 0, new OpenCommitFilesCommandQuickPickItem(commit)); + items.splice(2, 0, new OpenCommitWorkingTreeFilesCommandQuickPickItem(commit)); + items.splice(3, 0, new OpenCommitFilesCommandQuickPickItem(commit)); if (goBackCommand) { items.splice(0, 0, goBackCommand); @@ -117,6 +142,7 @@ export class CommitFileDetailsQuickPick { description: `\u00a0 \u2014 \u00a0\u00a0 $(git-commit) ${commit.message}` }, Commands.CopyMessageToClipboard, [uri, commit.sha, commit.message])); + items.push(new OpenCommitWorkingTreeFileCommandQuickPickItem(commit)); items.push(new OpenCommitFileCommandQuickPickItem(commit)); if (options.showFileHistory) {