Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added support to revert from explorer (close #606) #608

Merged
merged 2 commits into from
Jun 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,15 @@
"dark": "icons/dark/clean.svg"
}
},
{
"command": "svn.revertExplorer",
"title": "Revert with SVN",
"category": "SVN",
"icon": {
"light": "icons/light/clean.svg",
"dark": "icons/dark/clean.svg"
}
},
{
"command": "svn.revertAll",
"title": "Revert All Changes",
Expand Down Expand Up @@ -483,6 +492,10 @@
"command": "svn.revert",
"when": "config.svn.enabled && svnOpenRepositoryCount != 0"
},
{
"command": "svn.revertExplorer",
"when": "false"
},
{
"command": "svn.update",
"when": "config.svn.enabled && svnOpenRepositoryCount != 0"
Expand Down Expand Up @@ -902,6 +915,11 @@
"command": "svn.changelist",
"group": "9_svn",
"when": "config.svn.enabled && svnOpenRepositoryCount != 0"
},
{
"command": "svn.revertExplorer",
"group": "7_modification",
"when": "config.svn.enabled && svnOpenRepositoryCount != 0"
}
]
},
Expand Down
2 changes: 2 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { Resolved } from "./commands/resolved";
import { Revert } from "./commands/revert";
import { RevertAll } from "./commands/revertAll";
import { RevertChange } from "./commands/revertChange";
import { RevertExplorer } from "./commands/revertExplorer";
import { RevertSelectedRanges } from "./commands/revertSelectedRanges";
import { SwitchBranch } from "./commands/switchBranch";
import { Update } from "./commands/update";
Expand Down Expand Up @@ -86,4 +87,5 @@ export function registerCommands(model: Model, disposables: Disposable[]) {
disposables.push(new OpenHeadFile());
disposables.push(new RevertAll());
disposables.push(new PickCommitMessage());
disposables.push(new RevertExplorer());
}
28 changes: 6 additions & 22 deletions src/commands/revert.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SourceControlResourceState, window } from "vscode";
import { SvnDepth } from "../common/types";
import { checkAndPromptDepth, confirmRevert } from "../input/revert";
import { Command } from "./command";

export class Revert extends Command {
Expand All @@ -10,33 +10,17 @@ export class Revert extends Command {
public async execute(...resourceStates: SourceControlResourceState[]) {
const selection = await this.getResourceStates(resourceStates);

if (selection.length === 0) {
if (selection.length === 0 || !(await confirmRevert())) {
return;
}

const yes = "Yes I'm sure";
const answer = await window.showWarningMessage(
"Are you sure? This will wipe all local changes.",
{ modal: true },
yes
);
const uris = selection.map(resource => resource.resourceUri);
const depth = await checkAndPromptDepth(uris);

if (answer !== yes) {
if (!depth) {
return;
}

const picks: any[] = [];

for (const depth in SvnDepth) {
if (SvnDepth.hasOwnProperty(depth)) {
picks.push({ label: depth, description: SvnDepth[depth] });
}
}

const placeHolder = "Select revert depth";
const pick = await window.showQuickPick(picks, { placeHolder });
const uris = selection.map(resource => resource.resourceUri);

await this.runByRepository(uris, async (repository, resources) => {
if (!repository) {
return;
Expand All @@ -45,7 +29,7 @@ export class Revert extends Command {
const paths = resources.map(resource => resource.fsPath);

try {
await repository.revert(paths, pick.label);
await repository.revert(paths, depth);
} catch (error) {
console.log(error);
window.showErrorMessage("Unable to revert");
Expand Down
28 changes: 6 additions & 22 deletions src/commands/revertAll.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SourceControlResourceGroup, window } from "vscode";
import { SvnDepth } from "../common/types";
import { checkAndPromptDepth, confirmRevert } from "../input/revert";
import { Command } from "./command";

export class RevertAll extends Command {
Expand All @@ -10,33 +10,17 @@ export class RevertAll extends Command {
public async execute(resourceGroup: SourceControlResourceGroup) {
const resourceStates = resourceGroup.resourceStates;

if (resourceStates.length === 0) {
if (resourceStates.length === 0 || !(await confirmRevert())) {
return;
}

const yes = "Yes I'm sure";
const answer = await window.showWarningMessage(
"Are you sure? This will wipe all local changes.",
{ modal: true },
yes
);
const uris = resourceStates.map(resource => resource.resourceUri);
const depth = await checkAndPromptDepth(uris);

if (answer !== yes) {
if (!depth) {
return;
}

const picks: any[] = [];

for (const depth in SvnDepth) {
if (SvnDepth.hasOwnProperty(depth)) {
picks.push({ label: depth, description: SvnDepth[depth] });
}
}

const placeHolder = "Select revert depth";
const pick = await window.showQuickPick(picks, { placeHolder });
const uris = resourceStates.map(resource => resource.resourceUri);

await this.runByRepository(uris, async (repository, resources) => {
if (!repository) {
return;
Expand All @@ -45,7 +29,7 @@ export class RevertAll extends Command {
const paths = resources.map(resource => resource.fsPath);

try {
await repository.revert(paths, pick.label);
await repository.revert(paths, depth);
} catch (error) {
console.log(error);
window.showErrorMessage("Unable to revert");
Expand Down
41 changes: 41 additions & 0 deletions src/commands/revertExplorer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Uri, window } from "vscode";
import { checkAndPromptDepth, confirmRevert } from "../input/revert";
import { Command } from "./command";

export class RevertExplorer extends Command {
constructor() {
super("svn.revertExplorer");
}

public async execute(_mainUri?: Uri, allUris?: Uri[]) {
if (!allUris) {
return;
}

const uris = allUris;
if (uris.length === 0 || !(await confirmRevert())) {
return;
}

const depth = await checkAndPromptDepth(uris);

if (!depth) {
return;
}

await this.runByRepository(uris, async (repository, resources) => {
if (!repository) {
return;
}

const paths = resources.map(resource => resource.fsPath);

try {
await repository.revert(paths, depth);
} catch (error) {
console.log(error);
window.showErrorMessage("Unable to revert");
}
});
}
}
64 changes: 64 additions & 0 deletions src/input/revert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Uri, window } from "vscode";
import { SvnDepth } from "../common/types";
import { lstat } from "../fs";

export async function confirmRevert() {
const yes = "Yes I'm sure";
const answer = await window.showWarningMessage(
"Are you sure? This will wipe all local changes.",
{ modal: true },
yes
);

if (answer !== yes) {
return false;
}

return true;
}

export async function promptDepth() {
const picks: any[] = [];

for (const depth in SvnDepth) {
if (SvnDepth.hasOwnProperty(depth)) {
picks.push({ label: depth, description: SvnDepth[depth] });
}
}

const placeHolder = "Select revert depth";
const pick = await window.showQuickPick(picks, { placeHolder });
if (!pick) {
return undefined;
}
return pick.label;
}

export async function checkAndPromptDepth(
uris: Uri[],
defaultDepth: keyof typeof SvnDepth = "empty"
) {
// Without uris, force prompt
let hasDirectory = uris.length === 0;

for (const uri of uris) {
if (uri.scheme !== "file") {
continue;
}
try {
const stat = await lstat(uri.fsPath);
if (stat.isDirectory()) {
hasDirectory = true;
break;
}
} catch (error) {
// ignore
}
}

if (hasDirectory) {
return await promptDepth();
}

return defaultDepth;
}
6 changes: 4 additions & 2 deletions src/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,10 @@ export class Repository implements IRemoteRepository {
);
}

public async revert(files: string[], depth: SvnDepth) {
return this.run(Operation.Revert, () => this.repository.revert(files, depth));
public async revert(files: string[], depth: keyof typeof SvnDepth) {
return this.run(Operation.Revert, () =>
this.repository.revert(files, depth)
);
}

public async info(path: string) {
Expand Down
18 changes: 13 additions & 5 deletions src/svnRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ export class Repository {
filePath = file;
}

const isChild = uri.scheme === "file" && isDescendant(this.workspaceRoot, uri.fsPath);
const isChild =
uri.scheme === "file" && isDescendant(this.workspaceRoot, uri.fsPath);

let target: string = filePath;

Expand All @@ -194,7 +195,10 @@ export class Repository {

if (revision) {
args.push("-r", revision);
if (isChild && !["BASE", "COMMITTED", "PREV"].includes(revision.toUpperCase())) {
if (
isChild &&
!["BASE", "COMMITTED", "PREV"].includes(revision.toUpperCase())
) {
const info = await this.getInfo();
target = info.url + "/" + target.replace(/\\/g, "/");
// TODO move to SvnRI
Expand Down Expand Up @@ -292,9 +296,13 @@ export class Repository {

const matches = result.stdout.match(/Committed revision (.*)\./i);
if (matches && matches[0]) {
const sendedFiles = (result.stdout.match(/(Sending|Adding|Deleting)\s+/g) || []).length;
const sendedFiles = (
result.stdout.match(/(Sending|Adding|Deleting)\s+/g) || []
).length;

const filesMessage = `${sendedFiles} ${sendedFiles === 1 ? "file" : "files"} commited`;
const filesMessage = `${sendedFiles} ${
sendedFiles === 1 ? "file" : "files"
} commited`;

return `${filesMessage}: revision ${matches[1]}.`;
}
Expand Down Expand Up @@ -453,7 +461,7 @@ export class Repository {
return true;
}

public async revert(files: string[], depth: SvnDepth) {
public async revert(files: string[], depth: keyof typeof SvnDepth) {
files = files.map(file => this.removeAbsolutePath(file));
const result = await this.exec(["revert", "--depth", depth, ...files]);
return result.stdout;
Expand Down