在Git 中你可以用子模块submodule来管理这些项目,submodule允许你将一个Git 仓库当作另外一个Git 仓库的子目录。这允许你克隆另外一个仓库到你的项目中并且保持你的提交相对独立。

添加子模块

此文中统一将远程项目https://github.com/zmide/test.git克隆到本地assets文件夹。

git submodule add https://github.com/zmide/test.git assets

添加子模块后运行git status, 可以看到目录有增加1个文件.gitmodules, 这个文件用来保存子模块的信息。

git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   .gitmodules
    new file:   assets

查看子模块

git submodule
 e336666666666666666666999999990570 assets (heads/master)

更新子模块

  • 更新项目内子模块到最新版本
git submodule update

  • 更新子模块为远程项目的最新版本
git submodule update --remote 

克隆包含子模块的项目

克隆包含子模块的项目有二种方法:一种是先克隆父项目,再更新子模块;另一种是直接递归克隆整个项目。

克隆父项目,再更新子模块

  1. 克隆父项目
git clone https://github.com/zmide/test.git assets

  1. 查看子模块
git submodule
 -e33f8599999666666666666666666663c0570 assets

子模块前面有一个-,说明子模块文件还未检入(空文件夹)。

  1. 初始化子模块
git submodule init
Submodule 'assets' (https://github.com/zmide/test.git) registered for path 'assets'

初始化模块只需在克隆父项目后运行一次。

  1. 更新子模块
git submodule update
Cloning into 'assets'...
remote: Counting objects: 151, done.
remote: Compressing objects: 100% (80/80), done.
remote: Total 151 (delta 18), reused 0 (delta 0), pack-reused 70
Receiving objects: 100% (151/151), 1.34 MiB | 569.00 KiB/s, done.
Resolving deltas: 100% (36/36), done.
Checking connectivity... done.
Submodule path 'assets': checked out 'e99664d999999999996666637152616221'

递归克隆整个项目

git clone https://github.com/zmide/test.git assets --recursive 

递归克隆整个项目,子模块已经同时更新了,一步到位。

修改子模块

在子模块中修改文件后,直接提交到远程项目分支。

git add .
git ci -m "commit"
git push origin HEAD:master

删除子模块

删除子模块比较麻烦,需要手动删除相关的文件,否则在添加子模块时有可能出现错误
同样以删除assets文件夹为例

  1. 删除子模块文件夹
git rm --cached assets
rm -rf assets

  1. 删除.gitmodules文件中相关子模块信息
[submodule "assets"]
  path = assets
  url = https://github.com/zmide/test.git

  1. 删除.git/config中的相关子模块信息
[submodule "assets"]
  url = https://github.com/zmide/test.git

  1. 删除.git文件夹中的相关子模块文件
rm -rf .git/modules/assets

这里讲一下将上面的技术运用到我们实际项目上

利用 git config 设置 alias 可以简化我们输入 git 的指令

首先我们在全局安排上 git pulla 以后就可以直接用 git pulla 来更新主项目和旗下模块的代码了,注意:这是在全局配置下设置的所以设置成功一次就好了,不需要全部项目设置一遍

git config --global alias.pulla '!git submodule init && git submodule update && git pull --recurse-submodules '

然后在我们项目下添加子模块,我这里拿公司的 toolkits 模块来举例

git submodule add http://code.haxibiao.cn/android/toolkits android/toolkits

添加成功后执行 git pulla 拉一下代码

关于 android/toolkits 更新后需要把 android 目录下的 settings.gradle 文件中的 toolkits 引用路径改为如下

include ':toolkits'
project(':toolkits').projectDir = new File('./toolkits')
// project(':toolkits').projectDir = new File('../node_modules/@hxf/toolkits_npm')

重新打包安装就好了