Skip to content

git submodule

目录


git submodule

git 模块允许以一种更优雅的方式在你的 git 项目中嵌套一个子 git 项目

bash
# 添加子模块
git submodule add <url> [<path>]

# 初始化
git submodule init
# 更新
git submodule update
# 或者合二为一
git submodule update --init
# 使用 --recursive 嵌套初始化子子模块
git submodule update --init --recursive
# 或者直接在 clone 父仓库时初始化
git clone --recurse-submodules <url>

变更

父项目不会记录子项目中的文件修改,只有在子项目更新版本(git pull,checkout 等)时,会将子项目的版本修改记作为父项目的一条变更,如下:

bash
git commit -am 'added DbConnector module'
[master fb9093c] added DbConnector module
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 DbConnector

注意 DbConnector 记录的 160000 模式。 这是 Git 中的一种特殊模式,它本质上意味着你是将一次提交记作一项目录记录的,而非将它记录成一个子目录或者一个文件。

子模块的版本更新后,更新记录随着 commit 提交到父项目。这样,当父项目变更(如 checkout)版本时,子项目也会随之变更到对应的版本。

子项目跟随父项目更新之后可能不会导致子项目内的文件(抓取但不覆盖),可以添加--recurse-submodules来让子模块也随之修改到对应的版本,也可以使用git submodule update来更新子模块

使用 git diff / git status 或者 IDE 的默认 git 无法查看子项目的具体文件变更,需要添加--submodule参数。如果你不想每次运行 git diff 时都输入 --submodule,那么可以将 diff.submodule 设置为 “log” 来将其作为默认行为。

bash
$ 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)

.gitmodules

本质上就是在 git 项目里面添加一个文件夹放子项目(真的吗?),但是通过位于项目根目录下的.gitmodulesgit submodule add之后自动生成)可以优雅地管理子项目

不用写.gitignore来屏蔽子项目文件夹,同时 git 命令也能识别子项目

.gitmodules
[submodule "DbConnector"]
	path = DbConnector
	url = https://github.com/chaconinc/DbConnector

参考资料

Copyright © 2022 田园幻想乡 浙ICP备2021038778号-1