git 子模块

0. 子模块信息

.gitmodules文件用来保存子模块的信息。

1. 查看子模块

$ git submodule
# 已检出子模块代码
cedbe91340dbcff661fa089b116441b11b050d38 themes/hugo-nuo (heads/master)

# 前面带 - 表示未检出代码,子模块是空文件夹
-cedbe91340dbcff661fa089b116441b11b050d38 themes/hugo-nuo (heads/master)

2. 创建子模块

2.2 方法1

# 在父项目仓库目录下

# Usage
$ git submodule add [url] [path]

# with path
$ git submodule add http://202.38.69.179:8000/ahxieqi/test-submdl.git testsubmdl
# 在当前本地仓库testsubmdl文件夹下创建子模块

# without path
$ git submodule add http://202.38.69.179:8000/ahxieqi/test-submdl.git
# 在当前本地仓库当前文件夹下创建子模块

2.3 方法2

例如我们要创建如下结构的项目

project
  |–moduleA
  |–readme.txt

创建project版本库,并提交readme.txt文件

$ git init --bare project.git   # 将初始化的裸库,存放在project.git文件夹下
$ git clone project.git project1    # 将project.git库,存放在project1文件夹下
$ cd project1   # 进入project1文件夹
$ echo "This is a project." > readme.txt    # 创建并写入 a.txt 文件
$ git add . # 将修改添加到暂存区
$ git commit -m "add readme.txt"    # 将 a.txt 提交到本地库
$ git push origin master    # 将修改推送到远程库
$ cd ..

创建moduleA版本库,并提交a.txt文件

$ git init --bare moduleA.git   # 将初始化的裸库,存放在moduleA.git文件夹下
$ git clone moduleA.git moduleA1    # 将moduleA.git库,存放在moduleA1文件夹下
$ cd moduleA1   # 进入moduleA1文件夹
$ echo "This is a submodule." > a.txt   # 创建并写入 a.txt 文件
$ git add . # 将修改添加到暂存区
$ git commit -m "add a.txt" # 将 a.txt 提交到本地库
$ git push origin master    # 将修改推送到远程库

在project项目中引入子模块moduleA,并提交子模块信息

$ cd project1   # 进入project1文件夹
$ git submodule add ../moduleA.git moduleA  # 在moduleA目录下添加子模块
$ git status
$ git diff
$ git add . # 将修改添加到暂存区
$ git commit -m "add submodule" # 将修改添加到本地库
$ git push origin master    # 将修改添加到远程库

3. 修改子模块

修改子模块之后只对子模块的版本库产生影响,对父项目的版本库不会产生任何影响。如果父项目需要用到最新的子模块代码,我们需要更新父项目中submodule commit id,默认的我们使用git status就可以看到父项目中submodule commit id已经改变了,我们只需要再次提交就可以了。

# 在主项目里修改 submodule

$ cd project1/moduleA
$ git branch
$ echo "This is a submodule." > b.txt
$ git add .
$ git commit -m "add b.txt"
$ git push origin master    # 将修改同步到子模块的远程库
$ cd ..
$ git status
$ git diff
$ git add .
$ git commit -m "update submodule add b.txt"
$ git push origin master    # 将修改同步到父项目的远程库

4. 更新子模块

先进入子模块,然后切换到需要的分支,这里是master分支,然后对子模块pull,这种方法会改变子模块的分支。

$ cd [submodule_folder] # 进入子模块目录
$ git checkout master   # 切换到需要的分支,默认子模块分支不是master分支
$ cd .. # 进入父项目目录
$ git submodule foreach git pull    # pull 子模块的更新
$ git status
$ git add .
$ git commit -m 'update submodule add c.txt'
$ git push origin master    # 更新父项目下的子模块

5. 克隆包含子模块的项目

5.1 方法1

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

# 1. 克隆父项目
$ git clone https://github.com/maonx/vimwiki-assets.git assets

# 2. 查看子模块
$ git submodule
-e33f854d3f51f5ebd771a68da05ad0371a3c0570 assets
# 子模块前面有一个-,说明子模块文件还未检入(空文件夹)。

# 3. 初始化子模块
$ git submodule init
Submodule 'assets' (https://github.com/maonx/vimwiki-assets.git) registered for path 'assets'
# 初始化模块只需在克隆父项目后运行一次。

# 4. 更新子模块
$ git submodule update
Cloning into 'assets'...
...
Submodule path 'assets': checked out 'e33f854d3f51f5ebd771a68da05ad0371a3c0570'

5.2 方法2

递归克隆整个项目

git clone --recursive https://github.com/maonx/vimwiki-assets.git assets
# 递归克隆整个项目,子模块已经同时更新了,一步到位。

6. 删除子模块

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

# 2. 删除.gitmodules文件中相关子模块信息
[submodule "assets"]
  path = assets
  url = https://github.com/maonx/vimwiki-assets.git

# 3. 删除.git/config中的相关子模块信息
[submodule "assets"]
  url = https://github.com/maonx/vimwiki-assets.git

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

参考链接:

http://www.cnblogs.com/nicksheng/p/6201711.html
https://laozhu.me/post/git-submodule-tutorial/

Table of Contents