VS Code Extensions
Ma X Git

Ma X Git

by majj

IDEA-style Git tool window for VS Code — branch browser, checkout and native file diff

Downloads

1

Rating

(0)

Version

0.0.2

Last updated

Aug 09, 2026

VS Code 扩展,在源代码管理(SCM)面板中提供类 IntelliJ IDEA 的 Git 分支浏览器与差异对比功能。

仓库结构

文件 职责
src/extension.ts 扩展入口,注册所有命令与 TreeView
src/gitService.ts 封装所有 git 命令(分支/标签/远程/差异/导出)
src/gitBranchTree.ts BRANCHES 视图的 TreeDataProvider,右键菜单逻辑
src/gitDiffTree.ts Changed Files 视图的 TreeDataProvider,差异文件列表
package.json 命令、viewsmenuswhen 贡献点
webpack.config.js 仅打包 src/extension.tsout/extension.js

视图(Views,挂在 scm 容器下)

  • maxGit.branches —— 标题 BRANCHES,始终显示(when: true)
    • 节点结构:HEAD(current branch) / Local(本地分支) / Remotes(远程仓库 → 远程分支) / Tags(标签)
    • 顶部 HEAD 节点显示当前分支;localBranchCurrent 为当前分支的 contextValue
  • maxGit.changedFiles —— 标题 Changed Files,仅在有差异会话时显示(when: maxGit.hasDiffSession,由 setContext 控制)
    • 展示某次对比的变更文件列表,带状态图标:新增 add / 修改 diff-modified / 删除 remove
    • 单击文件节点(或 hover 点 inline "Open Diff")打开该文件原生差异(vscode.diff)

命令(Commands)

maxGit.refreshBranches —— 刷新 BRANCHES 视图 maxGit.clearDiff —— 关闭 Changed Files 列表(标题栏关闭按钮) maxGit.openFileDiff —— 打开单个文件的差异对比

右键菜单(branch/tag 节点,view/item/context)

当前已显示的菜单项

命令 标题 适用节点
maxGit.checkout Checkout local/remoteBranch/tag
maxGit.checkoutNewBranch New Branch from... local/remoteBranch
maxGit.compareWithCurrent Compare with Current local/remoteBranch/tag
maxGit.showDiffWithWorkingTree Show Diff with Working Tree local/remoteBranch/tag
maxGit.deleteRef Delete local/remoteBranch/tag

已隐藏但代码仍保留的菜单项(从 package.jsonview/item/context 移除即可恢复)

这些命令的完整实现都在 gitService.tsgitBranchTree.ts 中,只需在 package.jsoncontributes.menus.view/item/context 加回对应条目即可重新出现在菜单。

命令 标题 when 条件 后端实现
maxGit.checkoutAndRebase Checkout and Rebase onto... viewItem =~ /^(localBranch|localBranchCurrent|remoteBranch)$/ GitService.checkoutAndRebasegit rebase <target>
maxGit.rebaseCurrentOnto Rebase Current onto... 同上 GitService.rebaseCurrentOntogit rebase <target>
maxGit.mergeIntoCurrent Merge into Current 同上 GitService.mergeIntoCurrentgit merge <source>
maxGit.pullIntoCurrentWithRebase Pull into Current using Rebase viewItem == remoteBranch GitService.pullIntoCurrentWithRebasegit pull --rebase <remote> <branch>
maxGit.pullIntoCurrentWithMerge Pull into Current using Merge viewItem == remoteBranch GitService.pullIntoCurrentWithMergegit pull <remote> <branch>

恢复示例(放回 view/item/context 数组):

{
  "command": "maxGit.checkoutAndRebase",
  "when": "view == maxGit.branches && viewItem =~ /^(localBranch|localBranchCurrent|remoteBranch)$/",
  "group": "1_branches@3"
},
{
  "command": "maxGit.rebaseCurrentOnto",
  "when": "view == maxGit.branches && viewItem =~ /^(localBranch|localBranchCurrent|remoteBranch)$/",
  "group": "3_merge@1"
},
{
  "command": "maxGit.mergeIntoCurrent",
  "when": "view == maxGit.branches && viewItem =~ /^(localBranch|localBranchCurrent|remoteBranch)$/",
  "group": "3_merge@2"
},
{
  "command": "maxGit.pullIntoCurrentWithRebase",
  "when": "view == maxGit.branches && viewItem == remoteBranch",
  "group": "3_merge@3"
},
{
  "command": "maxGit.pullIntoCurrentWithMerge",
  "when": "view == maxGit.branches && viewItem == remoteBranch",
  "group": "3_merge@4"
}

Checkout 行为约定(与 IDEA 一致)

  • 本地分支 → git checkout <branch>
  • 远程分支 → git checkout -b <branch> <remote>/<branch>(创建同名跟踪分支,避免 detached HEAD)
  • 标签(tag)→ git checkout -b <tag> <tag>(创建同名本地分支,避免 detached HEAD)

GitService.getCurrentBranchName()git rev-parse --abbrev-ref HEAD 作为当前分支的权威判定,兜底保证 HEAD 节点与本地分支 current 标记正确。

差异对比实现说明

  • 对比时调用 GitService.exportTree(ref, dir)(git ls-tree -r -z --name-only + git show <ref>:<file>,-z 避免中文文件名被加引号)把整棵树导出到临时目录。
  • 工作树用 GitService.exportWorkingTree(dir)(git checkout-index -a -f --prefix=...)。
  • 变更列表用 GitService.getDiffFiles/getDiffFilesWithWorkingTree(git diff --name-status)返回带 A/M/D 状态的 ChangedFile[]
  • 不要用目录 URI 直接 vscode.diff(旧版本 VS Code 不支持目录级 diff,会报 "is actually a directory");改为逐文件 vscode.diff(fileUri, fileUri)

构建

npm install
npm run compile   # 或 npm run watch

F5 启动 Extension Host 调试。

Related extensions