从RTC-Jazz迁移后合并多Git仓库的技术方案咨询
我们使用Jazz-RTC已有约15年,现需短时间内迁移至Git。原工作流为每个版本创建对应流,流中包含代表项目不同目录的组件(如server、gui、doc、db等),后续版本逐步新增组件。
迁移脚本为每个版本流中的每个组件创建了独立Git仓库,变更集转为对应仓库的提交,保留了各组件的线性提交历史(仅master分支),但仓库间存在大量重复代码。
我们希望将这些独立Git仓库合并为一个结构如下的仓库:
Combined_Project |_server |_gui |_db |_doc |_reports
且需确保文件变更历史(提交)按日期顺序排列。优先考虑Git原生方案,也接受第三方工具。
此前尝试通过git remote add -f V2.0gui <gui-from-other-repo>+git merge V2.0gui/master合并,提交顺序混乱;尝试rebase也导致历史错乱。
补充说明:原代码为线性开发,最终只需单Git仓库且无分支,所有仓库的提交需按签入/提交日期合并至master分支。现咨询该需求的最优实现策略与工具。
最优实现策略(Git原生+filter-repo工具)
1. 准备工作
- 安装
git filter-repo(Git官方推荐替代git filter-branch的工具,性能更稳定、执行效率更高) - 将所有需要合并的独立组件仓库克隆到本地临时目录
2. 调整每个组件仓库的目录结构
对每个组件仓库,将所有文件迁移到对应子目录下(比如server仓库的所有文件移到server/),同时完整保留原提交历史:
# 进入server组件仓库目录 cd server-repo git filter-repo --to-subdirectory-filter server
执行完成后,该仓库的所有历史提交都会自动将文件路径调整为server/开头。同理处理其他组件仓库:
cd gui-repo git filter-repo --to-subdirectory-filter gui cd db-repo git filter-repo --to-subdirectory-filter db # 其余组件仓库按上述逻辑依次执行
3. 创建合并目标仓库并导入所有组件历史
# 创建并进入新的合并仓库 mkdir Combined_Project && cd Combined_Project git init # 添加每个组件仓库为远程仓库并拉取完整历史 git remote add server ../server-repo git fetch server git remote add gui ../gui-repo git fetch gui # 其余组件仓库依次执行添加和fetch操作
4. 按时间排序合并所有提交
使用git rev-list提取所有仓库的提交记录,按提交时间排序后,通过git cherry-pick依次应用到目标仓库的master分支:
# 提取所有提交,按作者提交时间排序(若需按提交者时间,替换为--committer-date-order) git rev-list --author-date-order --all > commits.txt # 循环执行cherry-pick,将提交按时间顺序应用 while read commit; do git cherry-pick $commit done < commits.txt
若遇到冲突,手动解决冲突后执行git cherry-pick --continue即可。由于原开发为线性流程,冲突概率极低。
5. 清理与验证
# 移除临时添加的远程仓库 git remote remove server git remote remove gui # 其余远程仓库依次移除 # 验证最终目录结构和提交历史 ls -la git log --oneline --graph --date-order
替代方案:合并后重排历史
若不想使用cherry-pick,也可先合并所有组件分支,再通过rebase按时间重排历史:
# 在目标仓库中合并所有组件分支 git merge server/master --allow-unrelated-histories git merge gui/master --allow-unrelated-histories # 其余分支依次执行合并 # 基于根提交重排历史,按提交时间排序 git rebase --root --committer-date-is-author-date
此方式可能触发更多冲突,需谨慎处理。
关键注意事项
- 坚决避免使用
git filter-branch,该命令已被Git官方标记为废弃,存在性能和稳定性问题 - 排序时需确认使用
--author-date-order还是--committer-date-order,确保与Jazz-RTC的签入时间逻辑匹配 - 操作前务必备份所有原始仓库,防止数据丢失
内容的提问来源于stack exchange,提问作者m4110c

