提取Git项目中的子目录为新的项目

目录

一个完成复杂任务的项目可能会由多个组件协作完成。例如单位使用的nwpc-monitor-platform项目,就由下面几个组件构成:

  • nmp-model: 模型
  • nmp-broker: 内网服务器
  • nmp-scheduler: 定时调度器
  • nmp-web: 外网服务器

当项目越来越庞大时,使用一个单一的项目管理各个组件开始变得比较臃肿,为了方便各个组件的后续开发,最好将它们拆开,保存为不同的项目。这就涉及到如何提取Git中的某个子目录为一个新的项目。

提取子目录

Github给出了详细的说明,参见《Splitting a subfolder out into a new repository》。

下面简要说明各个步骤。

首先在一个新的目录中克隆整个项目。

git clone https://github.com/perillaroc/nwpc-monitor-platform.git

接着在克隆的目录中提取子目录,例如提取nmp-broker到master分支

git filter-branch --prune-empty --subdirectory-filter nmp-broker master

然后修改remote origin的url地址,指向新项目。

git remote set-url origin https://github.com/nwpc-oper/nmp-broker.git

最后,更新远程项目。

git push -u origin master

子模块

如果拆分子目录后想要保留原有项目的目录结构不变,可以使用子模块(submodule)将拆分后的项目与原项目关联。 这样原有的部署方案依然有效。但submodule据说有各式各样的坑,所以还是要改掉原有的部署方案,适应项目的变化。

添加子模块的命令如下:

git submodule add https://github.com/nwpc-oper/nmp-broker.git nmp-borker

使用git-filter-repo

2020.01 更新

使用 git filter-branch 会提示使用git-filter-repo工具。

https://github.com/newren/git-filter-repo

该工具CLI接口类似,但效率更高。参看如下示例:

(base) D:\ploto>python ..\git-filter-repo.py --subdirectory-filter ploto-gidat
Parsed 182 commits
New history written in 0.87 seconds; now repacking/cleaning...
Repacking your repo and cleaning out old unneeded objects
HEAD is now at c387ac5 :building_construction: move gidat into ploto_gidat module. fix #6
Enumerating objects: 40, done.
Counting objects: 100% (40/40), done.
Delta compression using up to 12 threads
Compressing objects: 100% (31/31), done.
Writing objects: 100% (40/40), done.
Total 40 (delta 4), reused 27 (delta 0)
Completely finished after 1.71 seconds.