合并两个子目录Git仓库至父目录仓库:实操问题与疑问
合并独立Git仓库到父仓库并保留提交历史
项目结构如下:
. └── maindir ├── subdir1 └── subdir2
最初我在subdir1和subdir2中分别创建了Git仓库,后来项目扩大,我创建了父目录maindir并在其中新建了Git仓库,但子目录的变更未被父仓库追踪。我希望将所有仓库的提交历史合并到maindir的Git仓库中,该如何操作?
编辑1
我尝试了合并独立仓库的方法,执行命令后得到如下报错:
$ git pull subdir1 remote: Enumerating objects: 58, done. remote: Counting objects: 100% (58/58), done. remote: Compressing objects: 100% (54/54), done. remote: Total 58 (delta 25), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (58/58), 9.96 KiB | 231.00 KiB/s, done. From standard_deviation * branch HEAD -> FETCH_HEAD hint: Pulling without specifying how to reconcile divergent branches is hint: discouraged. You can squelch this message by running one of the following hint: commands sometime before your next pull: hint: hint: git config pull.rebase false # merge (the default strategy) hint: git config pull.rebase true # rebase hint: git config pull.ff only # fast-forward only hint: hint: You can replace "git config" with "git config --global" to set a default hint: preference for all repositories. You can also pass --rebase, --no-rebase, hint: or --ff-only on the command line to override the configured default per hint: invocation. fatal: refusing to merge unrelated histories
下一步该怎么做?
编辑2
我尝试使用git filter-repo工具,但对部分步骤存在疑问,以下是我的操作笔记,是否正确?
cd /path/to/subdir1 # 现在处于subdir1目录 cd .. # 现在处于maindir目录 mv subdir1 maindir # 在maindir目录下,将subdir1重命名为maindir,形成嵌套结构 git filter-repo --to-subdirectory-filter subdir1/ # 使用工具 cd ../subdir2 # 此处我不理解为何要加`..`?当前应该仍在maindir目录,哪里理解错了? git filter-repo --to-subdirectory-filter subdir2/ # 尚未执行后续步骤 cd ../maindir # 尚未执行 git remote add -f s2 ../subdir2 # 尚未执行 git merge --allow-unrelated-histories s2/main # 尚未执行 git remote remove s2 # 尚未执行
正确操作方案(基于git filter-repo)
前置准备
确保已安装git filter-repo(Git 2.22及以上版本推荐使用,替代老旧的git filter-branch)
处理subdir1仓库
- 进入
subdir1的独立仓库:
cd /path/to/maindir/subdir1
- 重写该仓库的所有提交历史,让所有文件的路径自动加上
subdir1前缀(确保合并到父仓库后路径正确):
git filter-repo --to-subdirectory-filter subdir1
- 返回
maindir的父仓库:
cd ../
- 将处理后的
subdir1仓库作为远程源添加,拉取并合并历史(添加--allow-unrelated-histories解决独立仓库合并的报错):
git remote add -f s1 ./subdir1 git merge --allow-unrelated-histories s1/main git remote remove s1
处理subdir2仓库
- 进入
subdir2的独立仓库:
cd ./subdir2
- 重写提交历史,给所有文件路径加上
subdir2前缀:
git filter-repo --to-subdirectory-filter subdir2
- 返回
maindir的父仓库:
cd ../
- 拉取并合并
subdir2的历史:
git remote add -f s2 ./subdir2 git merge --allow-unrelated-histories s2/main git remote remove s2
验证结果
执行以下命令查看合并后的完整提交历史:
git log --oneline --graph
或者直接查看目录结构,确认subdir1和subdir2的文件都被父仓库正确追踪。
对编辑2操作的修正
你之前的操作存在几个关键错误:
- 不需要重命名
subdir1,--to-subdirectory-filter会自动在提交历史中为所有文件添加指定的目录前缀 - 必须在子仓库内部执行
git filter-repo命令,而不是在maindir中执行 - 从
maindir进入subdir2直接用cd ./subdir2即可,不需要加../(../会跳到maindir的上级目录,这是你理解错误的地方)
内容的提问来源于stack exchange,提问作者ecjb
相关产品推荐
相关产品推荐

