源代码控制API
源代码控制API允许扩展作者定义源代码管理(SCM)功能。它提供了一个简洁而强大的API接口,使得许多不同的SCM系统可以集成到Visual Studio Code中,同时与所有这些系统共享一个统一的用户界面。

VS Code 本身附带了一个源代码控制提供程序,即 Git 扩展,这是此 API 的最佳参考,如果您想贡献自己的 SCM 提供程序,这是一个很好的起点。市场上有其他很好的例子,例如 SVN 扩展。
本文档将帮助您构建一个扩展,使任何SCM系统都能与VS Code一起工作。
注意: 您可以随时参考我们文档中的
vscode命名空间 API 参考。
源代码控制模型
一个SourceControl是负责用资源状态填充源代码控制模型的实体,这些资源状态是SourceControlResourceState的实例。资源状态本身被组织在组中,这些组是SourceControlResourceGroup的实例。
你可以使用vscode.scm.createSourceControl创建一个新的SourceControl。
为了更好地理解这三个实体如何相互关联,让我们以Git为例。考虑以下git status的输出:
vsce main* → git status
On branch main
Your branch is up-to-date with 'origin/main'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
renamed: src/api.ts -> src/test/api.ts
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: .travis.yml
modified: README.md
在这个工作区中有很多事情正在进行。首先,README.md 文件已被修改、暂存,然后再次修改。其次,src/api.ts 文件已被移动到 src/test/api.ts,并且该移动已被暂存。最后,.travis.yml 文件已被删除。
对于这个工作区,Git定义了两个资源组:工作树和索引。该组中的每个文件更改都是资源状态:
- 索引 - 资源组
README.md, 已修改 - 资源状态src/test/api.ts, 从src/api.ts重命名 - 资源状态
- 工作树 - 资源组
.travis.yml, 已删除 - 资源状态README.md, 已修改 - 资源状态
注意同一个文件,README.md,是两个不同资源状态的一部分。
以下是Git创建此模型的方式:
function createResourceUri(relativePath: string): vscode.Uri {
const absolutePath = path.join(vscode.workspace.rootPath, relativePath);
return vscode.Uri.file(absolutePath);
}
const gitSCM = vscode.scm.createSourceControl('git', 'Git');
const index = gitSCM.createResourceGroup('index', 'Index');
index.resourceStates = [
{ resourceUri: createResourceUri('README.md') },
{ resourceUri: createResourceUri('src/test/api.ts') }
];
const workingTree = gitSCM.createResourceGroup('workingTree', 'Changes');
workingTree.resourceStates = [
{ resourceUri: createResourceUri('.travis.yml') },
{ resourceUri: createResourceUri('README.md') }
];
对源代码控制和资源组所做的更改将传播到源代码控制视图。
源代码控制视图
VS Code 能够随着源代码控制模型的变化来填充源代码控制视图。资源状态可以使用 SourceControlResourceDecorations 进行自定义:
export interface SourceControlResourceState {
readonly decorations?: SourceControlResourceDecorations;
}
前面的例子足以在源代码控制视图中填充一个简单的列表,但用户可能希望对每个资源执行许多用户交互。例如,当用户点击资源状态时会发生什么?资源状态可以选择提供一个命令来处理此操作:
export interface SourceControlResourceState {
readonly command?: Command;
}
菜单
有六个源代码控制菜单ID,您可以在其中放置菜单项,以便为用户提供更丰富的用户界面。
scm/title 菜单位于 SCM 视图标题的右侧。navigation 组中的菜单项将内联显示,而所有其他菜单项将位于 … 下拉菜单中。
这三者相似:
scm/resourceGroup/context向SourceControlResourceGroup项添加命令。scm/resourceState/context向SourceControlResourceState项添加命令。scm/resourceFolder/context当SourceControlResourceState的resourceUri路径包含文件夹且用户选择了树状视图而非列表视图模式时,向中间文件夹添加命令。
将菜单项放置在inline组中以使其内联。所有其他菜单项组将显示在通常通过鼠标右键点击访问的上下文菜单中。
请注意,SCM视图支持多选,因此命令接收的参数是一个或多个资源的数组。
例如,Git 支持通过将 git.stage 命令添加到 scm/resourceState/context 菜单并使用以下方法声明来暂存多个文件:
stage(...resourceStates: SourceControlResourceState[]): Promise<void>;
在创建它们时,SourceControl 和 SourceControlResourceGroup 实例要求你提供一个 id 字符串。这些值将分别填充到 scmProvider 和 scmResourceGroup 上下文键中。你可以在菜单项的 when 子句中依赖这些 上下文键。以下是 Git 如何能够为其 git.stage 命令显示内联菜单项的方式:
{
"command": "git.stage",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "inline"
}
scm/sourceControl 菜单是 源代码控制仓库 视图中每个 SourceControl 实例的上下文菜单:

scm/change/title 允许您向快速差异内联差异编辑器的标题栏贡献命令,具体描述见下文。该命令将作为参数传递文档的URI、其中的更改数组以及内联更改差异编辑器当前聚焦的更改索引。例如,以下是stageChange Git命令的声明,该命令通过when子句测试originalResourceScheme 上下文键等于git贡献到此菜单:
async stageChange(uri: Uri, changes: LineChange[], index: number): Promise<void>;
SCM 输入框
源代码控制输入框位于每个源代码控制视图的顶部,允许用户输入消息。您可以获取(并设置)此消息以执行操作。例如,在Git中,这被用作提交框,用户在其中输入提交消息,git commit命令会获取这些消息。
export interface SourceControlInputBox {
value: string;
}
export interface SourceControl {
readonly inputBox: SourceControlInputBox;
}
用户可以输入 Ctrl+Enter(或在 macOS 上输入 Cmd+Enter)来接受任何消息。您可以通过为您的 SourceControl 实例提供一个 acceptInputCommand 来处理此事件。
export interface SourceControl {
readonly acceptInputCommand?: Command;
}
快速差异
VS Code 还支持显示 快速差异 编辑器边栏装饰。点击这些装饰将显示内联差异体验,您可以为其贡献上下文命令:

这些装饰是由VS Code本身计算的。您所需要做的就是为VS Code提供任何给定文件的原始内容。
export interface SourceControl {
quickDiffProvider?: QuickDiffProvider;
}
使用QuickDiffProvider的provideOriginalResource方法,您的实现能够告诉VS Code与作为方法参数提供的Uri匹配的原始资源的Uri。
将此API与workspace命名空间中的registerTextDocumentContentProvider方法结合使用,该方法允许您为任意资源提供内容,前提是提供一个Uri,该Uri与其注册的自定义scheme相匹配。
下一步
要了解更多关于VS Code扩展模型的信息,请尝试以下主题:
- SCM API 参考 - 阅读完整的 SCM API 文档
- Git Extension - 通过阅读Git扩展实现来学习
- Extension API Overview - 了解完整的 VS Code 扩展性模型。
- 扩展清单文件 - VS Code 的 package.json 扩展清单文件参考
- Contribution Points - VS Code 贡献点参考