多仓库多分支迁移至Monorepo的分步实现方案求助
多仓库转单仓库(保留全部分支与提交历史)分步方案
前置准备
- 安装
git filter-repo(替代老旧的git filter-branch,处理提交历史更高效稳定) - 确认所有原仓库的分支已同步到最新状态(你已完成此操作)
- 创建全新的空Git仓库作为目标单仓库
步骤1:处理单个原仓库的所有分支(以repo1为例)
针对每个原仓库,先重写其所有分支的提交历史,将仓库内所有文件移动到对应子目录(如apps/repo1),这是避免后续分支产生大量冗余差异的核心操作。
- 克隆原仓库的本地临时副本:
git clone <repo1的远程地址> repo1-temp cd repo1-temp
- 重写当前分支的历史,将所有文件迁移到
apps/repo1目录:
git filter-repo --to-subdirectory-filter apps/repo1
- 遍历处理该仓库的其他分支:
# 列出所有本地分支(排除当前已处理的分支) for branch in $(git branch -l | grep -v '^\*'); do git checkout $branch git filter-repo --to-subdirectory-filter apps/repo1 done
提示:执行
git filter-repo后,本地副本与原远程仓库的关联会被移除,分支历史会被完全重写,属于正常结果。
步骤2:将处理后的仓库分支导入单仓库
回到新建的单仓库目录,将处理后的repo1本地副本作为远程仓库添加,拉取所有分支并重命名:
- 在单仓库目录下操作:
cd ../monorepo git remote add repo1 ../repo1-temp git fetch repo1
- 拉取repo1的所有分支并重命名:
# 拉取main分支作为单仓库的基础main分支(首次操作使用) git checkout -b main repo1/main # 拉取其他分支并按规则重命名 git checkout -b repo1-branch1 repo1/branch1 git checkout -b repo1-branch2 repo1/branch2
- 移除临时远程关联:
git remote remove repo1
步骤3:重复步骤1-2处理剩余仓库(repo2、repo3)
对repo2和repo3执行完全相同的操作:
- 克隆临时副本,用
git filter-repo将所有分支的文件迁移到apps/repo2、apps/repo3 - 将处理后的仓库作为远程添加到单仓库,拉取分支并重命名为
repo2-branch1、repo3-branch2等
注意:处理后续仓库的main分支时,需要合并到单仓库的main分支:
git checkout main git merge repo2/main --allow-unrelated-histories git merge repo3/main --allow-unrelated-histories
添加--allow-unrelated-histories参数是因为原仓库的提交历史相互独立,合并时Git会提示无共同祖先。
步骤4:验证迁移结果
- 查看单仓库的所有分支:
git branch -a
应显示预期的main、repo1-branch1、repo2-branch2等所有分支。
- 检查分支目录结构与提交历史:
git checkout repo1-branch1 ls apps/repo1 # 确认提交历史完整 git log --oneline
- 验证分支差异:
切换到不同分支对比差异,确认只有业务代码变更,无因目录迁移导致的大量冗余差异。
常见问题处理
- 执行
git filter-repo时提示"fatal: not a git repository":确认当前目录是原仓库本地副本的根目录。 - 合并main分支时出现冲突:手动解决冲突后提交即可,由于原仓库文件都在各自的
apps/subdir下,冲突概率极低。
内容的提问来源于stack exchange,提问作者Rodrigo Sedano
相关产品推荐
相关产品推荐

