diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index a1b6551223b..14988e8ee62 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -5,9 +5,10 @@ 'use strict'; -import { Uri, commands, scm, Disposable, SCMResourceGroup, SCMResource } from 'vscode'; -import { Model, Resource, ResourceGroup } from './model'; +import { Uri, commands, scm, Disposable, SCMResourceGroup, SCMResource, window } from 'vscode'; +import { Model, Resource } from './model'; import { log } from './util'; +import * as path from 'path'; type Command = (...args: any[]) => any; @@ -39,12 +40,31 @@ async function unstageAll(model: Model): Promise { return await model.unstage(); } -function clean(model: Model, resource: Resource): void { - log('clean', resource); +async function clean(model: Model, resource: Resource): Promise { + const basename = path.basename(resource.uri.fsPath); + const message = `Are you sure you want to clean changes in ${basename}?`; + const yes = 'Yes'; + const no = 'No, keep them'; + const pick = await window.showQuickPick([no, yes], { placeHolder: message }); + + if (pick !== yes) { + return; + } + + return await model.clean(resource); } -function cleanAll(model: Model, resourceGroup: ResourceGroup): void { - log('clean all', resourceGroup); +async function cleanAll(model: Model): Promise { + const message = `Are you sure you want to clean all changes?`; + const yes = 'Yes'; + const no = 'No, keep them'; + const pick = await window.showQuickPick([no, yes], { placeHolder: message }); + + if (pick !== yes) { + return; + } + + return await model.clean(...model.workingTreeGroup.resources); } function resolveURI(command: (t: SCMResource | SCMResourceGroup | undefined) => R): (uri: Uri) => R | undefined { @@ -83,8 +103,8 @@ export function registerCommands(model: Model): Disposable { commands.registerCommand('git.stageAll', compose(stageAll, catchErrors, bindModel)), commands.registerCommand('git.unstage', compose(unstage, catchErrors, bindModel, resolveURI)), commands.registerCommand('git.unstageAll', compose(unstageAll, catchErrors, bindModel)), - commands.registerCommand('git.clean', compose(clean, bindModel, resolveURI)), - commands.registerCommand('git.cleanAll', compose(cleanAll, bindModel, resolveURI)), + commands.registerCommand('git.clean', compose(clean, catchErrors, bindModel, resolveURI)), + commands.registerCommand('git.cleanAll', compose(cleanAll, catchErrors, bindModel)), ]; return Disposable.from(...disposables); diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index 65f9344fc28..1a33677e05f 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -116,9 +116,9 @@ export class ResourceGroup implements SCMResourceGroup { get id(): string { return this._id; } get label(): string { return this._label; } - get resources(): SCMResource[] { return this._resources; } + get resources(): Resource[] { return this._resources; } - constructor(private _id: string, private _label: string, private _resources: SCMResource[]) { + constructor(private _id: string, private _label: string, private _resources: Resource[]) { } } @@ -127,7 +127,7 @@ export class MergeGroup extends ResourceGroup { static readonly ID = 'merge'; - constructor(resources: SCMResource[]) { + constructor(resources: Resource[]) { super(MergeGroup.ID, 'Merge Changes', resources); } } @@ -136,7 +136,7 @@ export class IndexGroup extends ResourceGroup { static readonly ID = 'index'; - constructor(resources: SCMResource[]) { + constructor(resources: Resource[]) { super(IndexGroup.ID, 'Staged Changes', resources); } } @@ -145,7 +145,7 @@ export class WorkingTreeGroup extends ResourceGroup { static readonly ID = 'workingTree'; - constructor(resources: SCMResource[]) { + constructor(resources: Resource[]) { super(WorkingTreeGroup.ID, 'Changes', resources); } } @@ -299,4 +299,35 @@ export class Model { await this.repository.commit(message, opts); await this.updateNow(); } + + async clean(...resources: Resource[]): Promise { + const toClean: string[] = []; + const toCheckout: string[] = []; + + resources.forEach(r => { + switch (r.type) { + case Status.UNTRACKED: + case Status.IGNORED: + toClean.push(r.uri.fsPath); + break; + + default: + toCheckout.push(r.uri.fsPath); + break; + } + }); + + const promises: Promise[] = []; + + if (toClean.length > 0) { + promises.push(this.repository.clean(toClean)); + } + + if (toCheckout.length > 0) { + promises.push(this.repository.checkout('', toCheckout)); + } + + await Promise.all(promises); + await this.updateNow(); + } } \ No newline at end of file