返回文章列表

文章

怎么把多个 GitHub 仓库合并到一个仓库,并且完整保留所有提交历史(commit log)

目录
  1. ⭐ 把多个 GitHub 仓库合并到一个仓库,并且完整保留所有提交历史(commit log)。
  2. ✅ **整体思路:使用 git subtree(推荐)、或 **git merge --allow-unrelated-histories
  3. 推荐方式:****git subtree —— 最干净、最安全、不会产生命名冲突、不会出现 merge mess。
  4. 🔥 方法一:使用 git subtree 合并多个仓库(强烈推荐)
  5. 📌 场景
  6. 而且每个目录下的 commit log 都完整保留。
  7. 🍀 Step-by-step(百分百可用)
  8. 1️⃣ 创建最终仓库(或者使用已有仓库)
  9. 确保仓库是空的或已有内容都 OK。
  10. 2️⃣ 添加要合并的仓库作为 remote
  11. 3️⃣ 使用 subtree add 将仓库引入
  12. ❗ 如果你想保留所有 Commit,不要 -squash:
  13. 4️⃣ 若你有 repo-b、repo-c,重复:
  14. repo-b:
  15. repo-c:
  16. 👍 完成后,你会得到:
  17. 🔥 方法二:使用 git merge --allow-unrelated-histories(不推荐)
  18. 1️⃣ 在 super-repo 中添加 remote
  19. 2️⃣ 创建目录,移动文件
  20. 3️⃣ 创建 commit
  21. 再对 repo-b / repo-c 重复。
  22. 🔥 方法三:git filter-repo(用于高级清洗)
  23. 这个方法更灵活但较复杂。
  24. 🎯 最推荐的方式
  25. 🎉 如果你告诉我:

把多个 GitHub 仓库合并到一个仓库,并且完整保留所有提交历史(commit log)。#

这套方法会:

  • 保留每个仓库的完整 Git 历史(作者、时间、提交记录全保留)
  • 不会混乱 commit tree
  • 各仓库的文件放进独立子目录
  • 不会污染主仓库的历史
  • 结果完全可推到 GitHub

✅ **整体思路:使用 git subtree(推荐)、或 **git merge --allow-unrelated-histories#

推荐方式:****git subtree —— 最干净、最安全、不会产生命名冲突、不会出现 merge mess。#

🔥 方法一:使用 git subtree 合并多个仓库(强烈推荐)#

📌 场景#

你有 3 个仓库:

  • repo-a
  • repo-b
  • repo-c 你要把它们合并到:
  • super-repo(最终大仓库) 结构最终会变成:
super-repo/
  repo-a/
  repo-b/
  repo-c/

而且每个目录下的 commit log 都完整保留#

🍀 Step-by-step(百分百可用)#

1️⃣ 创建最终仓库(或者使用已有仓库)#

git clone https://github.com/you/super-repo.git
cd super-repo

确保仓库是空的或已有内容都 OK。#

2️⃣ 添加要合并的仓库作为 remote#

以 repo-a 为例:

git remote add repo-a https://github.com/xxx/repo-a.git
git fetch repo-a


3️⃣ 使用 subtree add 将仓库引入#

git subtree add --prefix=repo-a repo-a main --squash

❗ 如果你想保留所有 Commit,不要 -squash#

git subtree add --prefix=repo-a repo-a main

  • -prefix=repo-a 就是将 repo-a 的内容放在 super-repo/repo-a 目录下。

4️⃣ 若你有 repo-b、repo-c,重复:#

repo-b:#

git remote add repo-b https://github.com/xxx/repo-b.git
git fetch repo-b
git subtree add --prefix=repo-b repo-b main

repo-c:#

git remote add repo-c https://github.com/xxx/repo-c.git
git fetch repo-c
git subtree add --prefix=repo-c repo-c main


👍 完成后,你会得到:#

super-repo/
  repo-a/
  repo-b/
  repo-c/
  ... (任何你自己的文件)

所有仓库的 log 完整保留:

git log -- repo-a
git log -- repo-b
git log -- repo-c


🔥 方法二:使用 git merge --allow-unrelated-histories(不推荐)#

这个方法也能保留 commit,但缺点:

  • 容易出现大量冲突
  • 目录可能混乱
  • Commit tree 会很复杂 流程如下:

1️⃣ 在 super-repo 中添加 remote#

git remote add repo-a https://github.com/xxx/repo-a.git
git fetch repo-a

2️⃣ 创建目录,移动文件#

mkdir repo-a
git read-tree --prefix=repo-a/ -u repo-a/main

3️⃣ 创建 commit#

git commit -m "Import repo-a"

再对 repo-b / repo-c 重复。#

🔥 方法三:git filter-repo(用于高级清洗)#

如果你想:

  • 给每个仓库加上 path 前缀
  • 重写历史
  • 清理大文件 这种属于 专业级迁移,需要:
git clone https://github.com/xxx/repo-a.git
cd repo-a
git filter-repo --to-subdirectory-filter repo-a

然后再 merge

git remote add super https://github.com/you/super-repo.git
git push super main

这个方法更灵活但较复杂。#

🎯 最推荐的方式#

用 git subtree add —— 最安全高效,不会破坏结构,commit 历史保持完整。


🎉 如果你告诉我:#

  • 要合并的仓库数量
  • 每个仓库的 GitHub 地址
  • 最终仓库结构想怎么组织 我可以直接给你 完全定制的命令版本 或者 自动化脚本(bash / PowerShell)