Skip to content

Commit 69c2584

Browse files
committed
Added support to add and remove changelists (#95);
1 parent 1f92653 commit 69c2584

File tree

7 files changed

+156
-2
lines changed

7 files changed

+156
-2
lines changed

icons/dark/remove.svg

Lines changed: 1 addition & 0 deletions
Loading

icons/light/remove.svg

Lines changed: 1 addition & 0 deletions
Loading

package.json

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@
6060
"dark": "icons/dark/add.svg"
6161
}
6262
},
63+
{
64+
"command": "svn.addChangelist",
65+
"title": "Add to a changelist",
66+
"category": "SVN",
67+
"icon": {
68+
"light": "icons/light/add.svg",
69+
"dark": "icons/dark/add.svg"
70+
}
71+
},
72+
{
73+
"command": "svn.removeChangelist",
74+
"title": "Remove from changelist",
75+
"category": "SVN",
76+
"icon": {
77+
"light": "icons/light/remove.svg",
78+
"dark": "icons/dark/remove.svg"
79+
}
80+
},
6381
{
6482
"command": "svn.commit",
6583
"title": "Commit Selected",
@@ -130,7 +148,20 @@
130148
"scm/resourceState/context": [
131149
{
132150
"command": "svn.add",
133-
"when": "scmProvider == svn && scmResourceGroup == unversioned",
151+
"when":
152+
"config.svn.enabled && scmProvider == svn && scmResourceGroup == unversioned",
153+
"group": "inline"
154+
},
155+
{
156+
"command": "svn.addChangelist",
157+
"when":
158+
"config.svn.enabled && scmProvider == svn && scmResourceGroup != external",
159+
"group": "inline"
160+
},
161+
{
162+
"command": "svn.removeChangelist",
163+
"when":
164+
"config.svn.enabled && scmProvider == svn && scmResourceGroup != changes && scmResourceGroup != unversioned && scmResourceGroup != external",
134165
"group": "inline"
135166
},
136167
{

src/commands.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,18 @@ class ChangeListItem implements QuickPickItem {
9898
}
9999
}
100100

101+
class NewChangeListItem implements QuickPickItem {
102+
constructor() {}
103+
104+
get label(): string {
105+
return "$(plus) New changelist";
106+
}
107+
108+
get description(): string {
109+
return "Create a new change list";
110+
}
111+
}
112+
101113
export class SvnCommands {
102114
private commands: any[] = [];
103115

@@ -218,6 +230,78 @@ export class SvnCommands {
218230
}
219231
}
220232

233+
@command("svn.addChangelist")
234+
async addChangelist(resource: Resource) {
235+
const repository = this.model.getRepository(resource.resourceUri.fsPath);
236+
237+
if (!repository) {
238+
return;
239+
}
240+
241+
const picks: QuickPickItem[] = [];
242+
243+
repository.changelists.forEach((group, changelist) => {
244+
if (group.resourceStates.length) {
245+
picks.push(new ChangeListItem(group));
246+
}
247+
});
248+
picks.push(new NewChangeListItem());
249+
250+
const selectedChoice: any = await window.showQuickPick(picks, {});
251+
if (!selectedChoice) {
252+
return;
253+
}
254+
255+
let changelistName = "";
256+
257+
if (selectedChoice instanceof NewChangeListItem) {
258+
const newChangelistName = await window.showInputBox();
259+
if (!newChangelistName) {
260+
return;
261+
}
262+
changelistName = newChangelistName;
263+
} else if (selectedChoice instanceof ChangeListItem) {
264+
changelistName = selectedChoice.resourceGroup.id.replace(
265+
/^changelist-/,
266+
""
267+
);
268+
} else {
269+
return;
270+
}
271+
272+
try {
273+
await repository.addChangelist(
274+
resource.resourceUri.fsPath,
275+
changelistName
276+
);
277+
} catch (error) {
278+
console.log(error);
279+
window.showErrorMessage(
280+
`Unable to add file "${
281+
resource.resourceUri.fsPath
282+
}" to changelist "${changelistName}"`
283+
);
284+
}
285+
}
286+
287+
@command("svn.removeChangelist")
288+
async removeChangelist(resource: Resource) {
289+
const repository = this.model.getRepository(resource.resourceUri.fsPath);
290+
291+
if (!repository) {
292+
return;
293+
}
294+
295+
try {
296+
await repository.removeChangelist(resource.resourceUri.fsPath);
297+
} catch (error) {
298+
console.log(error);
299+
window.showErrorMessage(
300+
`Unable to remove file "${resource.resourceUri.fsPath}" from changelist`
301+
);
302+
}
303+
}
304+
221305
@command("svn.commit", { repository: true })
222306
async commit(
223307
repository: Repository,

src/repository.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export class Repository {
2626
public watcher: FileSystemWatcher;
2727
public sourceControl: SourceControl;
2828
public changes: SourceControlResourceGroup;
29+
public unversioned: SourceControlResourceGroup;
2930
public external: SourceControlResourceGroup;
3031
public changelists: Map<string, SourceControlResourceGroup> = new Map();
3132
private disposables: Disposable[] = [];
@@ -124,12 +125,17 @@ export class Repository {
124125
updateBranchName();
125126

126127
this.changes = this.sourceControl.createResourceGroup("changes", "Changes");
128+
this.unversioned = this.sourceControl.createResourceGroup(
129+
"unversioned",
130+
"Unversioned"
131+
);
127132
this.external = this.sourceControl.createResourceGroup(
128133
"external",
129134
"External"
130135
);
131136

132137
this.changes.hideWhenEmpty = true;
138+
this.unversioned.hideWhenEmpty = true;
133139
this.external.hideWhenEmpty = true;
134140

135141
this.disposables.push(
@@ -155,6 +161,7 @@ export class Repository {
155161
@debounce(1000)
156162
async update() {
157163
let changes: any[] = [];
164+
let unversioned: any[] = [];
158165
let external: any[] = [];
159166
let changelists: Map<string, Resource[]> = new Map();
160167

@@ -181,7 +188,9 @@ export class Repository {
181188
? Uri.file(path.join(this.workspaceRoot, status.rename))
182189
: undefined;
183190

184-
if (status.status === Status.EXTERNAL) {
191+
if (status.status === Status.UNVERSIONED) {
192+
unversioned.push(new Resource(uri, status.status, renameUri));
193+
} else if (status.status === Status.EXTERNAL) {
185194
external.push(new Resource(uri, status.status, renameUri));
186195
} else {
187196
if (status.status === Status.UNVERSIONED) {
@@ -213,6 +222,7 @@ export class Repository {
213222
});
214223

215224
this.changes.resourceStates = changes;
225+
this.unversioned.resourceStates = unversioned;
216226

217227
this.changelists.forEach((group, changelist) => {
218228
group.resourceStates = [];
@@ -221,6 +231,7 @@ export class Repository {
221231
changelists.forEach((resources, changelist) => {
222232
let group = this.changelists.get(changelist);
223233
if (!group) {
234+
// Prefix 'changelist-' to prevent double id with 'change' or 'external'
224235
group = this.sourceControl.createResourceGroup(
225236
`changelist-${changelist}`,
226237
`Changelist "${changelist}"`
@@ -264,6 +275,14 @@ export class Repository {
264275
return this.repository.addFile(filePath);
265276
}
266277

278+
addChangelist(filePath: string, changelist: string) {
279+
return this.repository.addChangelist(filePath, changelist);
280+
}
281+
282+
removeChangelist(changelist: string) {
283+
return this.repository.removeChangelist(changelist);
284+
}
285+
267286
dispose(): void {
268287
this.disposables = dispose(this.disposables);
269288
}

src/svn.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,16 @@ export class Svn {
200200
return this.exec("", ["add", path]);
201201
}
202202

203+
addChangelist(path: string, changelist: string) {
204+
path = path.replace(/\\/g, "/");
205+
return this.exec("", ["changelist", changelist, path]);
206+
}
207+
208+
removeChangelist(path: string) {
209+
path = path.replace(/\\/g, "/");
210+
return this.exec("", ["changelist", path, "--remove"]);
211+
}
212+
203213
show(path: string, revision?: string, options: CpOptions = {}) {
204214
var args = ["cat", path];
205215

src/svnRepository.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ export class Repository {
6464
return this.svn.add(filePath);
6565
}
6666

67+
addChangelist(filePath: string, changelist: string) {
68+
return this.svn.addChangelist(filePath, changelist);
69+
}
70+
71+
removeChangelist(filePath: string) {
72+
return this.svn.removeChangelist(filePath);
73+
}
74+
6775
async getCurrentBranch(): Promise<string> {
6876
const info = await this.getInfo();
6977

0 commit comments

Comments
 (0)