Browse Source

WIP of Stash Explorer commands

# Conflicts:
#	src/commands/stashApply.ts
main
rebornix 7 years ago
committed by Eric Amodio
parent
commit
b81d873a34
8 changed files with 106 additions and 37 deletions
  1. +1
    -0
      images/dark/icon-add.svg
  2. +1
    -0
      images/light/icon-add.svg
  3. +25
    -1
      package.json
  4. +44
    -29
      src/commands/stashApply.ts
  5. +15
    -2
      src/commands/stashDelete.ts
  6. +4
    -2
      src/views/explorerNode.ts
  7. +10
    -1
      src/views/stashCommitNode.ts
  8. +6
    -2
      src/views/stashExplorer.ts

+ 1
- 0
images/dark/icon-add.svg View File

@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#C5C5C5"/><rect height="3" width="11" y="7" x="3" fill="#C5C5C5"/></svg>

+ 1
- 0
images/light/icon-add.svg View File

@ -0,0 +1 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#424242"/><rect height="3" width="11" y="7" x="3" fill="#424242"/></svg>

+ 25
- 1
package.json View File

@ -948,9 +948,18 @@
"category": "GitLens"
},
{
"command": "gitlens.stashDelete",
"title": "Delete Stashed Changes",
"category": "GitLens"
},
{
"command": "gitlens.stashSave",
"title": "Stash Changes",
"category": "GitLens"
"category": "GitLens",
"icon": {
"dark": "images/dark/icon-add.svg",
"light": "images/light/icon-add.svg"
}
},
{
"command": "gitlens.resetSuppressedWarnings",
@ -1312,6 +1321,11 @@
"command": "gitlens.stashExplorer.refresh",
"when": "gitlens:enabled && view == gitlens.stashExplorer",
"group": "navigation"
},
{
"command": "gitlens.stashSave",
"when": "gitlens:enabled && view == gitlens.stashExplorer",
"group": "navigation"
}
],
"view/item/context": [
@ -1354,6 +1368,16 @@
"command": "gitlens.diffWithWorking",
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == commit-file",
"group": "2_gitlens@2"
},
{
"command": "gitlens.stashApply",
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == stash-commit",
"group": "3_gitlens@1"
},
{
"command": "gitlens.stashDelete",
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == stash-commit",
"group": "3_gitlens@1"
}
]
},

+ 44
- 29
src/commands/stashApply.ts View File

@ -7,6 +7,7 @@ import { GlyphChars } from '../constants';
import { CommitQuickPickItem, StashListQuickPick } from '../quickPicks';
import { Logger } from '../logger';
import { CommandQuickPickItem } from '../quickPicks';
import { StashCommitNode } from '../views/stashCommitNode';
export interface StashApplyCommandArgs {
confirm?: boolean;
@ -22,45 +23,59 @@ export class StashApplyCommand extends Command {
super(Commands.StashApply);
}
async execute(args: StashApplyCommandArgs = { confirm: true, deleteAfter: false }) {
async execute(args: StashApplyCommandArgs | StashCommitNode = { confirm: true, deleteAfter: false }) {
if (!this.git.repoPath) return undefined;
args = { ...args };
if (args.stashItem === undefined || args.stashItem.stashName === undefined) {
const stash = await this.git.getStashList(this.git.repoPath);
if (stash === undefined) return window.showInformationMessage(`There are no stashed changes`);
if (args instanceof StashCommitNode) {
try {
const ret = await this.git.stashApply(this.git.repoPath, args.commit.stashName, false);
args.refreshNode();
return ret;
} catch (ex) {
return this._errorHandling(ex);
}
} else {
args = { ...args };
if (args.stashItem === undefined || args.stashItem.stashName === undefined) {
const stash = await this.git.getStashList(this.git.repoPath);
if (stash === undefined) return window.showInformationMessage(`There are no stashed changes`);
const currentCommand = new CommandQuickPickItem({
label: `go back ${GlyphChars.ArrowBack}`,
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to apply stashed changes`
}, Commands.StashApply, [args]);
const currentCommand = new CommandQuickPickItem({
label: `go back ${GlyphChars.ArrowBack}`,
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to apply stashed changes`
}, Commands.StashApply, [args]);
const pick = await StashListQuickPick.show(this.git, stash, 'apply', args.goBackCommand, currentCommand);
if (pick === undefined || !(pick instanceof CommitQuickPickItem)) return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute();
const pick = await StashListQuickPick.show(this.git, stash, 'apply', args.goBackCommand, currentCommand);
if (pick === undefined || !(pick instanceof CommitQuickPickItem)) return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute();
args.goBackCommand = currentCommand;
args.stashItem = pick.commit as GitStashCommit;
}
args.goBackCommand = currentCommand;
args.stashItem = pick.commit as GitStashCommit;
}
try {
if (args.confirm) {
const message = args.stashItem.message.length > 80 ? `${args.stashItem.message.substring(0, 80)}${GlyphChars.Ellipsis}` : args.stashItem.message;
const result = await window.showWarningMessage(`Apply stashed changes '${message}' to your working tree?`, { title: 'Yes, delete after applying' } as MessageItem, { title: 'Yes' } as MessageItem, { title: 'No', isCloseAffordance: true } as MessageItem);
if (result === undefined || result.title === 'No') return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute();
try {
if (args.confirm) {
const message = args.stashItem.message.length > 80 ? `${args.stashItem.message.substring(0, 80)}${GlyphChars.Ellipsis}` : args.stashItem.message;
const result = await window.showWarningMessage(`Apply stashed changes '${message}' to your working tree?`, { title: 'Yes, delete after applying' } as MessageItem, { title: 'Yes' } as MessageItem, { title: 'No', isCloseAffordance: true } as MessageItem);
if (result === undefined || result.title === 'No') return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute();
args.deleteAfter = result.title !== 'Yes';
}
args.deleteAfter = result.title !== 'Yes';
}
return await this.git.stashApply(this.git.repoPath, args.stashItem.stashName, args.deleteAfter);
}
catch (ex) {
Logger.error(ex, 'StashApplyCommand');
if (ex.message.includes('Your local changes to the following files would be overwritten by merge')) {
return window.showErrorMessage(`Unable to apply stash. Your working tree changes would be overwritten.`);
return await this.git.stashApply(this.git.repoPath, args.stashItem.stashName, args.deleteAfter);
}
else {
return window.showErrorMessage(`Unable to apply stash. See output channel for more details`);
catch (ex) {
return this._errorHandling(ex);
}
}
}
private _errorHandling(ex: any) {
Logger.error(ex, 'StashApplyCommand');
if (ex.message.includes('Your local changes to the following files would be overwritten by merge')) {
return window.showErrorMessage(`Unable to apply stash. Your working tree changes would be overwritten.`);
}
else {
return window.showErrorMessage(`Unable to apply stash. See output channel for more details`);
}
}
}

+ 15
- 2
src/commands/stashDelete.ts View File

@ -5,6 +5,7 @@ import { GlyphChars } from '../constants';
import { GitService } from '../gitService';
import { Logger } from '../logger';
import { CommandQuickPickItem } from '../quickPicks';
import { StashCommitNode } from '../views/stashCommitNode';
export interface StashDeleteCommandArgs {
confirm?: boolean;
@ -19,8 +20,16 @@ export class StashDeleteCommand extends Command {
super(Commands.StashDelete);
}
async execute(args: StashDeleteCommandArgs = { confirm: true }) {
async execute(args: StashDeleteCommandArgs | StashCommitNode = { confirm: true }) {
if (!this.git.repoPath) return undefined;
let stashCommitNode = undefined;
if (args instanceof StashCommitNode) {
stashCommitNode = args;
args = {
confirm: true,
stashItem: args.commit
};
}
args = { ...args };
if (args.stashItem === undefined || args.stashItem.stashName === undefined) return undefined;
@ -36,7 +45,11 @@ export class StashDeleteCommand extends Command {
if (result === undefined || result.title !== 'Yes') return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute();
}
return await this.git.stashDelete(this.git.repoPath, args.stashItem.stashName);
const ret = await this.git.stashDelete(this.git.repoPath, args.stashItem.stashName);
if (stashCommitNode) {
stashCommitNode.refreshNode();
}
return ret;
}
catch (ex) {
Logger.error(ex, 'StashDeleteCommand');

+ 4
- 2
src/views/explorerNode.ts View File

@ -1,7 +1,6 @@
'use strict';
import { ExtensionContext, TreeItem } from 'vscode';
import { Event, ExtensionContext, TreeItem} from 'vscode';
import { GitService, GitUri } from '../gitService';
export declare type ResourceType = 'status' | 'branches' | 'repository' | 'branch-history' | 'file-history' | 'stash-history' | 'commit' | 'stash-commit' | 'commit-file';
export abstract class ExplorerNode {
@ -12,4 +11,7 @@ export abstract class ExplorerNode {
abstract getChildren(): ExplorerNode[] | Promise<ExplorerNode[]>;
abstract getTreeItem(): TreeItem | Promise<TreeItem>;
onDidChangeTreeData?: Event<ExplorerNode>;
refreshNode?(): void;
}

+ 10
- 1
src/views/stashCommitNode.ts View File

@ -1,5 +1,5 @@
'use strict';
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Event, EventEmitter, ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitFileNode } from './commitFileNode';
import { ExplorerNode, ResourceType } from './explorerNode';
import { CommitFormatter, GitService, GitStashCommit, GitUri } from '../gitService';
@ -8,6 +8,15 @@ export class StashCommitNode extends ExplorerNode {
readonly resourceType: ResourceType = 'stash-commit';
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
public get onDidChangeTreeData(): Event<ExplorerNode> {
return this._onDidChangeTreeData.event;
}
public refreshNode() {
this._onDidChangeTreeData.fire();
}
constructor(public readonly commit: GitStashCommit, context: ExtensionContext, git: GitService) {
super(new GitUri(commit.uri, commit), context, git);
}

+ 6
- 2
src/views/stashExplorer.ts View File

@ -2,7 +2,6 @@
import { commands, Event, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, Uri } from 'vscode';
import { ExplorerNode, StashNode } from './explorerNodes';
import { GitService, GitUri } from '../gitService';
import { StashCommitNode } from './stashCommitNode';
export * from './explorerNodes';
@ -10,7 +9,7 @@ export class StashExplorer implements TreeDataProvider {
private _node: ExplorerNode;
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
public get onDidChangeTreeData(): Event<StashCommitNode> {
public get onDidChangeTreeData(): Event<ExplorerNode> {
return this._onDidChangeTreeData.event;
}
@ -28,6 +27,11 @@ export class StashExplorer implements TreeDataProvider {
}
async getTreeItem(node: ExplorerNode): Promise<TreeItem> {
if (node.onDidChangeTreeData) {
node.onDidChangeTreeData(() => {
this._onDidChangeTreeData.fire();
});
}
return node.getTreeItem();
}

Loading…
Cancel
Save