diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ad76dd..264c1f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ### Added +- Adds a _Checkout_ command to file nodes in the views to replace the local file with the specified revision — closes [#684](https://github.com/eamodio/vscode-gitlens/issues/684) - Adds a prompt to enable the view to the _Show \* View_ commands when the specified view is disabled — closes [#710](https://github.com/eamodio/vscode-gitlens/issues/710) & [#711](https://github.com/eamodio/vscode-gitlens/issues/711) ### Removed diff --git a/package.json b/package.json index a81a52e..b882ebb 100644 --- a/package.json +++ b/package.json @@ -4320,19 +4320,29 @@ "group": "5_gitlens_1@1" }, { + "command": "gitlens.views.checkout", + "when": "viewItem =~ /gitlens:file:(commit|results)\\b/", + "group": "5_gitlens_1@2" + }, + { "command": "gitlens.views.applyChanges", "when": "!gitlens:readonly && viewItem == gitlens:file:stash", "group": "1_gitlens@1" }, { + "command": "gitlens.views.checkout", + "when": "!gitlens:readonly && viewItem == gitlens:file:stash", + "group": "1_gitlens@2" + }, + { "command": "gitlens.showQuickCommitDetails", "when": "viewItem =~ /gitlens:file\\b(?!(:stash|:status))/", - "group": "5_gitlens_2@2" + "group": "5_gitlens_2@1" }, { "command": "gitlens.showCommitInView", "when": "viewItem =~ /gitlens:file\\b(?!(:stash|:status))/", - "group": "5_gitlens_2@3" + "group": "5_gitlens_2@2" }, { "command": "gitlens.showQuickFileHistory", diff --git a/src/views/nodes/commitFileNode.ts b/src/views/nodes/commitFileNode.ts index d999dac..62a8b71 100644 --- a/src/views/nodes/commitFileNode.ts +++ b/src/views/nodes/commitFileNode.ts @@ -6,7 +6,7 @@ import { GlyphChars } from '../../constants'; import { Container } from '../../container'; import { CommitFormatter, GitFile, GitLogCommit, GitUri, StatusFileFormatter } from '../../git/gitService'; import { View } from '../viewBase'; -import { ResourceType, ViewNode, ViewRefNode } from './viewNode'; +import { ResourceType, ViewNode, ViewRefFileNode } from './viewNode'; export enum CommitFileNodeDisplayAs { CommitLabel = 1 << 0, @@ -19,7 +19,7 @@ export enum CommitFileNodeDisplayAs { File = FileLabel | StatusIcon } -export class CommitFileNode extends ViewRefNode { +export class CommitFileNode extends ViewRefFileNode { constructor( view: View, parent: ViewNode, @@ -31,6 +31,10 @@ export class CommitFileNode extends ViewRefNode { super(GitUri.fromFile(file, commit.repoPath, commit.sha), view, parent); } + get fileName(): string { + return this.file.fileName; + } + get priority(): number { return 0; } diff --git a/src/views/nodes/resultsFileNode.ts b/src/views/nodes/resultsFileNode.ts index 0c6e899..e11a8ad 100644 --- a/src/views/nodes/resultsFileNode.ts +++ b/src/views/nodes/resultsFileNode.ts @@ -5,9 +5,9 @@ import { Commands, DiffWithCommandArgs } from '../../commands'; import { Container } from '../../container'; import { GitFile, GitUri, StatusFileFormatter } from '../../git/gitService'; import { View } from '../viewBase'; -import { ResourceType, ViewNode } from './viewNode'; +import { ResourceType, ViewNode, ViewRefFileNode } from './viewNode'; -export class ResultsFileNode extends ViewNode { +export class ResultsFileNode extends ViewRefFileNode { constructor( view: View, parent: ViewNode, @@ -16,11 +16,15 @@ export class ResultsFileNode extends ViewNode { public readonly ref1: string, public readonly ref2: string ) { - super(GitUri.fromFile(file, repoPath, ref1 ? ref1 : ref2 ? ref2 : undefined), view, parent); + super(GitUri.fromFile(file, repoPath, ref1 || ref2), view, parent); + } + + get fileName(): string { + return this.file.fileName; } get ref() { - return this.ref1 ? this.ref1 : this.ref2 ? this.ref2 : undefined; + return this.ref1 || this.ref2; } getChildren(): ViewNode[] { diff --git a/src/views/nodes/viewNode.ts b/src/views/nodes/viewNode.ts index 4951f45..e2574c3 100644 --- a/src/views/nodes/viewNode.ts +++ b/src/views/nodes/viewNode.ts @@ -113,6 +113,10 @@ export abstract class ViewRefNode extends ViewNode extends ViewRefNode { + abstract get fileName(): string; +} + export interface PageableViewNode { readonly supportsPaging: boolean; maxCount: number | undefined; diff --git a/src/views/viewCommands.ts b/src/views/viewCommands.ts index d2fccca..039aa6c 100644 --- a/src/views/viewCommands.ts +++ b/src/views/viewCommands.ts @@ -34,6 +34,7 @@ import { StatusFileNode, TagNode, ViewNode, + ViewRefFileNode, ViewRefNode, viewSupportsNodeDismissal } from './nodes'; @@ -210,10 +211,8 @@ export class ViewCommands implements Disposable { return node.push({ force: force }); } - private async applyChanges(node: CommitFileNode | StashFileNode | ResultsFileNode) { - if (!(node instanceof CommitFileNode) && !(node instanceof ResultsFileNode)) { - return; - } + private async applyChanges(node: ViewRefFileNode) { + if (!(node instanceof ViewRefFileNode)) return; void (await this.openFile(node)); @@ -228,9 +227,13 @@ export class ViewCommands implements Disposable { } } - private checkout(node: ViewRefNode) { + private checkout(node: ViewRefNode | ViewRefFileNode) { if (!(node instanceof ViewRefNode)) return undefined; + if (node instanceof ViewRefFileNode) { + return Container.git.checkout(node.repoPath, node.ref, node.fileName); + } + return Container.git.checkout(node.repoPath, node.ref); } @@ -287,14 +290,11 @@ export class ViewCommands implements Disposable { Container.compareView.selectForCompare(node.repoPath, node.ref); } - private compareFileWithSelected(node: CommitFileNode | ResultsFileNode | StashFileNode) { - if ( - this._selectedFile === undefined || - (!(node instanceof CommitFileNode) && !(node instanceof ResultsFileNode)) || - node.ref === undefined - ) { + private compareFileWithSelected(node: ViewRefFileNode) { + if (this._selectedFile === undefined || !(node instanceof ViewRefFileNode) || node.ref === undefined) { return undefined; } + if (this._selectedFile.repoPath !== node.repoPath) { this.selectFileForCompare(node); return undefined; @@ -321,8 +321,8 @@ export class ViewCommands implements Disposable { private _selectedFile: CompareSelectedInfo | undefined; - private selectFileForCompare(node: CommitFileNode | ResultsFileNode | StashFileNode) { - if ((!(node instanceof CommitFileNode) && !(node instanceof ResultsFileNode)) || node.ref === undefined) return; + private selectFileForCompare(node: ViewRefFileNode) { + if (!(node instanceof ViewRefFileNode) || node.ref === undefined) return; this._selectedFile = { ref: node.ref, @@ -343,8 +343,8 @@ export class ViewCommands implements Disposable { void commands.executeCommand(BuiltInCommands.FocusFilesExplorer); } - private openChanges(node: CommitFileNode | ResultsFileNode | StashFileNode) { - if (!(node instanceof CommitFileNode) && !(node instanceof ResultsFileNode)) return undefined; + private openChanges(node: ViewRefFileNode) { + if (!(node instanceof ViewRefFileNode)) return undefined; const command = node.getCommand(); if (command === undefined || command.arguments === undefined) return undefined; @@ -354,8 +354,8 @@ export class ViewCommands implements Disposable { return commands.executeCommand(command.command, uri, args); } - private async openChangesWithWorking(node: CommitFileNode | ResultsFileNode | StashFileNode) { - if (!(node instanceof CommitFileNode) && !(node instanceof ResultsFileNode)) return undefined; + private async openChangesWithWorking(node: ViewRefFileNode) { + if (!(node instanceof ViewRefFileNode)) return undefined; const args: DiffWithWorkingCommandArgs = { showOptions: { @@ -375,15 +375,12 @@ export class ViewCommands implements Disposable { return commands.executeCommand(Commands.DiffWithWorking, node.uri, args); } - private openFile( - node: CommitFileNode | FileHistoryNode | LineHistoryNode | ResultsFileNode | StashFileNode | StatusFileNode - ) { + private openFile(node: ViewRefFileNode | StatusFileNode | FileHistoryNode | LineHistoryNode) { if ( - !(node instanceof CommitFileNode) && + !(node instanceof ViewRefFileNode) && + !(node instanceof StatusFileNode) && !(node instanceof FileHistoryNode) && - !(node instanceof LineHistoryNode) && - !(node instanceof ResultsFileNode) && - !(node instanceof StatusFileNode) + !(node instanceof LineHistoryNode) ) { return undefined; }