如何拆分Git子目录到新仓库并保留文件重命名/移动历史
解决Git目录迁移并保留完整重命名/移动历史的方案
我来帮你搞定这个问题——你之前尝试的方法没留住重命名历史,核心原因是没用到能追踪文件blob关联的工具。官方现在更推荐用git filter-repo替代git filter-branch,它能精准梳理提交历史,完整保留文件的重命名、移动记录。下面是一步步的操作指南:
步骤1:备份原仓库
操作前先做个备份,防止误操作搞坏原仓库:
cp -r projectA projectA-backup
步骤2:安装git filter-repo
如果你的环境还没装这个工具:
- Ubuntu/Debian:
sudo apt install git-filter-repo - macOS:
brew install git-filter-repo - 其他系统可以通过包管理器或官方源码编译安装
步骤3:过滤原仓库,只保留dir1和dir2的完整历史
进入原仓库目录,执行过滤命令:
cd projectA git filter-repo --path dir1 --path dir2
这个命令会自动遍历所有提交,只保留和dir1、dir2相关的内容,包括这些目录/文件之前的所有重命名、移动记录——它是通过追踪文件的blob对象(内容唯一标识)来关联历史,而不是只看表面路径,这就是它比你之前用的方法靠谱的地方。
如果需要把dir1和dir2合并到新仓库的同一个目录下(比如combined目录),可以加上--to-subdirectory-filter参数:
git filter-repo --path dir1 --path dir2 --to-subdirectory-filter combined
步骤4:创建新仓库projectB并迁移内容
现在处理后的projectA已经只包含目标目录和完整历史了,接下来把它迁移到新仓库:
# 新建并进入projectB目录 mkdir ../projectB && cd ../projectB git init # 添加处理后的projectA作为远程仓库 git remote add origin ../projectA # 拉取所有内容(替换master为你的主分支名,比如main) git pull origin master # 之后可以移除临时远程,换成你的正式远程仓库 git remote remove origin git remote add origin <你的projectB远程仓库地址> git push -u origin master
验证历史是否完整
迁移完成后,在projectB里执行以下命令验证:
# 追踪某个文件的完整历史,包括重命名 git log --follow dir1/somefile # 或者用gitk可视化查看 gitk --follow dir1/somefile
你会看到这个文件所有的提交记录,包括它之前的路径变更、重命名操作。
为什么你之前的方法失败了?
git filter-branch的index-filter方式:它是基于当前路径做过滤,没有追踪文件的blob关联,导致重命名前的旧路径提交被过滤掉了;git subtree split:它只针对单个目录处理,没法同时处理多个目录并保留跨目录或重命名的关联历史;- 补丁方式:补丁是基于快照生成的,会丢失文件的历史关联信息,自然没法追踪重命名记录。
内容的提问来源于stack exchange,提问作者EJS
相关产品推荐
相关产品推荐

