You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

合并两个子目录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仓库

  1. 进入subdir1的独立仓库:
cd /path/to/maindir/subdir1
  1. 重写该仓库的所有提交历史,让所有文件的路径自动加上subdir1前缀(确保合并到父仓库后路径正确):
git filter-repo --to-subdirectory-filter subdir1
  1. 返回maindir的父仓库:
cd ../
  1. 将处理后的subdir1仓库作为远程源添加,拉取并合并历史(添加--allow-unrelated-histories解决独立仓库合并的报错):
git remote add -f s1 ./subdir1
git merge --allow-unrelated-histories s1/main
git remote remove s1

处理subdir2仓库

  1. 进入subdir2的独立仓库:
cd ./subdir2
  1. 重写提交历史,给所有文件路径加上subdir2前缀:
git filter-repo --to-subdirectory-filter subdir2
  1. 返回maindir的父仓库:
cd ../
  1. 拉取并合并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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:05:33