Git 进阶:Submodule
Git has something called submodule support. This allows you to specify one or more other git repositories within another – a bit like svn:externals (except trickier, but more powerful of course :).
Git Submodule 对于大型团队项目来说,是个很好的团队协作工具,它允许你的项目模块化成为每一个 Repository,最终汇聚成一个完整的项目。换句话说,Git Submodule 可以别人的 Repo 挂到你自己的 Repo 中的任何位置,成为的 Repo 的一部分。
下面说说一些基本的操作
1. 增加一个 Submodule 到你的项目
$ git submodule add [email protected]:another_project.git another_project
该命令会在你的项目 Repository 下产生一个 .gitmodules 文件,来记录你的 Submodule 信息,同时 another_project项目也clone下来,此时观察你的 Repo
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# new file: .gitmodules
# new file: another_project
你可能会注意到,git 只记录了 submodule 目录,而没有记录目录下的文件。实际上,git 是按照 commit id 来比对 submodule 变动的
$ git add .gitmodules another_project
$ git commit -m "Add another_project submodule"
$ git submodule init
2. 更新你项目中的 Submodule
$ cd another_project
$ git pull origin master
$ cd your_project
$ git add another_project
$ git commit another_project -m "Updated another_project Submodule to latest HEAD"
$ git push
更新 repo 下所有的 submodules
$ git submodule foreach git pull
3. 修改你项目中的 Submodule
如果你恰巧拥有 Submodule 远程 commit 权限,进入你的 Submodule 目录,作些修改,提交
$ cd another_project
...make your changes...
$ git commit -a -m "fixed a bug"
$ git push origin master
$ cd your_project
$ git add another_project
$ git commit -m "Updated another_project"
$ git push origin master
重要一点:由于 Submodule 只比对 commit id,所以你务必要在 Submodule 内做 commit、push后,再到你当前的 Repo 作 push
4. 删除 Submodule
$ cd your_project
$ git rm --cached another_project
$ rm -rf another_project
$ vim .gitmodules
...remove another_project...
$ vim .git/config
...remove another_project...
$ git commit -a -m 'Remove another_project submodule'
Git Submodule 虽然是个强大的团队合作开发功能,但请务必不要混乱,否则一些版本错乱是难免的
5. 示例
clone 一个含 submdule 的分支
$ git clone [email protected]:Ihavee/vimrc.git ~/.vim
$ cd ~/.vim
$ git submodule update --init
clone 一个含 submodule 的分支,其 submodule 下再含 submodule,可以采用递归参数 --recursive
$ git clone [email protected]:Ihavee/dotfiles.git
$ cd dotfiles
$ git submodule update --recursive --init