项目中添加子模块

项目中添加子模块

  • 经常有这样的事情,当你在一个项目上工作时,你需要在其中使用另外一个项目。也许它是一个第三方开发的库或者是你独立开发和并在多个父项目中使用的。这个场景下一个常见的问题产生了:你想将两个项目单独处理但是又需要在其中一个中使用另外一个。这里以 hexo-next 为例

  • Git 通过子模块处理这个问题。子模块允许你将一个 Git 仓库当作另外一个 Git 仓库的子目录。这允许你克隆另外一个仓库到你的项目中并且保持你的提交相对独立

  • 你想把 next 加入到你的项目中,可能既要保持你自己的变更,又要延续上游的变更。首先你要把外部的仓库克隆到你的子目录中。你通过 git submodule add 将外部项目加为子模块放入 themes/next 文件夹下:

1
git submodule add https://github.com/Gzbox/hexo-theme-next.git  themes/next
  • 会生成两个文件,输入 git status 可以发现
1
2
3
4
    ...
# new file: .gitmodules
# new file: themes/next
...
  • 尽管 next 是你工作目录里的子目录,但 Git 把它视作一个子模块,当你不在那个目录里时并不记录它的内容。取而代之的是,Git 将它记录成来自那个仓库的一个特殊的提交。当你在那个子目录里修改并提交时,子项目会通知那里的 HEAD 已经发生变更并记录你当前正在工作的那个提交;通过那样的方法,当其他人克隆此项目,他们可以重新创建一致的环境。
  • 修改完以后你可以正常提交了
1
2
3
git add .
git commit -m "first commit with submodule"
git push

克隆带有子模块的项目

  • 你克隆一个带子模块的项目。当你遇到这样一个项目,你将得到了包含子项目的目录,但里面没有文件:
  • next 目录存在了,但是是空的。你必须运行两个命令:git submodule init 来初始化你的本地配置文件,git submodule update 来从那个项目拉取所有数据并检出你上层项目里所列的合适的提交
1
2
3
4
5
git submodule init
...
git submodule update
...

  • 在你的 next 子目录就处于你先前提交的确切状态了。如果另外一个开发者变更了 next 的代码并提交,你拉取那个引用然后归并之,将得到稍有点怪异的东西:因为你所拥有的指向子模块的指针和子模块目录的真实状态并不匹配。为了修复这一点,你必须再次运行 git submodule update:
1
2
git merge origin/master
git submodule update