面对比较复杂的我的项目,咱们有可能会将代码依据性能拆解成不同的子模块。主我的项目对子模块有依赖关系,却又并不关怀子模块的外部开发流程细节。
submodule容许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到本人的我的项目中,同时还放弃提交的独立。

一、创立 submodule

首先创立有两个我的项目,同时上传至git并放弃同步:main-project(主) 和 sub-project(子)
其中 project-main 的近程仓库地址为 http://xxxx/main-project.git,而 project-sub-1 的近程仓库地址为http://xxxx/sub-project.git
在main-project 中增加 sub-project ,而又放弃 sub-project 本身独立的版本控制。

应用 git submodule add <submodule_url> 命令能够在我的项目中创立一个submodule 。
从主我的项目文件夹中进入git

$ git submodule add http://xxxx/sub-project.gitCloning into 'D:/project/main-project/sub-project'...remote: Counting objects: 60, done.remote: Compressing objects: 100% (45/45), done.remote: Total 60 (delta 14), reused 0 (delta 0)Unpacking objects: 100% (60/60), done.warning: LF will be replaced by CRLF in .gitmodules.The file will have its original line endings in your working directory

默认状况下,子模块会将submodule放到一个与仓库同名的目录中, 如果你想要放到其余中央,那么能够在命令结尾增加一个不同的门路
此时其会在main-project文件夹下创立sub-project submodule,如下图

运行 git status查看目前状态

$ git statusOn branch masterYour branch is up to date with 'origin/master'.Changes to be committed:  (use "git restore --staged <file>..." to unstage)        modified:   .gitmodules        new file:   sub-project

此处的 .gitmodules 文件,该配置文件保留了我的项目 URL 与曾经拉取的本地目录之间的映射关系,如果有多个子模块,该文件中就会有多条记录。

运行git diff --cached sub-project/ 查看不同

$ git diff --cached sub-project/diff --git a/sub-project b/sub-projectnew file mode 160000index 0000000..b25121d--- /dev/null+++ b/sub-project@@ -0,0 +1 @@+Subproject commit b25121d683f0e47b798fa095579d9fa6761ee698

此处记录的 160000 模式, 是 Git 中的一种非凡模式,它实质上意味着你是将一次提交记作一项目录记录的,而非将它记录成一个子目录或者一个文件。

最初咱们提交它,至此咱们曾经增加了一个submodule(sub-project),其中在main-project中的.gitmodules 文件中保留了之间的映射关系,除此之外,此时在 .git/config 文件中也会多出一些信息,在 .git/modules 文件夹下也会多出一份内容,如下图。

二、 submodule内容的更新

当sub-projcet子项目在其余人员批改更新后,main-project我的项目如何同步更新

首先咱们在sub-project独立我的项目上批改代码后提交

之后咱们在main-project和main-project的submodule(sub-project)上查看更新状态,发现并没有同步内容信息

这还是阐明在main-project中保留的submodule中只是sub-project过后的一个版本,最新的版本内容并不会依据sub-project的同步而同步。

主我的项目能够应用 git submodule update 更新子模块的代码,但那是指 以后主我的项目文件夹下的子模块目录内容与以后主我的项目记录的子模块版本不统一时,会参考后者进行更新,而咱们在sub-project独立我的项目上批改代码后提交主我的项目并不通晓。

此时咱们进入submodule(sub-project)文件门路下
拉取submodule的master分支代码 git pull origin master

EDZ@▒▒ƽ▒▒▒▒-▒▒▒▒ MINGW64 /d/project/main-project/sub-project (master)$ git pull origin masterremote: Counting objects: 6, done.remote: Compressing objects: 100% (4/4), done.remote: Total 6 (delta 2), reused 4 (delta 0)Unpacking objects: 100% (6/6), done.From http://xxxx/sub-project * branch            master     -> FETCH_HEAD   b25121d..b861fae  master     -> origin/masterUpdating b25121d..b861faeFast-forward src/main/java/Sub.java | 2 ++ 1 file changed, 2 insertions(+)

同时,咱们能够看到main-project有了更新内容信息

如果不想在子目录中手动抓取与合并,那么还有种更容易的形式。 运行 git submodule update --remote,Git 将会进入子模块而后抓取并更新。

EDZ@▒▒ƽ▒▒▒▒-▒▒▒▒ MINGW64 /d/project/main-project (master)$ git submodule update --remoteremote: Counting objects: 6, done.remote: Compressing objects: 100% (4/4), done.remote: Total 6 (delta 2), reused 0 (delta 0)Unpacking objects: 100% (6/6), done.From http://xxxx/sub-project   b861fae..6e3c1d6  master     -> origin/masterSubmodule path 'sub-project': checked out '6e3c1d61b4d8878d791b95ab9531ffc5ea30f98c'

当运行 git submodule update --remote 时,Git默认会尝试更新所有子模块, 所以如果有很多子模块的话,也能够传递想要更新的子模块的名字。

至此,submodule内容的更新就能够实现