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