Skip to content

Commit 5363f22

Browse files
committed
Merge remote-tracking branch 'remotes/upstream/master' into rework_changes
# Conflicts: # src/commands.ts
2 parents 33e8db0 + fbabc36 commit 5363f22

File tree

10 files changed

+272
-25
lines changed

10 files changed

+272
-25
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
README.md

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
# **v1.11.1**
2+
3+
## Changes
4+
5+
* @JohnstonCode Updated readme file
6+
7+
# **v1.11.0**
8+
9+
## What's New
10+
11+
* @JohnstonCode Added commit message list
12+
13+
# **v1.10.0**
14+
15+
## What's New
16+
17+
* @JohnstonCode Added conflict support
18+
119
# **v1.9.0**
220

321
## What's New

README.md

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,8 @@ If you use [TortoiseSVN](https://tortoisesvn.net/), make sure the option
3333
**Command Line Tools** is checked during installation and
3434
`C:\Program Files\TortoiseSVN\bin` is available in PATH.
3535

36-
## Features
37-
38-
* [x] Source Control View
39-
* [x] Quick Diffs in gutter
40-
* [x] Status Bar
41-
* [ ] SVN Commands
42-
4336
## Feedback & Contributing
4437

45-
* This is a work in progress and im sure there will be some issues.
4638
* Please report any bugs, suggestions or documentation requests via the
4739
[Issues](https://github.com/JohnstonCode/svn-scm/issues)
4840
* Feel free to submit
@@ -54,3 +46,69 @@ If you use [TortoiseSVN](https://tortoisesvn.net/), make sure the option
5446
* @edgardmessias
5547
* @csholmq
5648
* @rwatts3
49+
50+
## Features
51+
52+
* Source Control View
53+
* Quick Diffs in gutter
54+
* Status Bar
55+
* Create changelists
56+
* Add files
57+
* Revert edits
58+
* Remove files
59+
* Create branches
60+
* Switch branches
61+
* Create patches
62+
* Diff changes
63+
* Commit changes/changelists
64+
* See commit messages
65+
66+
## Settings
67+
68+
`svn.enabled`
69+
* Enables Svn as a SCM in VS Code.
70+
`"default"` — true
71+
72+
`svn.path`
73+
* Path to the svn executable
74+
`"default"` — null
75+
76+
`svn.diff.withHead`
77+
* Show diff changes using latest revision in the repository. Set false to use latest revision in local folder
78+
`"default"` — true
79+
80+
`svn.layout.trunk`
81+
* Relative path for 'trunk' in SVN URL, 'null' to disable. (Ex.: 'trunk', 'main')
82+
`"default"` — trunk
83+
84+
`svn.layout.branches`
85+
* Relative path for 'branches' in SVN URL, 'null' to disable. (Ex.: 'branches', 'versions')
86+
`"default"` — branches
87+
88+
`svn.layout.tags`
89+
* Relative path for 'tags' in SVN URL, 'null' to disable. (Ex.: 'tags', 'stamps')
90+
`"default"` — tags
91+
92+
`svn.multipleFolders.enabled`
93+
* Allow to find subfolders using SVN
94+
`"default"` — false
95+
96+
`svn.multipleFolders.depth`
97+
* Maximum depth to find subfolders using SVN
98+
`"default"` — 4
99+
100+
`svn.multipleFolders.ignore`
101+
* Folders to ignore using SVN
102+
`"default"` — `["**/.git", "**/.hg", "**/vendor", "**/node_modules"]`
103+
104+
`svn.sourceControl.ignoreOnCommit`
105+
* Changelists to ignore on commit
106+
`"default"` — `["ignore-on-commit"]`
107+
108+
`svn.sourceControl.showExternal`
109+
* Allow to show in source control the list the external folders
110+
`"default"` — false
111+
112+
`svn.log.length`
113+
* Number of commit messages to log
114+
`"default"` — 50

package.json

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "svn-scm",
33
"displayName": "SVN",
44
"description": "Integrated Subversion source control",
5-
"version": "1.9.0",
5+
"version": "1.11.1",
66
"publisher": "johnstoncode",
77
"engines": {
88
"vscode": "^1.17.0"
@@ -148,6 +148,16 @@
148148
"command": "svn.remove",
149149
"title": "Remove Selected",
150150
"category": "SVN"
151+
},
152+
{
153+
"command": "svn.resolve",
154+
"title": "Resolve Conflicts",
155+
"category": "SVN"
156+
},
157+
{
158+
"command": "svn.log",
159+
"title": "Show commit messages",
160+
"category": "SVN"
151161
}
152162
],
153163
"menus": {
@@ -186,6 +196,14 @@
186196
{
187197
"command": "svn.patch",
188198
"when": "config.svn.enabled"
199+
},
200+
{
201+
"command": "svn.resolve",
202+
"when": "config.svn.enabled"
203+
},
204+
{
205+
"command": "svn.log",
206+
"when": "config.svn.enabled"
189207
}
190208
],
191209
"scm/resourceGroup/context": [],
@@ -354,6 +372,12 @@
354372
"description":
355373
"Allow to show in source control the list the external folders",
356374
"default": false
375+
},
376+
"svn.log.length": {
377+
"type": "number",
378+
"minimum": 1,
379+
"description": "Number of commit messages to log",
380+
"default": 50
357381
}
358382
}
359383
}

src/commands.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { toSvnUri, fromSvnUri } from "./uri";
1919
import * as fs from "fs";
2020
import * as path from "path";
2121
import { start } from "repl";
22+
import { getConflictPickOptions } from "./conflictItems";
2223

2324
interface CommandOptions {
2425
repository?: boolean;
@@ -180,10 +181,7 @@ export class SvnCommands {
180181
picks.push(new ChangeListItem(repository.changes));
181182
}
182183

183-
const svnConfig = workspace.getConfiguration(
184-
"svn",
185-
Uri.file(repository.workspaceRoot)
186-
);
184+
const svnConfig = workspace.getConfiguration("svn");
187185
const ignoreOnCommitList = svnConfig.get<string[]>(
188186
"sourceControl.ignoreOnCommit",
189187
[]
@@ -764,6 +762,44 @@ export class SvnCommands {
764762
}
765763
}
766764

765+
@command("svn.resolve", { repository: true })
766+
async resolve(repository: Repository) {
767+
const conflicts = repository.conflicts.resourceStates;
768+
769+
if (!conflicts.length) {
770+
window.showInformationMessage("No Conflicts");
771+
}
772+
773+
for (const conflict of conflicts) {
774+
const placeHolder = `Select conflict option for ${
775+
conflict.resourceUri.path
776+
}`;
777+
const picks = getConflictPickOptions();
778+
779+
const choice = await window.showQuickPick(picks, { placeHolder });
780+
781+
if (!choice) {
782+
return;
783+
}
784+
785+
await repository.resolve(conflict.resourceUri.path, choice.label);
786+
}
787+
}
788+
789+
@command("svn.log", { repository: true })
790+
async log(repository: Repository) {
791+
try {
792+
const result = await repository.repository.log();
793+
// send the log results to a new tab
794+
workspace.openTextDocument({ content: result }).then(doc => {
795+
window.showTextDocument(doc);
796+
});
797+
} catch (error) {
798+
console.error(error);
799+
window.showErrorMessage("Unable to log");
800+
}
801+
}
802+
767803
private getSCMResource(uri?: Uri): Resource | undefined {
768804
uri = uri
769805
? uri

src/conflictItems.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { QuickPickItem } from "vscode";
2+
3+
interface ConflictOption {
4+
label: string;
5+
description: string;
6+
}
7+
8+
const ConflictOptions = [
9+
{
10+
label: "base",
11+
description:
12+
"Choose the file that was the (unmodified) BASE revision before you tried to integrate changes"
13+
},
14+
{
15+
label: "working",
16+
description:
17+
"Assuming that you've manually handled the conflict resolution, choose the version of the file as it currently stands in your working copy."
18+
},
19+
{
20+
label: "mine-full",
21+
description:
22+
"Preserve all local modifications and discarding all changes fetched"
23+
},
24+
{
25+
label: "theirs-full",
26+
description:
27+
"Discard all local modifications and integrating all changes fetched"
28+
},
29+
{
30+
label: "mine-conflict",
31+
description:
32+
"Resolve conflicted files by preferring local modifications over the changes fetched"
33+
},
34+
{
35+
label: "theirs-conflict",
36+
description:
37+
"Resolve conflicted files by preferring the changes fetched from the server over local modifications"
38+
}
39+
];
40+
41+
class ConflictItem implements QuickPickItem {
42+
constructor(private option: ConflictOption) {}
43+
44+
get label(): string {
45+
return this.option.label;
46+
}
47+
48+
get description(): string {
49+
return this.option.description;
50+
}
51+
}
52+
53+
export function getConflictPickOptions() {
54+
return ConflictOptions.map(option => new ConflictItem(option));
55+
}

src/repository.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export class Repository {
2929
public unversioned: SourceControlResourceGroup;
3030
public external: SourceControlResourceGroup;
3131
public changelists: Map<string, SourceControlResourceGroup> = new Map();
32+
public conflicts: SourceControlResourceGroup;
3233
private disposables: Disposable[] = [];
3334
public currentBranch = "";
3435
public isSwitchingBranch: boolean = false;
@@ -133,10 +134,15 @@ export class Repository {
133134
"external",
134135
"External"
135136
);
137+
this.conflicts = this.sourceControl.createResourceGroup(
138+
"conflicts",
139+
"conflicts"
140+
);
136141

137142
this.changes.hideWhenEmpty = true;
138143
this.unversioned.hideWhenEmpty = true;
139144
this.external.hideWhenEmpty = true;
145+
this.conflicts.hideWhenEmpty = true;
140146

141147
this.disposables.push(
142148
toDisposable(() => clearInterval(this.branchesTimer))
@@ -163,14 +169,15 @@ export class Repository {
163169
let changes: any[] = [];
164170
let unversioned: any[] = [];
165171
let external: any[] = [];
172+
let conflicts: any[] = [];
166173
let changelists: Map<string, Resource[]> = new Map();
167174

168175
const statuses = (await this.repository.getStatus()) || [];
169176

170-
const fileConfig = workspace.getConfiguration("files");
177+
const fileConfig = workspace.getConfiguration("files", Uri.file(this.root));
171178
const svnConfig = workspace.getConfiguration("svn");
172179

173-
const filesToExclude = fileConfig.get<any>("exclude", null);
180+
const filesToExclude = fileConfig.get<any>("exclude");
174181

175182
let excludeList: string[] = [];
176183
for (const pattern in filesToExclude) {
@@ -188,15 +195,20 @@ export class Repository {
188195
? Uri.file(path.join(this.workspaceRoot, status.rename))
189196
: undefined;
190197

191-
const resouce = new Resource(uri, status.status, renameUri, status.props);
198+
const resource = new Resource(
199+
uri,
200+
status.status,
201+
renameUri,
202+
status.props
203+
);
192204

193205
if (status.status === Status.NORMAL && status.props === PropStatus.NONE) {
194206
// On commit, `svn status` return all locked files with status="normal" and props="none"
195207
return;
196-
} else if (status.status === Status.UNVERSIONED) {
197-
unversioned.push(resouce);
198208
} else if (status.status === Status.EXTERNAL) {
199-
external.push(resouce);
209+
external.push(resource);
210+
} else if (status.status === Status.CONFLICTED) {
211+
conflicts.push(resource);
200212
} else {
201213
if (status.status === Status.UNVERSIONED) {
202214
const matches = status.path.match(
@@ -210,24 +222,27 @@ export class Repository {
210222
statuses.some(s => s.path === matches[1])
211223
) {
212224
return;
225+
} else {
226+
unversioned.push(resource);
213227
}
214228
}
215229

216230
if (!status.changelist) {
217-
changes.push(resouce);
231+
changes.push(resource);
218232
} else {
219233
let changelist = changelists.get(status.changelist);
220234
if (!changelist) {
221235
changelist = [];
222236
}
223-
changelist.push(resouce);
237+
changelist.push(resource);
224238
changelists.set(status.changelist, changelist);
225239
}
226240
}
227241
});
228242

229243
this.changes.resourceStates = changes;
230244
this.unversioned.resourceStates = unversioned;
245+
this.conflicts.resourceStates = conflicts;
231246

232247
this.changelists.forEach((group, changelist) => {
233248
group.resourceStates = [];
@@ -357,4 +372,13 @@ export class Repository {
357372
this._onDidChangeBranch.fire();
358373
}
359374
}
375+
376+
async resolve(file: string, action: string) {
377+
try {
378+
const response = await this.repository.resolve(file, action);
379+
window.showInformationMessage(response);
380+
} catch (error) {
381+
window.showErrorMessage(error);
382+
}
383+
}
360384
}

0 commit comments

Comments
 (0)