Skip to content

Commit

Permalink
Fix mrcrowl#100: Add purge support
Browse files Browse the repository at this point in the history
  • Loading branch information
hdpoliveira committed Jul 3, 2020
1 parent 41f69b7 commit 58fc04a
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 0 deletions.
54 changes: 54 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,23 @@
"title": "%command.pull%",
"category": "Hg"
},
{
"command": "hg.purge",
"title": "%command.purge%",
"category": "Hg",
"icon": "$(discard)"
},
{
"command": "hg.purgeFiles",
"title": "%command.purgeFiles%",
"category": "Hg",
"icon": "$(discard)"
},
{
"command": "hg.purgeAll",
"title": "%command.purgeAll%",
"category": "Hg"
},
{
"command": "hg.push",
"title": "%command.push%",
Expand Down Expand Up @@ -444,6 +461,18 @@
"command": "hg.pull",
"when": "config.hg.enabled && !hg.missing && hgOpenRepositoryCount != 0"
},
{
"command": "hg.purge",
"when": "false"
},
{
"command": "hg.purgeFiles",
"when": "config.hg.enabled && !hg.missing && hgOpenRepositoryCount != 0"
},
{
"command": "hg.purgeAll",
"when": "config.hg.enabled && !hg.missing && hgOpenRepositoryCount != 0"
},
{
"command": "hg.push",
"when": "config.hg.enabled && !hg.missing && hgOpenRepositoryCount != 0"
Expand Down Expand Up @@ -556,6 +585,11 @@
"group": "4_stage",
"when": "config.hg.enabled && !hg.missing && scmProvider == hg"
},
{
"command": "hg.purgeAll",
"group": "4_stage",
"when": "config.hg.enabled && !hg.missing && scmProvider == hg"
},
{
"command": "hg.mergeHeads",
"group": "5_merge",
Expand Down Expand Up @@ -615,6 +649,16 @@
"when": "config.hg.enabled && !hg.missing && scmProvider == hg && scmResourceGroup == untracked",
"group": "1_modification"
},
{
"command": "hg.purgeFiles",
"when": "config.hg.enabled && !hg.missing && scmProvider == hg && scmResourceGroup == untracked",
"group": "1_modification"
},
{
"command": "hg.purgeFiles",
"when": "config.hg.enabled && !hg.missing && scmProvider == hg && scmResourceGroup == untracked",
"group": "inline1"
},
{
"command": "hg.addAll",
"when": "config.hg.enabled && !hg.missing && scmProvider == hg && scmResourceGroup == untracked",
Expand Down Expand Up @@ -702,11 +746,21 @@
"when": "config.hg.enabled && !hg.missing && scmProvider == hg && scmResourceGroup == working",
"group": "inline"
},
{
"command": "hg.purge",
"when": "config.hg.enabled && !hg.missing && scmProvider == hg && scmResourceGroup == untracked",
"group": "inline1"
},
{
"command": "hg.add",
"when": "config.hg.enabled && !hg.missing && scmProvider == hg && scmResourceGroup == untracked",
"group": "inline"
},
{
"command": "hg.purge",
"when": "config.hg.enabled && !hg.missing && scmProvider == hg && scmResourceGroup == untracked",
"group": "1_modification"
},
{
"command": "hg.add",
"when": "config.hg.enabled && !hg.missing && scmProvider == hg && scmResourceGroup == untracked",
Expand Down
3 changes: 3 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
"command.update": "Update to...",
"command.branch": "Create Branch...",
"command.pull": "Pull",
"command.purge": "Purge",
"command.purgeFiles": "Purge All Untracked Files",
"command.purgeAll": "Purge All Untracked and Ignored Files",
"command.push": "Push",
"command.pushTo": "Push to...",
"command.add": "Add Files",
Expand Down
44 changes: 44 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,50 @@ export class CommandCenter {
}
}

@command('hg.purgeFiles', { repository: true })
async purgeFiles(repository: Repository): Promise<void> {
return this._purge(repository.untrackedGroup.resources);
}

@command('hg.purgeAll', { repository: true })
async purgeAll(repository: Repository): Promise<void> {
if (await interaction.confirmDeleteUntrackedAndIgnored()) {
return await repository.purgeAll();
}
}

@command('hg.purge')
async purge(...resourceStates: SourceControlResourceState[]): Promise<void> {
if (resourceStates.length === 0) {
const resource = this.getSCMResource();

if (!resource) {
return;
}

resourceStates = [resource];
}

const scmResources = resourceStates
.filter(s => s instanceof Resource && s.resourceGroup instanceof UntrackedGroup) as Resource[];
return this._purge(scmResources);
}

private async _purge(scmResources: Resource[]): Promise<void> {
if (!scmResources.length) {
return;
}

const fileNames = scmResources.map(r => path.basename(r.resourceUri.fsPath));
const confirmed = await interaction.confirmDeleteFiles(fileNames);
if (!confirmed) {
return;
}

const resources = scmResources.map(r => r.resourceUri);
await this.runByRepository(resources, async (repository, uris) => repository.purge(...uris));
}

private async smartCommit(repository: Repository, getCommitMessage: () => Promise<string | undefined>, opts: CommitOptions = {}): Promise<boolean> {
// validate no conflicts
const numConflictResources = repository.conflictGroup.resources.length;
Expand Down
23 changes: 23 additions & 0 deletions src/hg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ export interface UnshelveOptions {
keep?: boolean;
}

export interface PurgeOptions {
paths?: string[];
all?: boolean;
}

export interface IMergeResult {
unresolvedCount: number;
}
Expand Down Expand Up @@ -360,6 +365,7 @@ export const HgErrorCodes = {
CantAccessRemote: 'CantAccessRemote',
RepositoryNotFound: 'RepositoryNotFound',
NoSuchFile: 'NoSuchFile',
ExtensionMissing: 'ExtensionMissing',
BranchAlreadyExists: 'BranchAlreadyExists',
NoRollbackInformationAvailable: 'NoRollbackInformationAvailable',
UntrackedFilesDiffer: 'UntrackedFilesDiffer',
Expand Down Expand Up @@ -506,6 +512,10 @@ export class Hg {
else if (/no such file/.test(result.stderr)) {
hgErrorCode = HgErrorCodes.NoSuchFile;
}
else if (/unknown command/.test(result.stderr)) {
hgErrorCode = HgErrorCodes.ExtensionMissing;
result.stderr = result.stderr.replace(/.*(unknown command '.*?').*/s, '$1');
}

if (options.logErrors !== false && result.stderr) {
this.log(`${result.stderr}\n`);
Expand Down Expand Up @@ -888,6 +898,19 @@ export class Repository {
}
}

async purge(opts: PurgeOptions): Promise<void> {
const args = ['purge'];

if (opts.paths && opts.paths.length) {
args.push.apply(args, opts.paths);
}
if (opts.all) {
args.push('--all');
}

await this.run(args);
}

async unshelveAbort(): Promise<void> {
await this.run(['unshelve', '--abort']);
}
Expand Down
28 changes: 28 additions & 0 deletions src/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ export namespace interaction {
message = localize('unshelve in progress', "There is already an unshelve operation in progress.");
options.modal = false;
break;
case HgErrorCodes.ExtensionMissing:
message = localize('extension missing', "Extension missing: {0}", err.stderr);
options.modal = false;
break;

default: {
const hint = (err.stderr || err.message || String(err))
Expand Down Expand Up @@ -558,6 +562,30 @@ export namespace interaction {
return choice === discard;
}

export async function confirmDeleteUntrackedAndIgnored(this: void): Promise<boolean> {
const message = localize('confirm delete all untracked and ignored',
"Are you sure you want to delete ALL untracked and ignored files?\nThis is IRREVERSIBLE!");
const deleteOption = localize('delete all', "Delete All");
const choice = await window.showWarningMessage(message, { modal: true }, deleteOption);
return choice === deleteOption;
}

export async function confirmDeleteFiles(fileNames: string[]): Promise<boolean> {
let message: string;

if (fileNames.length === 1) {
message = localize('confirm delete', "Are you sure you want to delete '{0}'?\nThis is IRREVERSIBLE!", path.basename(fileNames[0]));
}
else {
const fileList = humanise.formatFilesAsBulletedList(fileNames);
message = localize('confirm delete multiple', "Are you sure you want to delete {0} files?\n\n{1}\n\nThis is IRREVERSIBLE!", fileNames.length, fileList);
}

const deleteOption = localize('delete', "Delete");
const choice = await window.showWarningMessage(message, { modal: true }, deleteOption);
return choice === deleteOption;
}

export async function confirmDeleteMissingFilesForCommit(filenames: string[]): Promise<boolean> {
let message: string;
if (filenames.length === 1) {
Expand Down
12 changes: 12 additions & 0 deletions src/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,18 @@ export class Repository implements IDisposable {
});
}

@throttle
async purge(...uris: Uri[]): Promise<void> {
const resources = this.mapResources(uris);
const relativePaths: string[] = resources.map(r => this.mapResourceToRepoRelativePath(r));
await this.run(Operation.Clean, () => this.repository.purge({paths: relativePaths}));
}

@throttle
async purgeAll(): Promise<void> {
await this.run(Operation.Clean, () => this.repository.purge({all: true}));
}

@throttle
async branch(name: string, opts?: { allowBranchReuse: boolean }): Promise<void> {
const hgOpts = opts && {
Expand Down

0 comments on commit 58fc04a

Please sign in to comment.