git子模块
到目前为止,将您的大项目分解为子项目.
现在使用以下命令将每个子项目添加到主项目:
1 | git submodule add <url> |
项目添加到您的仓库后,您必须初始化并更新它.
1 | git submodule init |
从Git 1.8.2开始,新选项 –remote
被添加
1 | git submodule update --remote --merge |
将从每个子模块的上游获取最新的更改,将它们合并,并检查子模块的最新版本.
使用场景
基于公司的项目会越来越多,常常需要提取一个公共的类库提供给多个项目使用,但是这个library
怎么和git
在一起方便管理呢?
我们需要解决下面几个问题:
- 如何在git项目中导入
library库
? library库
在其他的项目中被修改了可以更新到远程的代码库中?- 其他项目如何获取到
library库
最新的提交? - 如何在clone的时候能够自动导入
library库
?
解决以上问题,可以考虑使用git的 Submodule
来解决。
什么是Submodule?
git Submodule
是一个很好的多项目使用共同类库的工具,他允许类库项目做为repository
,子项目做为一个单独的git项目
存在父项目中,子项目可以有自己的独立的commit
,push
,pull
。而父项目以Submodule
的形式包含子项目,父项目可以指定子项目header
,父项目中会的提交信息包含Submodule
的信息,再clone父项目
的时候可以把Submodule
初始化。
在项目中使用Submodule
使用git
命令可以直接添加Submodule
:
1 | git submodule add git@github.com:xxx.git pod-library |
使用 git status
命令可以看到
1 | git status |
1 | On branch master |
可以看到多了两个需要提交的文件:.gitmodules
和 pod-library
.gitmodules
内容包含Submodule
的主要信息,指定reposirory
,指定路径:
1 | [submodule "pod-library"] |
可以看到记录了子项目的目录和子项目的git
地址信息。
pod-libray
内容只保护子项目的commit id
,就能指定到对于的git header
上,例如:
1 | Subproject commit 4ac42d2f8b9ba0c2f0f2f2ec87ddbd529275fea5 |
4ac42d2f8b9ba0c2f0f2f2ec87ddbd529275fea5
就是子项目的commit id
,父项目的git并不会记录Submodule
的文件变动,它是按照commit git
指定Submodule
的git header
。
另外,这两个文件都需要提交到父项目的git中。
还可以这样使用命令添加Submodule
1 | git add .gitmodules pod-ibrary |
修改Submodule
首先需要确认有对Submodule的commit权限。
进入Submodule
目录里面:
1 | cd pod-library/ |
修改其中的一个文件看下文件的可以用git status
查看变动:
1 | git status |
提交Submodule
的更改内容:
1 | git commit -a -m'test submodule' |
然后push
到远程服务器:
1 | git push |
然后再回到父目录,提交Submodule
在父项目中的变动:
1 | cd .. |
可以看到pod-library
中已经变更为Submodule
最新的commit id
:
1 | Subproject commit 330417cf3fc1d2c42092b20506b0d296d90d0b5f |
需要把Submodule
的变动信息推送到父项目的远程服务器
1 | git commit -m'update submodule' |
这样就把子模块的变更信息以及子模块的变更信息提交到远程服务器了,从远程服务器上更新下来的内容就是最新提交的内容了。
更新Submodule
更新Submodule
有两种方式:
在父项目的目录下直接运行
1 | git submodule foreach git pull |
在Submodule的目录下面更新
1 | cd pod-library |
可以看到在Submodule
的目录中,使用git
和单独的一个项目是一样的,注意更新Submodule
的时候如果有新的commit id
产生,需要在父项目产生一个新的提交,pod-libray文件中的 Subproject commit
会变为最新的commit id
。
clone Submodule
clone Submodule
有两种方式 一种是采用递归的方式clone整个项目,一种是clone父项目,再更新子项目。
- 采用递归参数
--recursive
1 | git clone git@github.com:xxx.git --recursive |
输出结果:
1 | loning into 'pod-project'... |
可以看到init Submodule
会自动被clone
下来
- 第二种方法先clone父项目,再初始化
Submodule
1 | git clone git@github.com:xxx/pod-project.git |
输出:
1 | Submodule 'pod-library' (git@github.com:xxx/pod-library.git) |
更新Submodule
:
1 | git submodule update |
运行结果:
1 | Cloning into 'pod-library'... |
删除Submodule
git
并不支持直接删除Submodule
需要手动删除对应的文件:
1 | cd pod-project |
更改git的配置文件config
:
1 | vim .git/config |
可以看到Submodule
的配置信息:
1 | [submodule "pod-library"] |
删除submodule相关的内容,然后提交到远程服务器:
1 | git commit -a -m 'remove pod-library submodule' |