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

VS Code 本身就内置了一个源代码管理提供程序,即 Git 扩展。它是此 API 的最佳参考,如果您想贡献自己的 SCM 提供程序,它也是一个绝佳的起点。在 Marketplace 中还有其他很棒的示例,例如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/repository 菜单是 **源代码管理存储库** 视图中每个 SourceControl 实例上的菜单。将菜单项放在 inline 组中,即可使其内联显示。所有其他菜单项组都将在 ... 菜单中显示。inline 组会根据可用空间进行渲染,未能显示的菜单项会自动移至 ... 菜单。
scm/sourceControl 菜单是 **源代码管理存储库** 视图中每个 SourceControl 实例上的上下文菜单。

scm/change/title 允许您为快速差异内联差异编辑器贡献命令到其标题栏,该编辑器稍后会进行介绍。命令将作为参数传递文档的 URI、其中的更改数组以及内联更改差异编辑器当前聚焦的更改的索引。例如,这是 stageChange Git 命令的声明,该命令已添加到此菜单,并具有一个测试 originalResourceScheme 上下文键等于 git 的 when 子句:
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 与其注册的自定义 scheme 匹配。
后续步骤
要了解有关 VS Code 可扩展性模型的更多信息,请尝试以下主题
- SCM API 参考 - 阅读完整的 SCM API 文档
- Git 扩展 - 通过阅读 Git 扩展实现来学习
- 扩展 API 概述 - 了解完整的 VS Code 可扩展性模型。
- 扩展清单文件 - VS Code package.json 扩展清单文件参考
- 贡献点 - VS Code 贡献点参考