跳转至

Git 子模块使用

概要: 简介 git submodule 的使用方法

创建时间: 2022.10.09 23:12:04

更新时间: 2023.08.16 22:26:10

在现有主库中添加子模块

添加子模块repo-a到主库

Bash
git submodule add http://192.168.2.145:3000/lzwang/repo-a.git
查看当前主库子模块配置.gitmodules
Properties
1
2
3
[submodule "repo-a"]
path = repo-a
url = http://192.168.2.145:3000/lzwang/repo-a.git
提交此变更到主库,无需使用git add命令
Bash
git commit -m "add submoudle repo-a"

重新拉取主库的两种方式

拉取时不初始化子模块

Bash
1
2
3
4
5
6
7
8
# 包含repo-a,但是为空目录
git clone ssh://git@192.168.2.145:13222/lzwang/playground.git

# 初始化repo-a
git submodule init

# 拉取repo-a
git submodule update

提示

  1. 初始化和拉取子模块的命令可以合并为: git submodule update --init
  2. 如果需要初始化并拉取全部任意深度嵌套子模块,命令为: git submodule update --init --recursive

拉取时初始化子模块

如果给 git clone 命令传递 --recurse-submodules 选项,它就会自动初始化并更新仓库中的每一个子模块, 包括可能存在的嵌套子模块

Bash
git clone --recurse-submodules ssh://git@192.168.2.145:13222/lzwang/playground.git

主库操作

更新子模块

Bash
git submodule update --remote

主库推送时检查子模块是否有更改

Bash
git push --recurse-submodules=check

主库推送时一并尝试推送子模块的更改

Bash
git push --recurse-submodules=on-demand

警告

使用上述命令时,如果子模块推送失败,则本次推送失败,不会有任何改动推入主库或其它子模块

子模块相关配置

配置使用的子模块分支

Bash
git config -f .gitmodules submodule.repo-a.branch master

配置主库推送时检查子模块的更改

Bash
git config push.recurseSubmodules check

同时在主库和子模块上改动并提交

提示

当我们运行 git submodule update 从子模块仓库中抓取修改时, Git 将会获得这些改动并更新子目录中的文件,但是会将子仓库留在一个称作“游离的 HEAD”的状态。 这意味着没有本地工作分支(例如 “master” )跟踪改动。 如果没有工作分支跟踪更改,也就意味着即便你将更改提交到了子模块,这些更改也很可能会在下次运行 git submodule update 时丢失。

同时对子模块进行修改和更新需要做如下事情

  1. 进入子模块目录并检出对应分支
  2. 在主库上,使用git submodule update --remote --merge参数将子模块分支更新
  3. 本地对子模块进行修改并提交commit
  4. 在主库上,使用git submodule update --remote --rebase参数将子模块分支更新
  5. 一并推送主库和子模块提交到远端git push --recurse-submodules=on-demand
    Bash
    # step1 检出子模块分支
    cd repo-a
    git checkout master
    
    # step2 更新子模块
    cd ..
    git submodule update --remote --merge
    
    # step3 子模块修改与提交
    cd repo-a
    vim a.txt
    git add a.txt
    git commit -m "modify a.txt"
    
    # step4 更新子模块
    git submodule update --remote --rebase
    
    # step5 提交主库和子模块改动
    git push --recurse-submodules=on-demand
    

提示

上述第2步和第4步类似于普通仓库的修改代码前git pull一把,然后在推送到远端前,再git pull一把避免本地与远端冲突

所有子模块执行相同命令

使用 foreach 关键字

Bash
git submodule foreach 'git stash'

添加和主库子目录同名的子模块

Bash
git rm -r CryptoLibrary
git submodule add https://github.com/chaconinc/CryptoLibrary

警告

不能使用rm -rf CryptoLibrary/ && git submodule add xxx命令,因为没有从git中取消暂存主库的子目录

参考