如何拆分Git仓库,保留指定多目录并调整目录结构?
拆分Git仓库并保留多目录提交历史
问题背景
现有Git仓库结构如下:
. ├── cmd │ ├── ctl │ │ └── main.go │ └── service │ └── main.go ├── go.mod ├── go.sum ├── internal │ ├── cmd │ │ ├── build.go │ │ ├── convert.go │ │ └── root.go │ └── util │ ├── command.go │ └── fileutil │ ├── tar.go │ └── unzip.go ├── Makefile ├── pkg │ ├── artifact │ │ ├── artifact.go │ │ └── archive │ │ ├── archive.conf │ │ └── archive.go │ ├── errdefs │ │ ├── error.go │ │ └── error_target.go │ └── addons │ ├── settings.go │ └── addons.go ├── README.md └── tests.sh
需要创建一个新仓库,仅保留以下路径的内容并调整目录结构:
cmd/ctl/*internal/cmd/*
最终目标目录结构:
. ├── ctl │ └── main.go ├── cmd ├── build.go ├── convert.go └── root.go
此前尝试过单目录拆分方法,但无法满足多目录保留并调整结构的需求。
解决方案:使用git filter-repo实现多目录拆分与结构调整
git filter-repo是Git官方推荐的仓库历史重写工具,比老旧的git filter-branch更高效可靠,以下是具体步骤:
1. 克隆原仓库的镜像副本
先创建原仓库的镜像克隆,避免操作影响原仓库:
git clone --mirror <原仓库URL> repo-mirror cd repo-mirror
2. 配置过滤规则,保留目标目录并调整结构
创建一个规则文件(比如filter-rules.txt),定义要保留的路径以及目录重映射规则:
keep cmd/ctl/ keep internal/cmd/ rename cmd/ctl/ ctl/ rename internal/cmd/ cmd/
然后执行过滤命令:
git filter-repo --paths-from-file filter-rules.txt
3. 验证结果
执行完后,查看当前仓库的目录结构是否符合预期:
git checkout main ls -la
此时应该能看到目标结构:ctl/和cmd/目录,且所有相关提交历史都被保留。
4. 推送到新仓库
创建新的空Git仓库,然后将本地镜像仓库的内容推送过去:
git remote set-url origin <新仓库URL> git push --mirror
注意事项
- 确保已安装
git filter-repo:如果你的Git版本低于2.22.0,需要单独安装该工具(可通过pip安装:pip install git-filter-repo) - 此操作会重写Git历史,请勿在原仓库直接操作,务必使用镜像副本
- 如果新仓库已有内容,推送前需确保为空或协调好历史冲突
内容的提问来源于stack exchange,提问作者BhanuKiran
相关产品推荐
相关产品推荐

