yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《Git》学习笔记

    • 常用Git命令清单
    • git 基本命令汇总
    • submodule子模块分享
      • 简介
        • 链接资料
      • 1. _添加_
        • 1.1 添加子模块
        • a. 创建子模块时指定一个分支
        • 1.2 _克隆含有子模块的项目_
      • 2. 删除子模块
      • 3. _更新子模块_
        • 3.1 单独修改子模块代码
        • 3.2 在项目中更新子模块
      • 4. _查看子模块_
      • 5. _将目录转化为子模块_
      • 6. _子模块批量处理_
    • Git变基合并
    • Git命令思维导图
    • Git基础与命令
    • Git分支-分支原理
    • Git分支的新建与合并-分支操作
    • Git分支管理-查看分支
    • Git分支开发工作流
    • Git分支-远程分支
    • Git分支-变基
    • Git工具-查看修订版本
    • Git工具-交互式暂存
    • Git工具-重写历史
    • Git工具-重置揭密
  • 工具
  • 《Git》学习笔记
YiZhang-You
2023-05-24
目录

submodule子模块分享

# submodule子模块分享

# 简介

为什么需要用子模块,什么场景下需要使用子模块?

  • 当项目越来越庞大之后,不可避免的要拆分成多个子模块,我们希望各个子模块有独立的版本管理,并且由专门的人去维护。这样可以提高开发效率,降低代码的耦合性,提高了代码的复用。

有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。

Git 通过子模块来解决这个问题。 子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。

# 链接资料

  1. 知乎

Git: submodule 子模块简明教程 (opens new window)

  1. git 官网

Git - 子模块 (opens new window)

# 1. 添加

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
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
1
2

# 1.1 添加_子模块_

通过在 git submodule add 命令后面加上想要跟踪的项目的相对或绝对 URL 来添加新的子模块

git submodule add [url] [path]

git submodule add https://github.com/iphysresearch/GWToolkit.git
1
2
3

如果你想要放到其他地方,那么可以在命令结尾添加一个不同的路径。

添加子模块后,若运行 git status,可以看到主仓库目录中会增加一个文件 .gitmodules,这个文件用来保存子模块的信息。

在 .git/config中会多出一块关于子模块信息的内容:

该配置文件保存了项目 URL 与已经拉取的本地目录之间的映射。如果有多个子模块,该文件中就会有多条记录。 要重点注意的是,该文件也像 .gitignore 文件一样受到(通过)版本控制。 它会和该项目的其他部分一同被拉取推送。 这就是克隆该项目的人知道去哪获得子模块的原因。

新生成的还有相关子模块的文件:.git/modules/test2/。

当项目添加完子模块后,需要将本次的添加子模块提交并推送到仓库:

$ git commit -m 'add submodule'
$ git push origin master
1
2

注意:如果你是旧版 Git 的话,你会发现 ./test2目录中是空的,你还需要在执行一步「更新子模块」,才可以把远程仓库项目中的内容下载下来

$ git submodule update --init --recursive
1

# a. 创建子模块时指定一个分支

通过 -b 指定对应分支

git submodule add -b master [URL to Git repo];
1

# 1.2 克隆含有子模块的项目

接下来我们将会克隆一个含有子模块的项目。 当你在克隆这样的项目时,默认会包含该子模块目录,但其中还没有任何文件。其中有子模块的目录,不过是空的。

必须运行两个命令:

  • git submodule init初始化子模块

  • git submodule update更新子模块

也可以合并成一步git submodule update --init

git clone https://github.com/chaconinc/
1

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

git clone --recurse-submodules https://github.com/chaconinc/MainProject
1

如果还要初始化、抓取并检出任何嵌套的子模块, 请使用简明的 git submodule update --init --recursive。

# 2. 删除子模块

删除子模块比较麻烦,需要手动删除相关的文件,否则在添加子模块时有可能出现错误同样以删除 test2 子模块仓库文件夹为例:

  1. 删除子模块文件夹
$ git rm --cached 子模块名称  删除缓存断开联系
$ rm -rf test2
1
2
  1. 删除 .gitmodules 文件中相关子模块的信息,类似于:
[submodule "test2"]
	path = test2
	url = https://gitee.com/yyzlt/test2.git
1
2
3
  1. 删除 .git/config 中相关子模块信息,类似于:
[submodule "test2"]
	active = true
	url = https://gitee.com/yyzlt/test2.git
1
2
3
  1. 删除 .git 文件夹中的相关子模块文件
$ rm -rf .git/modules/test2
1

# 3. 更新子模块

# 3.1 单独修改子模块代码

当我们修改子模块仓库合并代码后,主项目中的子模块不会自动拉取最新代码,需要手动指定和变更。

正确做法:

  • 进入子模块的目录

  • git submodule update --remote

  • 检出到想要的分支或提交

  • 如果有修改子模块的代码需要先提交(拉取最新代码)

当运行 git submodule update --remote时,Git 默认会尝试更新 所有子模块。

所以如果有很多子模块的话,你可以传递想要更新的子模块的名字。

如果子模块有嵌套的子模块,则应使用 -recursive选项。

更新项目内子模块到最新版本:

$ git submodule update
1

更新子模块为远程项目的最新版本:

$ git submodule update --remote
1

子模块中有嵌套的子模块:

git submodule update --remote --recursive 
1

# 3.2 在项目中更新子模块

直接在主项目中修改子模块的代码,并提交更新。

在主项目中提交子项目版本

0、进入子模块的目录

1、创建分支
git branch new2  

2、切换分支
git checkout new2

3、修改代码

4、添加文件
git add .

5、提交
git commit -m "说明信息"
git push origin new2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

可以看到,其操作流程是和普通项目的提交一样的。

需要留意的是,在终端 Git 命令操作下,位于主仓库目录中除了子模块外的任何子目录下进行的 commit 操作,都会记到主仓库下。只有在子模块目录内的任何 commit 操作,才会记到子模块仓库下。

# 4. 查看子模块

要查看当前代码仓库所使用的子模块及其状态,除了看 .gitmodules文件外,还可以执行 git submodule 命令。

$ git submodule
 c1199300ee3a7c895a27f351352eabcf6dc543bd test2 (heads/master)
1
2

# 5. 将目录转化为子模块

随着仓库使用的越来越久,仓库中的子目录越来越多,仓库也变得越来越大。会导致pull和push的时间变长,共享代码就会变得很痛苦。

可以用将子目录独立成一个submodule的方式,保留分支和提交历史。

步骤:

  1. Clone仓库到本地目录
git clone https://gitee.com/yyzlt/test1.git
1

我想要把test3这个子目录submodule化

  1. 选择要保留的分支

通常刚clone下来的仓库本地只会有一个branch:master,如果我们希望在马上要做的子模块中保存其他的分支,那就首先把它们创建出来

git branch release
git branch fix
# 保存其他分支
1
2
3

最后origin这个remote是不需要的,把它删除了

git remote rm origin
1
  1. 转化成submodule
$ git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter test3 -- --all
1

该命令过滤所有历史提交,保留对test1子目录有影响的提交,并且把子目录设为该仓库的根目录。下面解释下各参数意思:

  • --tag-name-filter cat 该参数控制我们要如何保存旧的tag,cat表示原样输出。

  • --prune-empty 删除空的(对子目录没有影响的)的提交

  • -subdirectory-filter 文件名称 指定子模块路径

  • --all 该参数必须跟在--后面,表示对所有分支做操作,如果你只想保存当前分支,就不需要这个参数了

该命令执行完毕后,查看当前目录结构就会发现里面已经是子目录的内容了。git log查看提交历史已经正常保存了。

  1. 清理不需要的object

上面的步骤完成后,当前仓库里还保存了很多不需要的object, 需要做下清理,才能减少当前仓库的体积。

$ git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d

$ git reflog expire --expire=now --all

$ git gc --aggressive --prune=now
1
2
3
4
5
  1. 提交子模块代码

  2. 首先要在gitee上创建名称为test3的仓库

  3. 对应remote

git remote add origin https://gitee.com/yyzlt/test3.git
1
  1. 提交
$ git push -u origin --all

$ git push -u origin --tags
1
2
3
  1. 添加submodule

  2. 再clone一份原来的仓库

  3. 删除子目录test3,并删除联系

git rm -r --cached test3
1
  1. 把test3仓库以submodule的方式添加
git submodule add https://gitee.com/yyzlt/test3.git
1
  1. 提交修改
$ git commit -m 'add submodule'
$ git push origin master
1
2

# 6. 子模块批量处理

如果一个项目有多个子模块,主模块和子模块分支不同,一个个手动切换分支很麻烦

git submodule foreach

简单来说 git submodule foreach 它能在每一个子模块中运行任意命令

所有的子模块都切换到 dev分支

git submodule foreach git checkout dev
1

拉取所有子模块的代码

git submodule foreach git pull
1

但是 foreach是遍历所有的子模块,我们要在所有的子模块下进行执行,势必会有场景中提到的报错情况,当报错后就会退出执行。我们可以在后面加条件报错后不直接退出,而是继续执行。

git submodule foreach '其他命令 || true'
1

编辑 (opens new window)
git 基本命令汇总
Git变基合并

← git 基本命令汇总 Git变基合并→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2023 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式