闽公网安备 35020302035485号
git submodule add git@github.com:walkerdu/draw_io.git submodules/draw_io执行完上述submodule add命令后,可以查看本地仓库的变化如下:
$git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitmodules
new file: submodules/draw_io
我们可以看到当前仓库的已经多了两个文件.gitmodules和submoudles/draw_io,且这「两个文件已经被自动加入了stage区域」;$cat .gitmodules
[submodule "submodules/draw_io"]
path = submodules/draw_io // 存放路径
url = git@github.com:walkerdu/draw_io.git // submodule的url地址
其中另外一个变化:submodules/draw_io在本地是add submodule后,clone下来的跟踪的项目draw_io的仓库;「但为什么上面git status提示的是他是一个new file呢」?下面研究一下原因:$git commit -m 'init submodule' . [master 4894d7d] init submodule 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 submodules/draw_io然后查看提交的内容如下:
/* 堆代码 duidaima.com */
$git show 4894d7d
commit 4894d7dbde107741a0956bc018ad1e6ec1ca80b3 (HEAD -> master)
Author: walkerdu <anonym_alias@163.com>
Date: Thu May 12 15:31:43 2022 +0800
init submodule
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..df23d83
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "submodules/draw_io"]
+ path = submodules/draw_io
+ url = git@github.com:walkerdu/draw_io.git
diff --git a/submodules/draw_io b/submodules/draw_io
new file mode 160000
index 0000000..9b5dcda
--- /dev/null
+++ b/submodules/draw_io
@@ -0,0 +1 @@
+Subproject commit 9b5dcdac92b0d0e07264ae22267814fd052d4560
我们可以看到submodules/draw_io提交的内容是此跟踪项目的最新的commitid;所以我们得知,「对于submodule管理的模块,会将.gitmodules映射的本地存储路径进行忽略,将其最新的commitid作为文件内容在主仓库中进行跟踪管理」;$git submodule update --remote
...
From github.com:walkerdu/draw_io
9b5dcda..26b9e31 master -> origin/master
Submodule path 'submodules/draw_io': checked out '26b9e31e0367c16894910f3ebce4e2d334a812da'
$git status
...
Changes not staged for commit:
...
modified: submodules/draw_io (new commits)
更新submodule后,主仓库里面可以发现跟踪的submodules/draw_io已经发生了变化;此时可以将最新的跟踪仓库的commitid的变化进行提交;这样项目就刷新了最新跟踪的submodule信息;我们此时看一下跟踪项目本地目录的状态:$git status HEAD detached at 117e833 nothing to commit, working tree clean「为什么跟踪的submodule本地项目变成了detached状态呢」?这里看一下git submodule update命令的man,简单说一下;
$git config -f .gitmodules submodule.submodules/draw_io.branch develop
$git status
On branch develop
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .gitmodules
跟踪draw_io的develop分支,执行完修改后.gitmodules发生变化,如下: [submodule "submodules/draw_io"]
path = submodules/draw_io
url = git@github.com:walkerdu/draw_io.git
+ branch = develop
然后执行git submoudle update --remote就可以刷新主仓库跟踪的commitid到分支的最新提交上面;「Git 2.34(Q4 2021)」版本及以后,在git clone --recurse-submodules拉取的仓库时,默认会设置git config --global submodule.recurse true,不需要再关心submodule的跟踪问题了;
通过git config --global push.recurseSubmodules=on-demand来配置;和上述含义一样;不过这里为什么不使用git config --global submodule.recurse true的设置呢?「看来submodule.recurse的配置不仅不对clone生效,在push的时候也不生效…」
git submodule foreachgit提供了可以在主项目中执行所有git命令来直接操作子项目的方式,命令:git submodule foreach 'git cmd',foreach可以遍历所有submodule,然后执行后面的git命令,如下查看子项目的所有分支:
$git submodule foreach 'git branch -av' Entering 'submodules/draw_io' * (HEAD detached at a62a01f) a62a01f change name master 117e833 [behind 4] update README.md remotes/origin/HEAD -> origin/master remotes/origin/develop a62a01f change name remotes/origin/master abe26b7 sync我们可以alias git-sf='git submodule foreach'来便捷的操作submodule;