[TOC]
# 使用场景
基于公司的项目会越来越多,常常需要提取一个公共的类库提供给多个项目使用,但是这个`library`怎么和`git`在一起方便管理呢?
我们需要解决下面几个问题:
* 如何在 git 项目中导入`library`库?
* `library`库在其他的项目中被修改了可以更新到远程的代码库中?
* 其他项目如何获取到`library`库最新的提交?
* 如何在 clone 的时候能够自动导入`library`库?
解决以上问题,可以考虑使用 git 的`Submodule`来解决。
# 什么是 Submodule?
submodule 是一个多项目管理工具,可以在当前 repo 中包含其它 repos、作为当前 repo 的子目录使用,同时能够保持 repos 之间的独立。
子项目拥有自己的 独立的`commit`,`push`,`pull`,而与主项目互不干扰。
主项目只需要记录子项目的地址和所需要的 `commit id`,通过地址和 `commit id` 就能够得到对应的子项目。
# 使用 Submodule
使用 git 命令可以直接添加 Submodule:
```shell
# 在当前 repo 添加一个子模块,使用 git status 命令可以看到。
$ git submodule add git@github.com:xxx/xxx.git path/to/xxx
```
命令执行完成,会在当前工程根路径下生成一个名为“.gitmodules”的文件,其中记录了子模块的信息。添加完成以后,再将子模块所在的文件夹添加到工程中即可。
修改子模块文件后,在当前 repo 执行`git status`只会看到有模块的 changes,而不是具体子模块文件:
```
diff --git a/path/to/submodule b/path/to/submodule
--- a/path/to/submodule
+++ b/path/to/submodule
@@ -1 +1 @@
-Subproject commit xxxxxxx
+Subproject commit xxxxxxx-dirty
```
# 克隆 Submodule
有两种方式:
* 采用递归的方式(`--recursive-submodules`)克隆整个项目
* 克隆父项目,再更新子项目(`--recursive-submodules`)
1. 采用递归参数`--recurse-submodules` (With version 2.13 of Git and later,`--recurse-submodules`can be used instead of`--recursive`)
```shell
$ git clone --recurse-submodules https://github.com/xi-editor/xi-mac
```
2. 第二种方法先 clone 父项目,再初始化子项目
```shell
$ git clone https://github.com/xi-editor/xi-mac
$ cd xi-mac
$ git submodule update --init --recursive
```
# 其他
Just to clarify for everyone.`git submodule update --recursive`looks to see which revision the parent repository has stored for each submodule, then checks out that revision in each submodule. It does**NOT**pull the latest commits for each submodule.`git submodule foreach git pull origin master`or`git pull origin master --recurse-submodules`is what you want if you intend to update each submodule to the latest from their origin repositories. Only then will you get pending changes in the parent repo with updated revision hashes for submodules. Check those in and you're good.
Note that neither`git pull --recurse-submodules`nor`git submodule update --recursive`does**not**initialize newly added submodules. To initialize them you need run`git submodule update --recursive --init`. Quote from[manual](https://git-scm.com/docs/git-submodule):*If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the submodule with the --init option.*
# `.gitattributes`
也可以为所有Git库设置统一的gitattributes文件:
~~~html
git config --get core.attributesFile
git config --global --get core.attributesFile
~~~
# Reference
[How to “git clone” including submodules?](https://stackoverflow.com/questions/3796927/how-to-git-clone-including-submodules)
[Easy way to pull latest of all git submodules](https://stackoverflow.com/questions/1030169/easy-way-to-pull-latest-of-all-git-submodules)
[使用 Git Submodule 管理子模块](https://segmentfault.com/a/1190000003076028)
[Git - 子模块](https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%AD%90%E6%A8%A1%E5%9D%97)
`man git-submodule`
[git submodules - Git diff says subproject is dirty - Stack Overflow](https://stackoverflow.com/questions/4873980/git-diff-says-subproject-is-dirty)
- 介绍
- 1. Get Git - 安装并且设置Git
- 2. Repository - 建立一个本地的repository
- 3. Commit to it - 检查状态、新增或修改commits
- 4. GitHubbin - 注册GitHub帐号
- 5. Remote Control - 将repository做本地和远程的连接
- 6. Forks and Clones - Fork和clone一个开源的计划
- 7. Branches aren't just for Birds - 建立一个feature branch
- Git分支开发模型
- 8. It's a Small World - 邀请并和别人合作
- 9. Pull, Never Out of Date - 利用Push和pull来和GitHub.com同步
- 10. Requesting You Pull Please - 建立一个pull request
- 11. Merge Tada - Merge和删除branches
- 学会 GitHub
- GitHub 使用指南
- git 与 github 模板配置
- GitHub Actions
- 实用技巧
- Git Flow
- Submodule子模块
- 工作记录
- 常用命令
- 帮助
- 资源
- 解疑答惑