使用背景

经常碰到这种情况:当你在一个Git 项目上工作时,你需要在其中使用另外一个Git 项目。也许它是一个第三方开发的Git 库或者是你独立开发和并在多个父项目中使用的。这个情况下一个常见的问题产生了:你想将两个项目单独处理但是又需要在其中一个中使用另外一个。
在Git 中你可以用子模块submodule来管理这些项目,submodule允许你将一个Git 仓库当作另外一个Git 仓库的子目录。这允许你克隆另外一个仓库到你的项目中并且保持你的提交相对独立。

添加子模块

此文中统一将远程项目https://github.com/maonx/vimwiki-assets.git克隆到本地assets文件夹。

  1. git submodule add https://github.com/maonx/vimwiki-assets.git assets

添加子模块后运行git status, 可以看到目录有增加1个文件.gitmodules, 这个文件用来保存子模块的信息。

  1. git status
  2. On branch master
  3. Initial commit
  4. Changes to be committed:
  5. (use "git rm --cached <file>..." to unstage)
  6. new file: .gitmodules
  7. new file: assets

查看子模块

  1. git submodule
  2. e33f854d3f51f5ebd771a68da05ad0371a3c0570 assets (heads/master)

更新子模块

  • 更新项目内子模块到最新版本

    1. git submodule update
  • 更新子模块为远程项目的最新版本

    1. git submodule update --remote

    克隆包含子模块的项目

    克隆包含子模块的项目有二种方法:一种是先克隆父项目,再更新子模块;另一种是直接递归克隆整个项目。

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

  • 克隆父项目

    1. git clone https://github.com/maonx/vimwiki-assets.git assets
  • 查看子模块

    1. git submodule
    2. -e33f854d3f51f5ebd771a68da05ad0371a3c0570 assets

    子模块前面有一个-,说明子模块文件还未检入(空文件夹)。

  • 初始化子模块

    1. git submodule init
    2. Submodule 'assets' (https://github.com/maonx/vimwiki-assets.git) registered for path 'assets'

    初始化模块只需在克隆父项目后运行一次。

  • 更新子模块

    1. git submodule update
    2. Cloning into 'assets'...
    3. remote: Counting objects: 151, done.
    4. remote: Compressing objects: 100% (80/80), done.
    5. remote: Total 151 (delta 18), reused 0 (delta 0), pack-reused 70
    6. Receiving objects: 100% (151/151), 1.34 MiB | 569.00 KiB/s, done.
    7. Resolving deltas: 100% (36/36), done.
    8. Checking connectivity... done.
    9. Submodule path 'assets': checked out 'e33f854d3f51f5ebd771a68da05ad0371a3c0570'

    递归克隆整个项目

    1. git clone https://github.com/maonx/vimwiki-assets.git assets --recursive

    递归克隆整个项目,子模块已经同时更新了,一步到位。

    修改子模块

    在子模块中修改文件后,直接提交到远程项目分支。

    1. git add .
    2. git ci -m "commit"
    3. git push origin HEAD:master

    删除子模块

    删除子模块比较麻烦,需要手动删除相关的文件,否则在添加子模块时有可能出现错误
    同样以删除assets文件夹为例

  • 删除子模块文件夹

    1. git rm --cached assets
    2. rm -rf assets
  • 删除.gitmodules文件中相关子模块信息

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

    1. [submodule "assets"]
    2. url = https://github.com/maonx/vimwiki-assets.git
  • 删除.git文件夹中的相关子模块文件

    1. rm -rf .git/modules/assets