说来惭愧,这篇是AI帮助我解决实际问题后,又生成的一篇博客,效率特别高。
在开发中,我们常会遇到一个项目变大、拆分或者整合的需求。如果你想将一个已有 Git 提交历史的小项目(例如:bbb/
)合并到另一个新的 Git 仓库(例如 GitHub 上新建的仓库 aaa
),并保留其所有提交历史记录,这篇博客将为你总结完整的操作流程和注意事项。
🧩 问题背景
我本地有一个项目叫 bbb/
,它是一个完整的 Git 仓库,有自己的提交历史。但我后来希望将它作为子目录的形式迁入另一个新的仓库 aaa/
中去,也就是想要实现结构如下:
aaa/
└── bbb/ # 原项目内容在这里,保留所有 commit 历史
但是直接复制粘贴代码会丢失原始提交历史记录;而直接合并 .git
会导致仓库结构错乱。
🧪 我遇到的问题
一开始,我使用了 git filter-repo
来把项目目录转换成子目录的历史,但目录嵌套出现了问题,执行完:
python -m git_filter_repo --to-subdirectory-filter bbb --force
之后,目录变成了:
bbb/bbb/your-files...
也就是说,子目录又包了一层自己的名字,导致整个目录嵌套了一层,不符合我的预期。
✅ 正确的操作流程
以下是正确的迁移流程,总结如下:
📁 假设目录结构如下
/your-path/
├── bbb/ # 原项目,有完整 Git 历史
🔨 步骤 1:在 GitHub 上创建新仓库 aaa
比如:
仓库名:
aaa
GitHub 地址:
git@github.com:yourname/aaa.git
🧪 步骤 2:在 bbb 目录中运行 git filter-repo
需要安装 git filter-repo
,教程可查看附录。
这一步会把整个项目的 Git 历史“包裹进” bbb/
子目录中:
cd bbb
python -m git_filter_repo --to-subdirectory-filter bbb --force
执行完后,项目结构会变成:
bbb/
└── bbb/
└── your-original-code...
(此时你的代码被包进了 bbb/
)
🧼 步骤 3:整理目录结构(可选)
这里你需要把 bbb/bbb/
中提交的数据拉回到 bbb/
中。
🌐 步骤 4:推送到远程仓库(aaa)
初始化 GitHub 仓库(如果还没 init 的话):
git remote add origin git@github.com:yourname/aaa.git
推送代码及其历史记录:
git push -u origin main
如果你当前分支不是
main
,请先切换:git checkout -b main
。
🎉 最终效果
在 GitHub 上打开 aaa
仓库,你将看到代码出现在 bbb/
子目录中,且每一次提交都被完整保留。
📎 附录:如何安装 git_filter_repo
git_filter_repo
是一个替代 git filter-branch
的高效工具,用于重写 Git 历史。由于它不是 Git 默认安装的一部分,我们需要手动安装。
✅ 方法一:通过 pip
安装(推荐)
适合大多数开发者,只需要有 Python 环境即可。
pip install git-filter-repo
安装后,你可以通过以下方式使用:
python -m git_filter_repo --help
⚠️ 注意:如果你运行 git filter-repo
报错(如 “git: 'filter-repo' is not a git command”),说明你的环境变量中没有自动添加别名,建议直接使用:
python -m git_filter_repo ...
✅ 方法二:手动安装脚本并加入 Git 命令目录(进阶)
适合想直接使用 git filter-repo
命令的用户:
前往 GitHub 下载脚本:
下载
git-filter-repo.py
文件,重命名为git-filter-repo
(无后缀)将该文件放入 Git 的执行目录中,例如:
C:\Program Files\Git\mingw64\libexec\git-core\
确保该目录在系统环境变量 PATH 中
完成后,即可直接使用任一命令:
git filter-repo ...
python -m git_filter_repo ... //或使用Python命令
评论区