-
Notifications
You must be signed in to change notification settings - Fork 29.5k
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
Exploration: SCM providers #15246
Comments
There are several approaches to coming up with the least common denominator problem. I'll do my best to put them to prose. FeaturesHere is the current set of features implemented by the git contribution:
|
Common ModelThe toughest part of this problem is how to make the current viewlet be something that could be contributed externally. Let's approach this first by sharing a common SCM model across the multiple SCM providers. Dirty diff, viewlet and actions Revolving around the // dirty diff is maybe a bad name...
// other names derivate from `original`, `baseline`, etc.
interface DirtyDiffProvider {
// returns the URI of the baseline document for dirty diff to compare with
getDirtyDiffTextDocument(uri: Uri): Uri | Thenable<Uri>;
}
interface SourceControlGroup {
id: string;
label: string;
icon: string | Uri;
}
interface SourceControlStatus {
groups: { [id: string]: Uri[]; };
}
interface SourceControlStatusProvider {
// a static way to know the labels for each resource group
groups: SourceControlGroup[];
// need a more generic term than `commit`
commit(message: string): void | Thenable<void>;
getStatus(): SourceControlStatus | Thenable<SourceControlStatus>;
// ugh, how to do drag and drop?
drop(resource: Uri): void: Thenable<void>;
// the status might change due to more than fs events, so we still need
// to give the provider a chance to let us know that the status changed
onStatusChange: Event<void>;
} We'd have to come up with the following new menu locations:
We'd need to have an SCM switcher in the upcoming SCM viewlet. We could create a context key to indicate which is the currently active SCM provider. This would require an ID. Status bar The status bar affordances could come in via the Alternatively, we could allow the provider to populate the current 2 status bar affordances via API and register commands that get executed when they are clicked. Quick Open All the quick open smart interactions can be dropped and transformed into simpler commands and simpler quick open interactions. We would basically let this go for now. |
Common UIAnother approach to solving the viewlet problem could be taking #14048 another step further and widening the new API to accommodate for the UI currently needed by the git viewlet. The current viewlet is composed of an input box placed above a tree widget. If one looks at those as a single widget, one sees that pattern everywhere around the workbench: git and search viewlets, quick open itself, problems view, etc; they are all trees with an input box above. Here's what we would have to do:
tbc |
Common Model 2We can also approach the problem from a push point of view. Here's how it could look: export namespace scm {
export function createSCMProvider(id: string, delegate: SCMDelegate): SCMProvider;
}
export interface SCMDelegate {
commitCommand: string;
clickCommand: string;
dragCommand?: string;
getOriginalResource(uri: Uri): Uri | Thenable<Uri>;
}
export interface SCMProvider extends Disposable {
createResourceGroup(id: string, label: string): SCMResourceGroup;
}
export interface SCMResourceGroup extends Disposable {
set(...resources: SCMResource[]): void;
get(): SCMResource[];
}
export interface SCMResource {
uri: Uri;
// status type, icon decoration, etc
} The SCM viewlet would be able to show the status given by a single SCM provider at once. Some ideas to select that provider include showing a dropdown picker or having API for providers to announce that they provide SCM info for each open file. We would use the provider ID as a part of several environment context keys, which would be used to add commands to menus. We could add that context-aware functionality to the status bar contributions too, allowing the status bar items to be alive only when a specific scm context is set. |
Closing the discussion. |
The Inner Loop
Code has successfully survived so far using git as the sole source control solution. This is obviously a narrow worldview since there are many other popular SCMs which lack of support could be limiting our user base. A few of the popular alternatives are TFS, SVN, Mercurial and Perforce.
We still consider Code to be a pretty decent tool which tackles the tight inner loop of development with git as an SCM. This inner loop focus allows us to justify having a simple UI, which lets you do 80% of the tasks within Code, while suggesting to use the CLI or another GUI application for the rest of the tasks. Think about visualising history and managing stashes, as examples. Note that these are still fair feature requests, which are properly tracked, but the argument here is that Code is still a successful tool while catering for the inner loop.
While making sense for SCMs like SVN and Mercurial, this argument might not translate easily to other, such as TFS, in which suggesting the CLI is not practical (users simply don't know how to) and suggesting another tool, which in this case happens to be Visual Studio itself, defeats the whole purpose.
This creates our first question: does the current philosophy of Code as a lightweight editor with some SCM features fit other SCM providers? Will it be enough?
The Least Common Denominator
The ultimate problem with supporting multiple SCM systems is to discover and specify the least common denominator between the different systems, in terms of functionality, UI and API. There is an obvious analogy to the Debugger world, with its debug adapters.
This can go from taking a large API area by sharing common widgets, such as buttons, input boxes, the tree, all the way to narrowing down the commonality and invent a common SCM model. Both solutions have advantages and disadvantages. They also have very different implementation time horizons.
The Interface
One other issue that came up in discussions concerns the interface between the SCM systems and Code itself.
If the least common denominator problem is solved by sharing platform UI pieces, this can be addressed the same way custom trees were in #14048. The extension API would be augmented and used for this purpose.
If, on the other hand, we decide to go down the road of supporting a common SCM model there are two alternatives. The obvious one would be to add API to our extension API, making SCM contributions simple extensions which are in charge of either spawning processes or binding to libraries in JavaScript. The other one would be to create a new protocol, on top of JSON-RPC, similarly to how it's done in the Debug world. This would enable SCM providers to be implemented in any language of choice, the obvious candidate being TFS implementation, which is already implemented as a Java library in the TEE project.
The text was updated successfully, but these errors were encountered: