166 lines
4.0 KiB
Markdown
Executable File
166 lines
4.0 KiB
Markdown
Executable File
# Submodule 子模块
|
||
|
||
https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%AD%90%E6%A8%A1%E5%9D%97#_git_submodules
|
||
|
||
## 新增
|
||
|
||
* 添加子模块
|
||
|
||
```bash
|
||
git submodule add <子模块地址> [指定路径(可选)]
|
||
# 此时 .gitmodules .git/config .git/modules 会添加子模块的信息
|
||
# 子模块目录也会下载,不为空
|
||
|
||
# 1. 未初始化: 指定分支
|
||
git submodule add -b main [URL to Git repo]
|
||
|
||
# 2. 已初始化: 修改分支
|
||
git config -f .gitmodules submodule.DbConnector.branch main
|
||
# 这里的 DbConnector 是子模块的名称,stable 是分支的名称
|
||
|
||
# 或者修改.gitmodules
|
||
[submodule "path/to/submodule"]
|
||
path = path/to/submodule
|
||
url = https://github.com/example/repo.git
|
||
branch = main
|
||
|
||
# 更新
|
||
git add path/to/submodule
|
||
git commit -m "Update submodule to use specific branch"
|
||
git submodule update --recursive --remote
|
||
```
|
||
|
||
* 查看
|
||
|
||
```bash
|
||
git status
|
||
# 发现只列出 submodule 目录而不是里面所有的文件
|
||
# 对于模块外的项目来说,把子模块整个文件夹当成一个文件
|
||
```
|
||
|
||
* 提交
|
||
|
||
```bash
|
||
git add .
|
||
git commmit -m 'git add submodule'
|
||
```
|
||
|
||
## 克隆
|
||
|
||
如果是克隆已经添加了子模块的项目
|
||
|
||
```bash
|
||
# 拉完主项目,此时子模块的目录是空的
|
||
git submodule init # 初始化本地配置文件
|
||
git submodule update # 拉取对应的提交
|
||
# 或者
|
||
git submodule update --init --recursive
|
||
|
||
# 或者在拉取的时候添加参数
|
||
git clone <地址> --recurse-submodules
|
||
|
||
# 子模块不一定是最新的,版本是在主项目里记录的版本
|
||
```
|
||
|
||
## 更新
|
||
|
||
* 情况1: 子模块的上游更新了, 本地还是旧的
|
||
|
||
```bash
|
||
# 子模块是一个独立的git项目,它并不需要知道自己被谁用
|
||
cd <子模块目录>
|
||
git pull
|
||
# 和第一次添加一样, 并不会在status里显示模块里面的文件更新
|
||
# submodule的版本控制在于submodule git 的 commit id, 所以要提交这些更新记录
|
||
cd <仓库目录>
|
||
git add .
|
||
git commit -m 'submodule update'
|
||
|
||
# 或者
|
||
git submodule update --remote --recursive # 递归更新子模块
|
||
git add .
|
||
git commit -m 'submodule update'
|
||
```
|
||
|
||
当项目的子模块很多的时候,可以一个命令更新所有的模块
|
||
|
||
```bash
|
||
git submodule foreach 'git pull origin master'
|
||
```
|
||
|
||
* 情况2: 远程仓库**主项目**的子模块信息更新了, 本地的子模块还是旧的
|
||
|
||
```bash
|
||
# 先更新主项目
|
||
git pull origin master
|
||
# 再根据主项目里的记录更新本地子模块
|
||
git submodule init
|
||
git submodule update
|
||
```
|
||
|
||
* 情况3: 对本地的子模块作了个人的修改
|
||
|
||
不能提交到子模块的仓库, 要自己fork一份再修改
|
||
|
||
* 情况4: 使用远程仓库覆盖本地的子模块
|
||
|
||
```sh
|
||
cd 子模块的目录
|
||
git reset --hard origin/main
|
||
```
|
||
|
||
## 修改模块
|
||
|
||
如果有子模块的修改权,那么把子模块当成单独的项目修改提交
|
||
|
||
## 删除模块
|
||
|
||
```bash
|
||
# 不要去手动修改 .gitmodules .git/config .git/modules cached
|
||
# 先卸载
|
||
git submodule deinit <子模块目录>
|
||
# 添加 --force 参数,则子模块内有本地修改,也会被移除
|
||
git submodule deinit --force static/platform
|
||
# 删除文件夹
|
||
git rm <子模块目录>
|
||
git commit -m "delete submodule"
|
||
```
|
||
|
||
## 拆分已有文件为子模块
|
||
|
||
```bash
|
||
# 建立新分支
|
||
git checkout -b test
|
||
# 建立单独的仓库
|
||
cd <sub-module>
|
||
git init
|
||
git add .
|
||
git commit -m "version 1.0 of sub-module"
|
||
git remote add origin <sub-module-originUrl>
|
||
git push -u origin master
|
||
|
||
# 把文件夹从暂存区和工作区删除
|
||
cd ../
|
||
git rm -r <sub-module>
|
||
git commit -m "remove sub-module directory"
|
||
rm -rf <sub-module>
|
||
|
||
# 注册为子模块
|
||
git submodule add <sub-module-originUrl> <sub文件夹>
|
||
git commit -m "add submodule version 1.0"
|
||
```
|
||
|
||
* 存在问题点:如果要回到拆分前没有子模块的分支,结果发现提示报错
|
||
|
||
```bash
|
||
error: The following untracked working tree files would be overwritten by checkout:
|
||
sub/a.txt
|
||
Please move or remove them before you switch branches.
|
||
# 可以强制切换, 注意强制切换前保存修改
|
||
git checkout -f master
|
||
# 再回到test分支,发现子模块文件夹空了
|
||
cd <sub-module>
|
||
# 找回
|
||
git checkout .
|
||
```
|