多根工作区是唯一生效前提,必须通过“Add Folder to Workspace”逐个添加含.git的仓库根目录、保存为.code-workspace文件、双击该文件启动;git.autoRepositoryDetection须设为false或subfolders以防误识别;批量操作应使用终端脚本而非UI;子模块需单独加入工作区并手动初始化。

多根工作区是唯一生效前提,不是可选项
VSCode 的 SCM 视图从不“自动聚合”多个 Git 仓库——它只响应你显式定义的工作区结构。如果你打开一个父目录,里面包含 client/、server/、shared/ 三个含 .git 的文件夹,SCM 依然只显示一个仓库,除非你走完整的工作区流程。
必须执行以下三步,缺一不可:
- 通过 File > Add Folder to Workspace… 逐个添加每个仓库的**根目录**(不能只加父目录)
- 添加完毕后,执行 File > Save Workspace As…,生成
my-workspace.code-workspace - 下次务必双击该文件,或运行
code my-workspace.code-workspace启动 —— 直接用code .打开父目录无效
验证是否成功:资源管理器顶部应显示多个并列文件夹图标;SCM 视图顶部下拉框中应列出全部仓库路径。否则所有后续操作都建立在错误前提上。
git.autoRepositoryDetection 必须设为 false 或 subfolders
默认值 true 会让 VSCode 递归扫描整个工作区,把 node_modules/.git、build/.git、甚至子模块的 .git 文件(非目录)误识别为独立仓库,导致 SCM 卡顿、状态错乱、下拉菜单里出现一堆灰色无效条目。
推荐做法:
- 项目结构扁平(如
./app、./api、./infra并列)→ 设为false,完全禁用自动探测 - 项目有明确一级子目录层级,且确定只有这些子目录含真实仓库 → 设为
subfolders - 设为
false后,若某个仓库没出现在 SCM 中,右键其文件夹 → Git: Open Repository in Parent Folder
这个设置直接影响 SCM 渲染性能和准确性,不是“开了更好”的可选功能,而是多仓库场景下的必要隔离手段。
批量 Git 操作别碰 UI,终端脚本才是正解
SCM 视图顶部下拉菜单只控制当前操作作用域,它不提供“全部拉取”“全部提交”按钮。试图手动切换每个仓库点一遍 Pull,不仅效率低,还容易漏掉某个仓库或点错目标远程。
真实开发中,你应该在集成终端里跑轻量脚本:
for d in */; do [ -d "$d/.git" ] && echo "=== $d ===" && git -C "$d" pull; done
关键细节:
- 脚本需在所有仓库的**共同父目录**下运行(如
~/projects/),不能在工作区根目录或某个仓库内 -
git -C "$d"是核心,它确保命令在指定目录执行,不依赖当前 shell 路径 - 如果仓库名含空格或特殊字符,用
"$d"包裹避免报错 - 需要推送时,把
pull换成push origin $(git -C "$d" rev-parse --abbrev-ref HEAD)
VSCode 终端支持分栏,你可以同时开多个 tab 分别跑不同命令,比 UI 点击更可控、可复现、可审计。
子模块必须单独加入工作区,否则永远灰色
子模块目录里的 .git 是个文件(指向 ../.git/modules/xxx),不是标准目录,VSCode 的 Git 扩展默认跳过它。所以你在主项目里看到子模块文件夹是灰色、未跟踪、无法提交 —— 这不是 bug,是设计行为。
正确做法只有两个动作:
- 先在终端运行
git submodule update --init --recursive,确保子模块代码已检出 - 然后把子模块所在文件夹路径(如
./libs/my-utils)也通过 Add Folder to Workspace… 加入工作区
加完后,SCM 顶部下拉框会出现两个条目:main-project 和 my-utils,各自独立显示状态、提交、分支。修改子模块代码后,必须先在 my-utils 上提交,再回到 main-project 提交更新后的子模块指针 —— 这个顺序不能颠倒,否则协作方拉不到最新内容。


















