把多个 github 仓库合并为单个仓库并保持双向同步

github subtree

Posted by Marlin on December 16, 2025

把多个 github 仓库合并为单个仓库并保持双向同步——以我的计算机学习资料项目为例

1. 需求背景

已有 N 个独立课程仓库(JavaWeb、操作系统、计算机网络……)
想要再建一个「总仓库」SUST-Computer-Science-Study-Materials,统一对外展示。

要求:

  1. 保留各仓库完整历史
  2. 后续能在总仓库中直接修改文件,也能随时把改动同步回原仓库
  3. 尽量自动化,不增加日常负担

2. 解决方案

解决方案有两种,分别是 subtree 和 submodule。

方案对比(subsree vs submodule)

维度 subtree(本文选用) submodule
历史保留 直接合并 需额外初始化
日常操作 正常 add / commit / push 多一步 git submodule update
冲突概率
双向同步 一条命令 极难

submodle主要是为了解决依赖管理问题,而不是合并仓库。 subtree更适合本文的需求。

3. 一次性初始化(subtree merge)

以下操作均在总仓库本地目录完成

3.1 克隆总仓库(本地已有总仓库则可忽略)

1
2
3
# 以前面提到的 总仓库 和 JavaWeb分仓库 为例
git clone https://github.com/marlin-phone/SUST-Computer-Science-Study-Materials
cd SUST-Computer-Science-Study-Materials

3.2 把课程仓库加为临时远程

1
git remote add javaweb https://github.com/marlin-phone/SUST-JavaWeb-Study-Materials

3.3 拉取并合并到子目录

1
2
git fetch javaweb
git subtree add --prefix=JavaWeb javaweb master --squash

参数说明:

  • --prefix=JavaWeb:指定把该仓库内容放到总仓库的哪个子目录下
  • javaweb:上一步添加的远程仓库名
  • master:远程仓库分支名(我的 JavaWeb 项目中使用的是 master,其它项目可能是 main)
  • --squash:把所有历史压缩为一次提交(可选),不添加则会保留完整 git 历史

3.4 推回 github

1
git push

重复 3.2 - 3.4 步骤,则可把其他课程仓库也合并进来。

4. 日常手动双向同步(两条命令)

4.1 从分仓库拉取更新到总仓库

1
git subtree pull --prefix=JavaWeb javaweb master --squash

参数说明同上。

4.2 从总仓库推送更新回分仓库

1
git subtree push --prefix=JavaWeb javaweb master

注意

  • 两条命令都在总仓库目录执行,小仓库无需任何操作。
  • 出现冲突时按普通 merge 解决即可。

5. 自动化:GitHub Actions 双向同步

暂无该需求,待有需求后实现确认无误后补充。