如果你的代码有依赖于某些第三方组件,而这些第三方组件又是常用的,例如模板、邮件、office等,建议把这些组件放到git的submodule里面,组件单独形成一个repo。
正好最近有用到Git Submodule,下面整理一下它的相关用法。
举个例子,假如说submodule所在的repo地址为https://yourcustomsite.com/test/mysubmodule
添加子模块
那么可以用以下命令把子模块加入到其中
git submodule add https://yourcustomsite.com/test/mysubmodule
这个命令执行完成之后,就会在你的项目里新增了mysubmodule
文件夹和.gitmodules
文件。
默认情况下,子模块的目录是与仓库同名的。如果想要指定别的目录名字othername
,那么可以这样:
git submodule add https://yourcustomsite.com/test/mysubmodule othername
一般情况下是成功的,有时候可能不成功是因为系统会提示你是否确认要更改子模块目录名,或者当前目录已经有同名子模块了 ,这个你可以你自己斟酌,可以加上--force
强制或者--name
设置目录名
git submodule add --force https://yourcustomsite.com/test/mysubmodule othername
如果你这个submodule的repo有好几个分支,你想用其中的某个分支mybranchname
,不想用默认的master分支,那么可以使用-b
来指定分支名称。
git submodule add -b mybranchname --force https://yourcustomsite.com/test/mysubmodule othername
去除子模块
假如说按照下面这个命令加入子模块
git submodule add -b mybranchname --force https://yourcustomsite.com/test/mysubmodule othername
如果想要删除子模块,则使用命令git submodule deinit othername
就能够去除本地的子模块文件,如果要删除远程的文件,还需要执行命令git rm -r othername
,这样也把当前项目的远程仓库里的子模块给删除了
url或者branch有改动
假如说按照下面这个命令加入子模块
git submodule add -b mybranchname --force https://yourcustomsite.com/test/mysubmodule othername
那么子模块加载完成后新增的.gitmodules
文件的格式是这样的:
.gitmodules
文件的内容
[submodule "othername"]
path = othername
url = https://yourcustomsite.com/test/mysubmodule
branch = mybranchname
如果项目里面已经添加了子目录,但是发现url或者branch不对,想要该成果来,那么步骤有以下几个:
- 步骤一、
git submodule deinit othername
去除子模块 - 步骤二、删除
.gitmodules
文件 - 步骤三、
git rm --cached othername
删除本项目仓库里的子模块 - 步骤四、
git submodule add ……
添加子模块
有时候操作会有一些提示,比如说
Please stage your changes to .gitmodules or stash them to proceed
一般是因为你没删除.gitmodules
文件,就去删远程仓库的子模块了。这个问题的解决办法是:先步骤二、再步骤三
还会有一些提示比如
'othername' already exists in the index
是因为你没有执行步骤三就去执行步骤四了,所以应该先执行步骤三,然后再执行步骤四。
有时候即使按照顺序执行了步骤三、步骤四,但还是会出现xxx already exists in the index
的报错,这个时候就要检查一下.git/modules
里面是不是已经存在xxx
了。
建议rm -rf .git/modules/*
在你把整个项目push到git的时候,git并不会把子模块的代码也放进去,而是会生成一个文件。
比如说你的子模块名字叫othersubname
,那么你会在你父项目的文件列表里面看到一个othersubname
,它的内容是Subproject commit-id xxxxxx
。但如果你把整个父项目clone下来,你是不会看见这个文件的,因为它变成了一个同名文件夹