如何合并无共同祖先但含共同代码的两个Git仓库?
如何合并两个拥有共同代码但无共同祖先的Git仓库?
背景情况
- 创建了repoRoot仓库
- repoRoot曾丢失,仅保留了文件备份
- 基于这份备份文件创建了无历史记录的repoNew仓库
- 在repoNew中,所有代码被迁移至新的subFolder目录
- 后续repoRoot仓库失而复得
需求
- 合并为单个仓库,优先保留repoRoot的完整历史记录
- 无缝接续repoNew的后续提交历史
- 尽可能保留两个仓库原有的所有分支
操作步骤
步骤1:初始化合并仓库
先把repoRoot克隆到本地,再将repoNew作为远程仓库引入:
# 克隆repoRoot到本地,命名为merged-repo git clone <repoRoot地址> merged-repo cd merged-repo # 添加repoNew为远程仓库并拉取所有内容 git remote add repoNew <repoNew地址> git fetch repoNew
步骤2:对齐文件结构(关键步骤)
因为两个仓库没有共同祖先,需要在repoRoot的历史末尾创建一个提交,让文件结构和repoNew的初始状态完全匹配(即把repoRoot的所有文件移到subFolder目录):
# 查看repoRoot最后一次提交的哈希值(示例哈希为abc123) git log --oneline # 基于该提交创建临时分支 git checkout -b temp-align abc123 # 创建subFolder并移动所有文件进去 mkdir subFolder git ls-files | grep -v ^subFolder$ | xargs mv -t subFolder/ git add . git commit -m "对齐repoNew初始结构:迁移所有文件至subFolder"
步骤3:合并repoNew的历史
此时temp-align分支的文件结构和repoNew初始状态一致,可直接合并:
# 合并repoNew的主分支(需替换为实际分支名,如main/master) git merge repoNew/main --allow-unrelated-histories # 若出现冲突,解决后提交: # git add . # git commit -m "解决合并冲突"
步骤4:整合到主分支
将合并后的历史同步到repoRoot的主分支:
git checkout main git merge temp-align # 删除临时分支 git branch -d temp-align
步骤5:迁移其他分支
如果两个仓库还有其他分支,重复类似流程:
# 以repoNew的feature分支为例 git checkout -b temp-feature repoRoot/feature-branch # 重复文件迁移操作(若该分支未调整结构) mkdir subFolder git ls-files | grep -v ^subFolder$ | xargs mv -t subFolder/ git add . git commit -m "对齐repoNew feature分支初始结构" # 合并repoNew的feature分支 git merge repoNew/feature-branch --allow-unrelated-histories # 同步到主仓库的feature分支 git checkout feature-branch git merge temp-feature git branch -d temp-feature
验证合并结果
执行以下命令查看合并后的历史结构,确认repoRoot历史在前、repoNew历史接续在后:
git log --oneline --graph
内容的提问来源于stack exchange,提问作者Patrick Wolf
相关产品推荐
相关产品推荐

