Git必备命令-子模块
1. 首次拉取带子仓库的代码方法:
仓库一起拉取:
代码语言:javascript复制git clone --recurse-submodules 父仓库地址
分开拉取:
代码语言:javascript复制git clone 父仓库地址
git submodule init // 初始化子模块
git submodule update // 更新子模块与主仓库中的子模块代码同步
// or
git submodule update --init
// or 嵌套的(子仓库中包含子仓库)
git submodule update --init --recursive
2. 在主仓库更改子仓库代码并提交方法:
3. 更新、拉取子仓库代码方法:
父目录中:
代码语言:javascript复制$ git submodule update // 与主仓库中的子模块代码同步
$ git submodule update --remote // 与子仓库中代码同步(同步所有的子模块)
$ git submodule update --remote xxx // 指定需要同步的子模块
子模块目录下更新:
代码语言:javascript复制git pull
默认情况下会跟踪子模块的 master 分支,设置为其他分支:
a. .gitmodules 设置
代码语言:javascript复制git config -f .gitmodules submodule.[submodule-name].branch [branch-name]
如果不用 -f .gitmodules 选项,那么它只会为你做修改。但是在仓库中保留跟踪信息更有意义一些,因为其他人也可以得到同样的效果。
https://blog.csdn.net/weixin_44070450/article/details/107701812
https://git-scm.com/book/zh/v2/Git-工具-子模块
4. 删除submodule
4.1 删除 .gitmodules 文件中相关的内容
代码语言:javascript复制-[submodule "editorjs"]
- path = editorjs
- url = https://github.com/codex-team/editor.js
4.2 删除.git/config 文件中相关内容
代码语言:javascript复制[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = https://github.com/talyguryn/test
fetch = refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
-[submodule "editorjs"]
- active = true
- url = https://github.com/codex-team/editor.js
4.3 删除缓存
代码语言:javascript复制git rm --cached path_to_submodule (no trailing slash)
4.4 删除 .git/modules下面目录
代码语言:javascript复制rm -rf .git/modules/path_to_submodule (no trailing slash)
4.5 删除 子目录
代码语言:javascript复制rm -rf path_to_submodule
4.6 提交更改
代码语言:javascript复制git commit -am "Remove submodule"
解决的问题:有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。也许是第三方库,或者你独立开发的,用于多个父项目的库。现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。
开始使用子模块 我们首先将一个已存在的 Git 仓库添加为正在工作的仓库的子模块。你可以通过在 git submodule add 命令后面加上想要跟踪的项目的相对或绝对 URL 来添加新的子模块。在本例中,我们将会添加一个名为 “DbConnector” 的库。
代码语言:javascript复制$ git submodule add https://github.com/chaconinc/DbConnector
Cloning into 'DbConnector'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.
克隆含有子模块的项目 接下来我们将会克隆一个含有子模块的项目。当你在克隆这样的项目时,默认会包含该子模块目录,但其中还没有任何文件:
代码语言:javascript复制$ git clone https://github.com/chaconinc/MainProject
Cloning into 'MainProject'...
remote: Counting objects: 14, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 14 (delta 1), reused 13 (delta 0)
Unpacking objects: 100% (14/14), done.
Checking connectivity... done.
$ cd MainProject
$ ls -la
total 16
drwxr-xr-x 9 schacon staff 306 Sep 17 15:21 .
drwxr-xr-x 7 schacon staff 238 Sep 17 15:21 ..
drwxr-xr-x 13 schacon staff 442 Sep 17 15:21 .git
-rw-r--r-- 1 schacon staff 92 Sep 17 15:21 .gitmodules
drwxr-xr-x 2 schacon staff 68 Sep 17 15:21 DbConnector
-rw-r--r-- 1 schacon staff 756 Sep 17 15:21 Makefile
drwxr-xr-x 3 schacon staff 102 Sep 17 15:21 includes
drwxr-xr-x 4 schacon staff 136 Sep 17 15:21 scripts
drwxr-xr-x 4 schacon staff 136 Sep 17 15:21 src
$ cd DbConnector/
$ ls
$
其中有 DbConnector 目录,不过是空的。你必须运行两个命令:git submodule init 用来初始化本地配置文件,而 git submodule update 则从该项目中抓取所有数据并检出父项目中列出的合适的提交。
代码语言:javascript复制$ git submodule init
Submodule 'DbConnector' (https://github.com/chaconinc/DbConnector) registered for path 'DbConnector'
$ git submodule update
Cloning into 'DbConnector'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.
Submodule path 'DbConnector': checked out 'c3f01dc8862123d317dd46284b05b6892c7b29bc'
不过还有更简单一点的方式。如果给 git clone 命令传递 --recurse-submodules 选项,它就会自动初始化并更新仓库中的每一个子模块, 包括可能存在的嵌套子模块。
代码语言:javascript复制$ git clone --recurse-submodules https://github.com/chaconinc/MainProject
Cloning into 'MainProject'...
remote: Counting objects: 14, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 14 (delta 1), reused 13 (delta 0)
Unpacking objects: 100% (14/14), done.
Checking connectivity... done.
Submodule 'DbConnector' (https://github.com/chaconinc/DbConnector) registered for path 'DbConnector'
Cloning into 'DbConnector'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.
Submodule path 'DbConnector': checked out 'c3f01dc8862123d317dd46284b05b6892c7b29bc'
如果你已经克隆了项目但忘记了 --recurse-submodules,那么可以运行 git submodule update --init 将 git submodule init 和 git submodule update 合并成一步。如果还要初始化、抓取并检出任何嵌套的子模块, 请使用简明的 git submodule update --init --recursive。
在包含子模块的项目上工作
从子模块的远端拉取上游修改 如果想要在子模块中查看新工作,可以进入到目录中运行 git fetch 与 git merge,合并上游分支来更新本地代码。
代码语言:javascript复制$ git fetch
From https://github.com/chaconinc/DbConnector
c3f01dc..d0354fc master -> origin/master
$ git merge origin/master
Updating c3f01dc..d0354fc
Fast-forward
scripts/connect.sh | 1
src/db.c | 1
2 files changed, 2 insertions( )
如果你不想在子目录中手动抓取与合并,那么还有种更容易的方式。运行 git submodule update --remote,Git 将会进入子模块然后抓取并更新。
代码语言:javascript复制$ git submodule update --remote DbConnector
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 2), reused 4 (delta 2)
Unpacking objects: 100% (4/4), done.
From https://github.com/chaconinc/DbConnector
3f19983..d0354fc master -> origin/master
Submodule path 'DbConnector': checked out 'd0354fc054692d3906c85c3af05ddce39a1c0644'
此命令默认会假定你想要更新并检出子模块仓库的 master 分支。不过你也可以设置为想要的其他分支。例如,你想要 DbConnector 子模块跟踪仓库的 “stable” 分支,那么既可以在 .gitmodules 文件中设置 (这样其他人也可以跟踪它),也可以只在本地的 .git/config 文件中设置。让我们在 .gitmodules 文件中设置它:
代码语言:javascript复制$ git config -f .gitmodules submodule.DbConnector.branch stable
$ git submodule update --remote
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 2), reused 4 (delta 2)
Unpacking objects: 100% (4/4), done.
From https://github.com/chaconinc/DbConnector
27cf5d3..c87d55d stable -> origin/stable
Submodule path 'DbConnector': checked out 'c87d55d4c6d4b05ee34fbc8cb6f7bf4585ae6687'
如果不用 -f .gitmodules 选项,那么它只会为你做修改。但是在仓库中保留跟踪信息更有意义一些,因为其他人也可以得到同样的效果。这时我们运行 git status,Git 会显示子模块中有“新提交”。
代码语言:javascript复制$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
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
modified: DbConnector (new commits)
no changes added to commit (use "git add" and/or "git commit -a")
从项目远端拉取上游更改 现在,让我们站在协作者的视角,他有自己的 MainProject 仓库的本地克隆, 只是执行 git pull 获取你新提交的更改还不够:
代码语言:javascript复制$ git pull
From https://github.com/chaconinc/MainProject
fb9093c..0a24cfc master -> origin/master
Fetching submodule DbConnector
From https://github.com/chaconinc/DbConnector
c3f01dc..c87d55d stable -> origin/stable
Updating fb9093c..0a24cfc
Fast-forward
.gitmodules | 2 -
DbConnector | 2 -
2 files changed, 2 insertions( ), 2 deletions(-)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
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: DbConnector (new commits)
Submodules changed but not updated:
* DbConnector c87d55d...c3f01dc (4):
< catch non-null terminated lines
< more robust error handling
< more efficient db routine
< better connection routine
no changes added to commit (use "git add" and/or "git commit -a")
默认情况下,git pull 命令会递归地抓取子模块的更改,如上面第一个命令的输出所示。然而,它不会 更新 子模块。这点可通过 git status 命令看到,它会显示子模块“已修改”,且“有新的提交”。此外,左边的尖括号(<)指出了新的提交,表示这些提交已在 MainProject 中记录,但尚未在本地的 DbConnector 中检出。为了完成更新,你需要运行 git submodule update:
代码语言:javascript复制$ git submodule update --init --recursive
Submodule path 'vendor/plugins/demo': checked out '48679c6302815f6c76f1fe30625d795d9e55fc56'
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean