git 版本控制下的源码安装
克隆源码
方法1(推荐-下载更速度快)
$ git clone git@github.com:jpe/some_repo.git # 不包含子模块
$ git submodule update --init --recursive # 更新子模块并初始化
方法2
一次克隆主模块和所有子模块并初始化
$ git clone --recursive git@github.com:jpe/some_repo.git
更新
从远程库获取所有主模块和所有子模块的更新
$ git fetch --all --recurse-submodules
版本切换
只有主分支,使用版本标签创建版本分支。
$ git checkout -b v1.0.0 v1.0.0 # 从主模块切换到某个版本,创建一个版本分支
$ git submodule update --recursive --force # 更新子模块到相应的版本
有版本分支
$ git checkout foo_local_branch # 从主模块切换到某个分支
$ git submodule update --recursive --force # 更新子模块到相应的版本
–force 选项:如果不使用,切换时,如果有文件或目录的增删,会报出警告:
warning: unable to rmdir foobar: Directory not empty
查看
列出所有子模块和它们的commit
$ git submodule status --recursive
修改子模块
先在 Github 上 fork 这个仓库并添加远程控制。即便是从 fork 的仓库上克隆的也需添加远程映射。
例如,fruit、fruit/apple 是在主模块中嵌套的子模块:
$ cd fruit
$ git remote add joe_fruit_remote git@github.com:joe/fruit_repo.git
$ cd apple
$ git remote add joe_apple_remote git@github.com:joe/apple_repo.git
主模块的版本或分支与子模块的版本或分支是相互关联的。也就是说,在子模块的版本或分支上显示 detached HEAD 。此外,这也是子模块提交给父模块的版本。因此,当从主模块切换到一个本地分支并且在层次结构的子模块中修改文件时,典型的流程是:
- 在修改的子模块中,从 detached HEAD 创建一个本地分支
- 自下而上的方式提交:从修改的叶子模块开始,一直向上运行到根模块。需要提交从修改的子模块到跟模块的路径上的所有模块。这是因为父模块的提交需要子模块修改的提交。
例如,fruit 和 fruit/apple 是主模块中嵌套的子模块:
$ git checkout -b foo_local_branch origin/foo_remote_branch
$ git submodule update --recursive
$ cd fruit
$ git checkout -b fruit_local_branch
$ vim change_some_files_in_fruit_submodule.sh
$ cd apple
$ git checkout -b apple_local_branch
$ vim change_some_files_in_apple_submodule.sh
$ git add change_some_files_in_apple_submodule.sh
$ git commit -m "Changes in fruit/apple go first"
$ cd ..
$ git add change_some_files_in_fruit_submodule.sh
$ git commit -m "Changes in fruit go next"
$ cd ..
$ git add -u
$ git commit -m "Commit new fruit submodule revision to main module"
推送到 fork 的库
修改完成之后,将修改的内容推送到 fork 的库 (自己的库)。一般将创建的子模块的本地分支推送到 fork 的远程分支。因为之后的 pull request 会很简单。
继续上面的例子:
$ cd fruit
$ cd apple
$ git push joe_apple_remote apple_remote_branch
$ cd ..
$ git push joe_fruit_remote fruit_remote_branch
$ cd ..
$ git push origin foo_remote_branch
发送 pull request
修改完成之后,将修改的内容推送到 fork 的源库 (其他人的库)。
- 将所有已修改子模块的本地分支推送到他们的远程库。(如上面的推送部分)
- 发送 pull request,一个修改的子模块一个拉取请求。