详细帖子请看:
https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%AD%90%E6%A8%A1%E5%9D%97
无奈里面东西太多,我稍微总结下常用的:
- 添加子库:
git submodule add
命令后面加上想要跟踪的项目的相对或绝对 URL 来添加新的子模块,这个操作会在项目主目录下产生一个隐藏的.gitmodules文件,这个文件里面就包含子模块的名称、本项目下的路径、URL路径、分支的信息。
- 检出带子模块库:
有两种方式:
- 直接用
git clone --recurse-submodules
后面跟项目路径就会自动初始化并更新仓库中的每一个子模块, 包括可能存在的嵌套子模块。 - 如果
git clone
之后忘记--recurse-submodules
了,或者按照步骤1新添加的子模块,则进入项目目录,输入git submodule update --init --recursive
这样子模块文件夹里面就有子库的内容了。
- 切换子模块分支:
刚clone下来的子模块当然是不能用的,因为默认是master分支,就需要切换到想要的开发分支上,需要更改下第1步里面的.gitmodules文件,直接在主项目目录下使用命令
git config -f .gitmodules submodule.xxxx(子库名).branch xxxx(想要切换的分支名)
来完成切换,做完之后记得最后要提交.gitmodules的更改。然后使用命令git submodule update --remote
来切换到并更新刚才的分支
- 更新子模块:
如果子模块上游有更新,我们想要同步到本地主项目里面的子模块,应该运行命令:git submodule update --init --recursive
,--recursive保证所有嵌套的子模块都会被更新。
- 子模块在使用
git submodule update
更新之后都会变成游离状态,如果此时去修改子模块内容并且希望提交到子模块远端,不会成功。所以,我们每做完这种更新之后,都要手动进入子库的文件夹,然后git checkout
一下我们希望使用的分支。这也是我们提交子库内容修改的前提,其背后的原因其实不难理解,主项目下的git按照.gitmodules文件中的要求检出了子库的分支,但子库下的git其实并不知道主项目的git做了什么,它只知道自己的内容变了,commit id对应不上了,自然就变成了游离状态,所以它需要手动重新跟踪到远端的正确分支。最麻烦的事情是我们所有的嵌套子库都要手动执行相同的操作:进入子库目录,checkout子库分支,不放心的话再git pull一下。 - 发布子模块改动:
git push
命令后跟--recurse-submodules=on-demand
可以在主目录将自己下层的子库更新推送到远端,但是仅限于自己的子库,自己子库的子库就不行了。所以我建议如果要push,请进入子库自行推送。然后记得回到主库提交子库文件夹的更新,因为子库内容变了,主库里面子库的SHA值就变了,这种提交其实仅仅提交一个SHA值。
基本需要用到的就这些了,如有需要欢迎大家继续补充。