git的submodule可以用于在项目中添加子项目,这样就可以让主项目可以引用子项目的同时,子项目又可以进行独立的版本控制管理。当子项目有了更新之后,可以便捷的在主项目中对相应子项目进行更新。
查看submodule 状态
1 | git submodule |
添加submodule
1 | git submodule add [-b master] [remote_repo] [dest_dir] |
上面的命令会将仓库地址remote_repo项目添加到当前项目的dest_dir文件夹。执行完成之后会在当前项目根目录中多一个.gitmodules
文件,并在.git/config
中添加submodule
字段。实际上执行的内容是首先将项目克隆到指定目录,然后在刚才说的两个文件中进行子模块的注册。所以该操作相当于修改了当前项目,所以可以使用git status
查看到新添加了一个目录和一个.gitmodules
文件。
现在直接添加并提交当前项目的修改就完成了子模块的添加
克隆带有submodule的项目
两种方式:
先克隆主项目再更新子模块
1 | git clone [remote_repo] [dest_dir] # 克隆主项目 |
直接克隆再有子模块的项目时只会建立子模块的目录,并不会把子模块克隆回来,.git/config
中也没有submodule
字段,此时使用git submodule
查看子模块时,可以看到它们commit id
前面会有个-
。只有执行了后面子模块的init
命令后才会在.git/config
中注册子模块。update
命令执行完才会将子模块拉回主项目中,此时使用git submodule
可以看到commit id
前面没有了-
。
对于克隆之后的项目,也可以将init
和update
一起执行:
1 | git submodule update --init --recursive |
递归克隆子模块
1 | git clone --recurse-submodules [remote_repo] [dest_dir] # 克隆项目remote_repo并递归克隆其子模块 |
等价于上面的那些命令
注意:此时子模块位于临时分支,不在主分支上
更新submodule
上面说了拉回来的子模块位于临时分支,不在主分支上
如果在主项目中的子模块发生了更新,需要首先进入子模块,将子模块切换到主分支,再拉回来。
如果有多个子模块,可以使用如下命令:
1 | git submodule foreach [command] |
command会在所有子模块中执行,所以可以如下更新所有子模块:
1 | git submodule foreach git checkout master |
然后在主模块中提交更新即可
删除submodule
1 | git submodule deinit <submodule path> # 取消submodule的注册,即从`.gitmodules`中删除 |
git submodule deinit <submodule path>
会取消submodule的注册,即从.gitmodules
中删除相应的子模块。
其他submodule命令
1 | git submodule [--quiet] sync [--recursive] [--] [<path>] |
同步已注册的submodule的URL