源代码管理 API
源代码管理 (SCM) API 允许扩展作者定义源代码管理功能。这是一个轻量级但功能强大的 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 定义了两个资源组:工作树 (working tree) 和 索引 (index)。该组内的每个文件变更都是一个资源状态
- 索引 - 资源组
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/repository 菜单是源代码管理存储库视图中每个 SourceControl 实例上的菜单。将菜单项放在 inline 组中以使其以内联方式显示。所有其他菜单项组将显示在 ... 菜单中。inline 组是根据可用空间渲染的,不适合的菜单项会自动移动到 ... 菜单中。
scm/sourceControl 菜单是源代码管理存储库视图中每个 SourceControl 实例上的上下文菜单。

scm/change/title 允许你为 Quick Diff(内联差异编辑器)的标题栏提供命令,详见后文。该命令将以文档的 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;
}
快速差异 (Quick Diff)
VS Code 还支持显示快速差异编辑器装订线装饰。单击这些装饰将显示内联差异体验,你可以为其贡献上下文命令。

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