Git 开发项目过程中,经常会有一些通用的部分希望抽取出来做成一个公共库来提供给别的工程来使用,而公共代码库的版本管理是个麻烦的事情。今天无意中发现了Git的git submodule命令,之前的问题迎刃而解了。

 

submodule 添加

为当前工程添加submodule,命令如下:

git submodule add 仓库地址 路径

其中,仓库地址是指子模块仓库地址,路径指将子模块放置在当前工程下的路径。 
注意:路径不能以 / 结尾(会造成修改不生效)、不能是现有工程已有的目录(不能順利 Clone)

命令执行完成,会在当前工程根路径下生成一个名为“.gitmodules”的文件,其中记录了子模块的信息。添加完成以后,再将子模块所在的文件夹添加到工程中即可。

 

submodule 删除

submodule的删除稍微麻烦点:首先,要在“.gitmodules”文件中删除相应配置信息。然后,执行“git rm –cached ”命令将子模块所在的文件从git中删除。

 

下载的工程带有submodule

当使用git clone下来的工程中带有submodule时,初始的时候,submodule的内容并不会自动下载下来的,此时,只需执行如下命令:

git submodule update --init --recursive

即可将子模块内容下载下来后工程才不会缺少相应的文件。

 

github克隆项目中的子模块submodule时遇到的问题

GitHub.com 真是个开源大宝库,不只能学习代码,还能学习git的使用!

最近在研究Off-the-Record-iOS项目(https://github.com/chrisballinger/Off-the-Record-iOS)时,学习实践了gitsubmodule的用法!

这个项目中有一个Submodules文件夹,包含了该项目所引用到的其他GitHub上的开源项目,最开始没注意到,直接Download ZIP拿下来的,发现XCode项目中一堆红色文件名,才发现原来还有很多依赖项目,仔细看了一下还挺不少,于是果断放弃手动挨个下载…

搜索了一下,发现项目的issue #87有人问到了类似的问题:

https://github.com/chrisballinger/Off-the-Record-iOS/issues/87

按照下面的回答,重新git clone了项目,并使用 git submodule init && git submodule update (1.6以后版本也可以直接用git clone –recursive代替)来更新项目中的依赖子模块,更了前几个之后又出现了新的错误:

Submodule path ‘Submodules/DAKeyboardControl’: checked out ‘5352d1ff2d1131d974d94406ed8fcf8eb068aa72′
Cloning into ‘Submodules/LibOrange’…
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Clone of ‘git@github.com:ChatSecure/LibOrange.git’ into submodule path ‘Submodules/LibOrange’ failed

这个issue #105也提到了:

https://github.com/chrisballinger/Off-the-Record-iOS/issues/105

根据作者的回答,需要更新对应项的git url,替换为https方式!

 

于是进入项目根目录

vim .gitmodules

编辑文件,找到提示问题的模块LibOrange,修改

url = git@github.com:ChatSecure/LibOrange.git为url = https://github.com/ChatSecure/LibOrange.git

:wq 保存退出

 

修改好模块url后还是不能直接更新,经过几次尝试,发现需要重新同步子模块的url

执行 git submodule sync

刷新url,然后

再次执行 git submodule update –init

这样又会提示:

fatal: Needed a single revision
Unable to find current revision in submodule path ‘Submodules/LibOrange’

这个问题参考这里:

http://blog.csdn.net/frank2336/article/details/7414545

解决方法时 rm -rf LibOrange 删掉已存在的文件夹

删除后,返回项目根目录,再次执行 git submodule update –init 就不再有问题了:

remote: Counting objects: 1052, done.
remote: Compressing objects: 100% (547/547), done.
remote: Total 1052 (delta 439), reused 1050 (delta 438)
Receiving objects: 100% (1052/1052), 3.96 MiB | 46 KiB/s, done.
Resolving deltas: 100% (439/439), done.
From https://github.com/ChatSecure/LibOrange
* branch HEAD -> FETCH_HEAD
Submodule path ‘Submodules/LibOrange’: checked out ‘d7ae559dfebe2eb6cc3996735fa6081e1aaa02fa’

这文章总结的太好了!!