'use strict'; import { commands, env, TextDocumentShowOptions, Uri, window } from 'vscode'; import { CreatePullRequestActionContext, OpenPullRequestActionContext } from '../api/gitlens'; import { Commands, DiffWithCommandArgs, DiffWithPreviousCommandArgs, DiffWithWorkingCommandArgs, executeActionCommand, executeCommand, executeEditorCommand, GitActions, OpenFileAtRevisionCommandArgs, } from '../commands'; import { configuration, FileAnnotationType, ViewShowBranchComparison } from '../configuration'; import { BuiltInCommands, ContextKeys, setContext } from '../constants'; import { Container } from '../container'; import { GitReference, GitRevision } from '../git/git'; import { GitUri } from '../git/gitUri'; import { BranchesNode, BranchNode, BranchTrackingStatusNode, CommitFileNode, CommitNode, CompareBranchNode, ContributorNode, ContributorsNode, FileHistoryNode, FolderNode, LineHistoryNode, nodeSupportsClearing, PageableViewNode, PagerNode, PullRequestNode, RemoteNode, RemotesNode, RepositoryFolderNode, RepositoryNode, ResultsFileNode, ResultsFilesNode, StashFileNode, StashNode, StatusFileNode, TagNode, TagsNode, ViewNode, ViewRefFileNode, ViewRefNode, viewSupportsNodeDismissal, } from './nodes'; import { debug } from '../system'; import { runGitCommandInTerminal } from '../terminal'; interface CompareSelectedInfo { ref: string; repoPath: string | undefined; uri?: Uri; } export class ViewCommands { constructor() { commands.registerCommand( 'gitlens.views.copy', async (selection: ViewNode | ViewNode[]) => { selection = Array.isArray(selection) ? selection : [selection]; if (selection.length === 0) return; const data = selection .map(n => n.toClipboard?.()) .filter(s => s != null && s.length > 0) .join(','); await env.clipboard.writeText(data); }, this, ); commands.registerCommand( 'gitlens.views.refreshNode', (node: ViewNode, reset?: boolean) => { if (reset == null && PageableViewNode.is(node)) { node.limit = undefined; node.view.resetNodeLastKnownLimit(node); } return node.view.refreshNode(node, reset == null ? true : reset); }, this, ); commands.registerCommand( 'gitlens.views.expandNode', (node: ViewNode) => node.view.reveal(node, { select: false, focus: false, expand: 3 }), this, ); commands.registerCommand( 'gitlens.views.clearNode', (node: ViewNode) => nodeSupportsClearing(node) && node.clear(), this, ); commands.registerCommand( 'gitlens.views.dismissNode', (node: ViewNode) => viewSupportsNodeDismissal(node.view) && node.view.dismissNode(node), this, ); commands.registerCommand('gitlens.views.executeNodeCallback', (fn: () => Promise) => fn(), this); commands.registerCommand('gitlens.views.loadMoreChildren', (node: PagerNode) => node.loadMore(), this); commands.registerCommand('gitlens.views.loadAllChildren', (node: PagerNode) => node.loadAll(), this); commands.registerCommand( 'gitlens.views.setShowRelativeDateMarkersOn', () => this.setShowRelativeDateMarkers(true), this, ); commands.registerCommand( 'gitlens.views.setShowRelativeDateMarkersOff', () => this.setShowRelativeDateMarkers(false), this, ); commands.registerCommand('gitlens.views.fetch', this.fetch, this); commands.registerCommand('gitlens.views.publishBranch', this.publishBranch, this); commands.registerCommand('gitlens.views.pull', this.pull, this); commands.registerCommand('gitlens.views.push', this.push, this); commands.registerCommand('gitlens.views.pushWithForce', n => this.push(n, true), this); commands.registerCommand('gitlens.views.closeRepository', this.closeRepository, this); commands.registerCommand('gitlens.views.setAsDefault', this.setAsDefault, this); commands.registerCommand('gitlens.views.unsetAsDefault', this.unsetAsDefault, this); commands.registerCommand('gitlens.views.openInTerminal', this.openInTerminal, this); commands.registerCommand('gitlens.views.star', this.star, this); commands.registerCommand('gitlens.views.unstar', this.unstar, this); commands.registerCommand('gitlens.views.browseRepoAtRevision', this.browseRepoAtRevision, this); commands.registerCommand( 'gitlens.views.browseRepoAtRevisionInNewWindow', n => this.browseRepoAtRevision(n, true), this, ); commands.registerCommand('gitlens.views.addAuthors', this.addAuthors, this); commands.registerCommand('gitlens.views.addAuthor', this.addAuthors, this); commands.registerCommand('gitlens.views.openChanges', this.openChanges, this); commands.registerCommand('gitlens.views.openChangesWithWorking', this.openChangesWithWorking, this); commands.registerCommand('gitlens.views.openFile', this.openFile, this); commands.registerCommand('gitlens.views.openFileRevision', this.openRevision, this); commands.registerCommand('gitlens.views.openChangedFiles', this.openFiles, this); commands.registerCommand('gitlens.views.openChangedFileDiffs', this.openAllChanges, this); commands.registerCommand('gitlens.views.openChangedFileDiffsWithWorking', this.openAllChangesWithWorking, this); commands.registerCommand('gitlens.views.openChangedFileRevisions', this.openRevisions, this); commands.registerCommand('gitlens.views.applyChanges', this.applyChanges, this); commands.registerCommand('gitlens.views.highlightChanges', this.highlightChanges, this); commands.registerCommand('gitlens.views.highlightRevisionChanges', this.highlightRevisionChanges, this); commands.registerCommand('gitlens.views.restore', this.restore, this); commands.registerCommand('gitlens.views.switchToBranch', this.switch, this); commands.registerCommand('gitlens.views.switchToAnotherBranch', this.switch, this); commands.registerCommand('gitlens.views.switchToCommit', this.switch, this); commands.registerCommand('gitlens.views.switchToTag', this.switch, this); commands.registerCommand('gitlens.views.addRemote', this.addRemote, this); commands.registerCommand('gitlens.views.pruneRemote', this.pruneRemote, this); commands.registerCommand('gitlens.views.stageDirectory', this.stageDirectory, this); commands.registerCommand('gitlens.views.stageFile', this.stageFile, this); commands.registerCommand('gitlens.views.unstageDirectory', this.unstageDirectory, this); commands.registerCommand('gitlens.views.unstageFile', this.unstageFile, this); commands.registerCommand('gitlens.views.compareAncestryWithWorking', this.compareAncestryWithWorking, this); commands.registerCommand('gitlens.views.compareWithHead', this.compareWithHead, this); commands.registerCommand('gitlens.views.compareWithUpstream', this.compareWithUpstream, this); commands.registerCommand('gitlens.views.compareWithSelected', this.compareWithSelected, this); commands.registerCommand('gitlens.views.selectForCompare', this.selectForCompare, this); commands.registerCommand('gitlens.views.compareFileWithSelected', this.compareFileWithSelected, this); commands.registerCommand('gitlens.views.selectFileForCompare', this.selectFileForCompare, this); commands.registerCommand('gitlens.views.compareWithWorking', this.compareWithWorking, this); commands.registerCommand( 'gitlens.views.setBranchComparisonToWorking', n => this.setBranchComparison(n, ViewShowBranchComparison.Working), this, ); commands.registerCommand( 'gitlens.views.setBranchComparisonToBranch', n => this.setBranchComparison(n, ViewShowBranchComparison.Branch), this, ); commands.registerCommand('gitlens.views.cherryPick', this.cherryPick, this); commands.registerCommand('gitlens.views.createBranch', this.createBranch, this); commands.registerCommand('gitlens.views.deleteBranch', this.deleteBranch, this); commands.registerCommand('gitlens.views.renameBranch', this.renameBranch, this); commands.registerCommand('gitlens.views.deleteStash', this.deleteStash, this); commands.registerCommand('gitlens.views.createTag', this.createTag, this); commands.registerCommand('gitlens.views.deleteTag', this.deleteTag, this); commands.registerCommand('gitlens.views.mergeBranchInto', this.merge, this); commands.registerCommand('gitlens.views.pushToCommit', this.pushToCommit, this); commands.registerCommand('gitlens.views.rebaseOntoBranch', this.rebase, this); commands.registerCommand('gitlens.views.rebaseOntoUpstream', this.rebaseToRemote, this); commands.registerCommand('gitlens.views.rebaseOntoCommit', this.rebase, this); commands.registerCommand('gitlens.views.resetCommit', this.resetCommit, this); commands.registerCommand('gitlens.views.resetToCommit', this.resetToCommit, this); commands.registerCommand('gitlens.views.revert', this.revert, this); commands.registerCommand('gitlens.views.undoCommit', this.undoCommit, this); commands.registerCommand('gitlens.views.terminalRemoveRemote', this.terminalRemoveRemote, this); commands.registerCommand('gitlens.views.createPullRequest', this.createPullRequest, this); commands.registerCommand('gitlens.views.openPullRequest', this.openPullRequest, this); } @debug() private addAuthors(node?: ContributorNode | ContributorsNode) { if (node != null && !(node instanceof ContributorNode) && !(node instanceof ContributorsNode)) { return Promise.resolve(); } return GitActions.Contributor.addAuthors( node?.uri.repoPath, node instanceof ContributorNode ? node.contributor : undefined, ); } @debug() private addRemote(node?: RemotesNode) { return GitActions.Remote.add(node?.repoPath); } @debug() private applyChanges(node: ViewRefFileNode) { if (!(node instanceof ViewRefFileNode)) return Promise.resolve(); if (node instanceof ResultsFileNode) { return GitActions.Commit.applyChanges( node.file, GitReference.create(node.ref1, node.repoPath), GitReference.create(node.ref2, node.repoPath), ); } if (node.ref == null || node.ref.ref === 'HEAD') return Promise.resolve(); return GitActions.Commit.applyChanges(node.file, node.ref); } @debug() private cherryPick(node: CommitNode) { if (!(node instanceof CommitNode)) return Promise.resolve(); return GitActions.cherryPick(node.repoPath, node.ref); } @debug() private closeRepository(node: RepositoryNode | RepositoryFolderNode) { if (!(node instanceof RepositoryNode) && !(node instanceof RepositoryFolderNode)) return; node.repo.closed = true; } @debug() private createBranch(node?: ViewRefNode | BranchesNode) { return GitActions.Branch.create(node?.repoPath, node instanceof ViewRefNode ? node?.ref : undefined); } @debug() private async createPullRequest(node: BranchNode | BranchTrackingStatusNode) { if (!(node instanceof BranchNode) && !(node instanceof BranchTrackingStatusNode)) { return Promise.resolve(); } const remote = await node.branch.getRemote(); return executeActionCommand('createPullRequest', { branch: { name: node.branch.name, remote: remote != null ? { name: remote.name, provider: remote.provider?.name, url: remote.url, } : undefined, repoPath: node.repoPath, }, }); } @debug() private createTag(node?: ViewRefNode | TagsNode) { return GitActions.Tag.create(node?.repoPath, node instanceof ViewRefNode ? node?.ref : undefined); } @debug() private deleteBranch(node: BranchNode) { if (!(node instanceof BranchNode)) return Promise.resolve(); return GitActions.Branch.remove(node.repoPath, node.branch); } @debug() private deleteStash(node: StashNode) { if (!(node instanceof StashNode)) return Promise.resolve(); return GitActions.Stash.drop(node.repoPath, node.commit); } @debug() private deleteTag(node: TagNode) { if (!(node instanceof TagNode)) return Promise.resolve(); return GitActions.Tag.remove(node.repoPath, node.tag); } @debug() private browseRepoAtRevision(node: ViewRefNode, openInNewWindow: boolean = false) { if (!(node instanceof ViewRefNode)) return Promise.resolve(); return GitActions.browseAtRevision(node.uri, { openInNewWindow: openInNewWindow }); } @debug() private fetch(node: RemoteNode | RepositoryNode | BranchNode | BranchTrackingStatusNode) { if (node instanceof RepositoryNode) return GitActions.fetch(node.repo); if (node instanceof RemoteNode) return GitActions.Remote.fetch(node.remote.repoPath, node.remote.name); if (node instanceof BranchNode || node instanceof BranchTrackingStatusNode) { return GitActions.fetch(node.repoPath, node.root ? undefined : node.branch); } return Promise.resolve(); } @debug() private async highlightChanges(node: CommitFileNode | ResultsFileNode | StashFileNode) { if ( !(node instanceof CommitFileNode) && !(node instanceof StashFileNode) && !(node instanceof ResultsFileNode) ) { return; } void (await this.openFile(node)); void (await Container.fileAnnotations.toggle( window.activeTextEditor, FileAnnotationType.Changes, node.ref.ref, true, )); } @debug() private async highlightRevisionChanges(node: CommitFileNode | ResultsFileNode | StashFileNode) { if ( !(node instanceof CommitFileNode) && !(node instanceof StashFileNode) && !(node instanceof ResultsFileNode) ) { return; } void (await this.openRevision(node, { showOptions: { preserveFocus: true, preview: true } })); void (await Container.fileAnnotations.toggle( window.activeTextEditor, FileAnnotationType.Changes, node.ref.ref, true, )); } @debug() private merge(node: BranchNode | TagNode) { if (!(node instanceof BranchNode) && !(node instanceof TagNode)) return Promise.resolve(); return GitActions.merge(node.repoPath, node instanceof BranchNode ? node.branch : node.tag); } @debug() private pushToCommit(node: CommitNode | CommitFileNode) { if (!(node instanceof CommitNode) && !(node instanceof CommitFileNode)) return Promise.resolve(); return GitActions.push(node.repoPath, false, node.commit); } @debug() private openPullRequest(node: PullRequestNode) { if (!(node instanceof PullRequestNode)) return Promise.resolve(); return executeActionCommand('openPullRequest', { pullRequest: { id: node.pullRequest.id, provider: node.pullRequest.provider, repoPath: node.uri.repoPath!, url: node.pullRequest.url, }, }); } @debug() private openInTerminal(node: RepositoryNode | RepositoryFolderNode) { if (!(node instanceof RepositoryNode) && !(node instanceof RepositoryFolderNode)) return Promise.resolve(); return commands.executeCommand(BuiltInCommands.OpenInTerminal, Uri.file(node.repo.path)); } @debug() private async pruneRemote(node: RemoteNode) { if (!(node instanceof RemoteNode)) return Promise.resolve(); return GitActions.Remote.prune(node.repo, node.remote.name); } @debug() private publishBranch(node: BranchNode | BranchTrackingStatusNode) { if (node instanceof BranchNode || node instanceof BranchTrackingStatusNode) { return GitActions.push(node.repoPath, undefined, node.branch); } return Promise.resolve(); } @debug() private pull(node: RepositoryNode | BranchNode | BranchTrackingStatusNode) { if (node instanceof RepositoryNode) return GitActions.pull(node.repo); if (node instanceof BranchNode || node instanceof BranchTrackingStatusNode) { return GitActions.pull(node.repoPath, node.root ? undefined : node.branch); } return Promise.resolve(); } @debug() private push(node: RepositoryNode | BranchNode | BranchTrackingStatusNode, force?: boolean) { if (node instanceof RepositoryNode) return GitActions.push(node.repo, force); if (node instanceof BranchNode || node instanceof BranchTrackingStatusNode) { return GitActions.push(node.repoPath, undefined, node.root ? undefined : node.branch); } return Promise.resolve(); } @debug() private rebase(node: BranchNode | CommitNode | CommitFileNode | TagNode) { if ( !(node instanceof BranchNode) && !(node instanceof CommitNode) && !(node instanceof CommitFileNode) && !(node instanceof TagNode) ) { return Promise.resolve(); } return GitActions.rebase(node.repoPath, node.ref); } @debug() private rebaseToRemote(node: BranchNode | BranchTrackingStatusNode) { if (!(node instanceof BranchNode) && !(node instanceof BranchTrackingStatusNode)) return Promise.resolve(); const upstream = node instanceof BranchNode ? node.branch.tracking : node.status.upstream; if (upstream == null) return Promise.resolve(); return GitActions.rebase( node.repoPath, GitReference.create(upstream, node.repoPath, { refType: 'branch', name: upstream, remote: true, }), ); } @debug() private renameBranch(node: BranchNode) { if (!(node instanceof BranchNode)) return Promise.resolve(); return GitActions.Branch.rename(node.repoPath, node.branch); } @debug() private resetCommit(node: CommitNode | CommitFileNode) { if (!(node instanceof CommitNode) && !(node instanceof CommitFileNode)) return Promise.resolve(); return GitActions.reset( node.repoPath, GitReference.create(`${node.ref.ref}^`, node.ref.repoPath, { refType: 'revision', name: `${node.ref.name}^`, message: node.ref.message, }), ); } @debug() private resetToCommit(node: CommitNode | CommitFileNode) { if (!(node instanceof CommitNode) && !(node instanceof CommitFileNode)) return Promise.resolve(); return GitActions.reset(node.repoPath, node.ref); } @debug() private restore(node: ViewRefFileNode) { if (!(node instanceof ViewRefFileNode)) return Promise.resolve(); return GitActions.Commit.restoreFile(node.fileName, node.ref); } @debug() private revert(node: CommitNode | CommitFileNode) { if (!(node instanceof CommitNode) && !(node instanceof CommitFileNode)) return Promise.resolve(); return GitActions.revert(node.repoPath, node.ref); } @debug() private setAsDefault(node: RemoteNode) { if (!(node instanceof RemoteNode)) return Promise.resolve(); return node.setAsDefault(); } @debug() private setBranchComparison(node: ViewNode, comparisonType: Exclude) { if (!(node instanceof CompareBranchNode)) return undefined; return node.setComparisonType(comparisonType); } @debug() private setShowRelativeDateMarkers(enabled: boolean) { return configuration.updateEffective('views', 'showRelativeDateMarkers', enabled); } @debug() private async stageFile(node: CommitFileNode | StatusFileNode) { if (!(node instanceof CommitFileNode) && !(node instanceof StatusFileNode)) return; void (await Container.git.stageFile(node.repoPath, node.file.fileName)); void node.triggerChange(); } @debug() private async stageDirectory(node: FolderNode) { if (!(node instanceof FolderNode) || !node.relativePath) return; void (await Container.git.stageDirectory(node.repoPath, node.relativePath)); void node.triggerChange(); } @debug() private star(node: BranchNode | RepositoryNode | RepositoryFolderNode) { if ( !(node instanceof BranchNode) && !(node instanceof RepositoryNode) && !(node instanceof RepositoryFolderNode) ) { return Promise.resolve(); } return node.star(); } @debug() private switch(node?: ViewRefNode | BranchesNode) { if (node == null) { return GitActions.switchTo(Container.git.getHighlanderRepoPath()); } if (!(node instanceof ViewRefNode) && !(node instanceof BranchesNode)) return Promise.resolve(); return GitActions.switchTo( node.repoPath, node instanceof BranchesNode || (node instanceof BranchNode && node.branch.current) ? undefined : node.ref, ); } @debug() private undoCommit(node: CommitNode | CommitFileNode) { if (!(node instanceof CommitNode) && !(node instanceof CommitFileNode)) return Promise.resolve(); return GitActions.reset( node.repoPath, GitReference.create(`${node.ref.ref}^`, node.ref.repoPath, { refType: 'revision', name: `${node.ref.name}^`, message: node.ref.message, }), ['--soft'], ); } @debug() private unsetAsDefault(node: RemoteNode) { if (!(node instanceof RemoteNode)) return Promise.resolve(); return node.setAsDefault(false); } @debug() private async unstageFile(node: CommitFileNode | StatusFileNode) { if (!(node instanceof CommitFileNode) && !(node instanceof StatusFileNode)) return; void (await Container.git.unStageFile(node.repoPath, node.file.fileName)); void node.triggerChange(); } @debug() private async unstageDirectory(node: FolderNode) { if (!(node instanceof FolderNode) || !node.relativePath) return; void (await Container.git.unStageDirectory(node.repoPath, node.relativePath)); void node.triggerChange(); } @debug() private unstar(node: BranchNode | RepositoryNode | RepositoryFolderNode) { if ( !(node instanceof BranchNode) && !(node instanceof RepositoryNode) && !(node instanceof RepositoryFolderNode) ) { return Promise.resolve(); } return node.unstar(); } @debug() private compareWithHead(node: ViewRefNode) { if (!(node instanceof ViewRefNode)) return Promise.resolve(); return Container.searchAndCompareView.compare(node.repoPath, node.ref, 'HEAD'); } @debug() private compareWithUpstream(node: BranchNode) { if (!(node instanceof BranchNode)) return Promise.resolve(); if (!node.branch.tracking) return Promise.resolve(); return Container.searchAndCompareView.compare(node.repoPath, node.branch.tracking, node.ref); } @debug() private compareWithWorking(node: ViewRefNode) { if (!(node instanceof ViewRefNode)) return Promise.resolve(); return Container.searchAndCompareView.compare(node.repoPath, node.ref, ''); } @debug() private async compareAncestryWithWorking(node: BranchNode) { if (!(node instanceof BranchNode)) return undefined; const branch = await Container.git.getBranch(node.repoPath); if (branch == null) return undefined; const commonAncestor = await Container.git.getMergeBase(node.repoPath, branch.ref, node.ref.ref); if (commonAncestor == null) return undefined; return Container.searchAndCompareView.compare( node.repoPath, { ref: commonAncestor, label: `ancestry with ${node.ref.ref} (${GitRevision.shorten(commonAncestor)})` }, '', ); } @debug() private compareWithSelected(node: ViewRefNode) { if (!(node instanceof ViewRefNode)) return; Container.searchAndCompareView.compareWithSelected(node.repoPath, node.ref); } @debug() private selectForCompare(node: ViewRefNode) { if (!(node instanceof ViewRefNode)) return; Container.searchAndCompareView.selectForCompare(node.repoPath, node.ref); } @debug() private compareFileWithSelected(node: ViewRefFileNode) { if (this._selectedFile == null || !(node instanceof ViewRefFileNode) || node.ref == null) { return Promise.resolve(); } if (this._selectedFile.repoPath !== node.repoPath) { this.selectFileForCompare(node); return Promise.resolve(); } const selected = this._selectedFile; this._selectedFile = undefined; void setContext(ContextKeys.ViewsCanCompareFile, false); return executeCommand(Commands.DiffWith, { repoPath: selected.repoPath, lhs: { sha: selected.ref, uri: selected.uri!, }, rhs: { sha: node.ref.ref, uri: node.uri, }, }); } private _selectedFile: CompareSelectedInfo | undefined; @debug() private selectFileForCompare(node: ViewRefFileNode) { if (!(node instanceof ViewRefFileNode) || node.ref == null) return; this._selectedFile = { ref: node.ref.ref, repoPath: node.repoPath, uri: node.uri, }; void setContext(ContextKeys.ViewsCanCompareFile, true); } @debug() private async openAllChanges(node: CommitNode | StashNode | ResultsFilesNode, options?: TextDocumentShowOptions) { if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) { return undefined; } if (node instanceof ResultsFilesNode) { const { files: diff } = await node.getFilesQueryResults(); if (diff == null || diff.length === 0) return undefined; return GitActions.Commit.openAllChanges( diff, { repoPath: node.repoPath, ref1: node.ref1, ref2: node.ref2, }, options, ); } return GitActions.Commit.openAllChanges(node.commit, options); } @debug() private openChanges(node: ViewRefFileNode | StatusFileNode) { if (!(node instanceof ViewRefFileNode) && !(node instanceof StatusFileNode)) return; const command = node.getCommand(); if (command?.arguments == null) return; switch (command.command) { case Commands.DiffWith: { const [args] = command.arguments as [DiffWithCommandArgs]; args.showOptions!.preview = false; void executeCommand(command.command, args); break; } case Commands.DiffWithPrevious: { const [, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs]; args.showOptions!.preview = false; void executeEditorCommand(command.command, undefined, args); break; } default: throw new Error(`Unexpected command: ${command.command}`); } // TODO@eamodio Revisit this // return GitActions.Commit.openChanges(node.file, node instanceof ViewRefFileNode ? node.ref : node.commit, { // preserveFocus: true, // preview: false, // }); } @debug() private async openAllChangesWithWorking( node: CommitNode | StashNode | ResultsFilesNode, options?: TextDocumentShowOptions, ) { if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) { return undefined; } if (node instanceof ResultsFilesNode) { const { files: diff } = await node.getFilesQueryResults(); if (diff == null || diff.length === 0) return undefined; return GitActions.Commit.openAllChangesWithWorking( diff, { repoPath: node.repoPath, ref: node.ref1 || node.ref2, }, options, ); } return GitActions.Commit.openAllChangesWithWorking(node.commit, options); // options = { preserveFocus: false, preview: false, ...options }; // let repoPath: string; // let files; // let ref: string; // if (node instanceof ResultsFilesNode) { // const { diff } = await node.getFilesQueryResults(); // if (diff == null || diff.length === 0) return; // repoPath = node.repoPath; // files = diff; // ref = node.ref1 || node.ref2; // } else { // repoPath = node.commit.repoPath; // files = node.commit.files; // ref = node.commit.sha; // } // if (files.length > 20) { // const result = await window.showWarningMessage( // `Are your sure you want to open all ${files.length} files?`, // { title: 'Yes' }, // { title: 'No', isCloseAffordance: true }, // ); // if (result == null || result.title === 'No') return; // } // for (const file of files) { // if (file.status === 'A' || file.status === 'D') continue; // const args: DiffWithWorkingCommandArgs = { // showOptions: options, // }; // const uri = GitUri.fromFile(file, repoPath, ref); // await commands.executeCommand(Commands.DiffWithWorking, uri, args); // } } @debug() private openChangesWithWorking(node: ViewRefFileNode | StatusFileNode) { if (!(node instanceof ViewRefFileNode) && !(node instanceof StatusFileNode)) return Promise.resolve(); if (node instanceof StatusFileNode) { return executeEditorCommand(Commands.DiffWithWorking, undefined, { uri: node.uri, showOptions: { preserveFocus: true, preview: true, }, }); } return GitActions.Commit.openChangesWithWorking(node.file, { repoPath: node.repoPath, ref: node.ref.ref }); } @debug() private openFile(node: ViewRefFileNode | StatusFileNode | FileHistoryNode | LineHistoryNode) { if ( !(node instanceof ViewRefFileNode) && !(node instanceof StatusFileNode) && !(node instanceof FileHistoryNode) && !(node instanceof LineHistoryNode) ) { return Promise.resolve(); } return GitActions.Commit.openFile(node.uri, { preserveFocus: true, preview: false, }); } @debug() private async openFiles(node: CommitNode | StashNode | ResultsFilesNode) { if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) { return undefined; } if (node instanceof ResultsFilesNode) { const { files: diff } = await node.getFilesQueryResults(); if (diff == null || diff.length === 0) return undefined; return GitActions.Commit.openFiles(diff, node.repoPath, node.ref1 || node.ref2); } return GitActions.Commit.openFiles(node.commit); } @debug() private openRevision( node: CommitFileNode | ResultsFileNode | StashFileNode | StatusFileNode, options?: OpenFileAtRevisionCommandArgs, ) { if ( !(node instanceof CommitFileNode) && !(node instanceof StashFileNode) && !(node instanceof ResultsFileNode) && !(node instanceof StatusFileNode) ) { return Promise.resolve(); } options = { showOptions: { preserveFocus: true, preview: false }, ...options }; let uri = options.revisionUri; if (uri == null) { if (node instanceof ResultsFileNode) { uri = GitUri.toRevisionUri(node.uri); } else { uri = node.commit.status === 'D' ? GitUri.toRevisionUri( node.commit.previousSha!, node.commit.previousUri.fsPath, node.commit.repoPath, ) : GitUri.toRevisionUri(node.uri); } } return GitActions.Commit.openFileAtRevision( uri, options.showOptions ?? { preserveFocus: true, preview: false }, ); } @debug() private async openRevisions(node: CommitNode | StashNode | ResultsFilesNode, _options?: TextDocumentShowOptions) { if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) { return undefined; } if (node instanceof ResultsFilesNode) { const { files: diff } = await node.getFilesQueryResults(); if (diff == null || diff.length === 0) return undefined; return GitActions.Commit.openFilesAtRevision(diff, node.repoPath, node.ref1, node.ref2); } return GitActions.Commit.openFilesAtRevision(node.commit); } private terminalRemoveRemote(node: RemoteNode) { if (!(node instanceof RemoteNode)) return; runGitCommandInTerminal('remote', `remove ${node.remote.name}`, node.remote.repoPath); } }