聊聊 Git SubModule(子模块)

2024-02-19 17:28
文章标签 模块 聊聊 git submodule

本文主要是介绍聊聊 Git SubModule(子模块),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

比如在公司不同开发团队中,有一个基础共享库,同时被多个项目调用。若要保证基础共享库的动态更新,那么就需要把共享库独立为一个代码库,但是分别把共享库中的文件拷贝到各自的项目中会造成冗余,而且再次更新共享库就会在不同项目下更新,会比较麻烦。

利用子模块可以作为解决该类问题的一种方案,子模块允许将一个Git仓库作为另一个Git仓库的子目录,并且可以独立地管理这个子仓库的版本,而且还能保持提交的独立性。

下面就通过实操来具体谈谈 Git submodule

一、什么是Git Submodule

Git Submodule 是Git版本控制系统中的一种机制,用于在一个Git仓库中包含另一个Git仓库。它允许将一个Git仓库作为另一个Git仓库的子目录,并且可以独立地管理这个子仓库的版本,同时还保持提交的独立。
image.png
Submodule的作用在于,它允许你在一个项目中使用其他项目的特定版本,而无需将整个子项目的代码复制到主项目中。这对于依赖管理和代码复用非常有用。

二、使用 Git Submodule

1 创建和初始化仓库

  • 初始化主库和子模块库

我采用的是 Gitee 来进行本次实操,首先在 Gitee 中创建一个主库 GitSubmoduleDemo,两个子模块库 ModuleAModuleB:
image.png
先将主库 clone 到本地:

$ git clone https://gitee.com/haohuin/git-submodule-demo.git
  • 在主库中,使用 git submodule add 命令添加 Submodule子模块。

其命令为:git submodule add <remote repo url> <local repo url>

  • remote repo url 指远程仓库的 url
  • local repo url 指本地仓库的路径 url
//在主库中添加ModuleA
$ git submodule add ../module-a.git ModuleA//在主库中添加ModuleB
$ git submodule add ../module-b.git ModuleB

查看当前主库的状态:

$ git status
On branch master
Your branch is up to date with 'origin/master'.Changes to be committed:(use "git restore --staged <file>..." to unstage)new file:   .gitmodulesnew file:   ModuleAnew file:   ModuleB

发现有新的文件在主库中,分别是 .gitmodules文件,ModuleAModuleB目录

1.1 .gitmodules文件

首先看一下 .gitmodules配置文件,它保存了远程仓库 url 与本地仓库 url 路径的映射:

[submodule "ModuleA"]path = ModuleAurl = ../module-a.git
[submodule "ModuleB"]path = ModuleBurl = ../module-b.git

每条记录对应一个子模块信息,path 和 url 对应远程仓库 url 和本地仓库路径

1.2 主库中的子模块

接着提交当前主库中出现的文件和目录:

//暂存
$ git add .
//提交
$ git commit -m "ModuleA and ModuleB submodule commit"
[master 2dcfefd] ModuleA and ModuleB submodule commit3 files changed, 8 insertions(+)create mode 100644 .gitmodulescreate mode 160000 ModuleAcreate mode 160000 ModuleB

发现ModuleAModuleB目录的模式编码为 160000
在之前讲解 index文件提到过,模式 160000是引用其他 Git 仓库的特殊文件类型,它允许将一个 Git 仓库作为另一个仓库的子目录进行管理。具体可以看这篇文章Git暂存区机制详解
所以此时主库中只是存储了子模块的引用,也就是一次的提交记录。而不是其他的文件或者目录。最后将主库中的修改进行推送:

$ git push origin master

image.png
发现在主库中ModuleAModuleB确实是以引用的形式存储的。

2 更新和同步子模块

那么如何将子模块的修改更新到主仓库中呢?这又分两种情况:

  • 在子模块所在的仓库中修改代码后提交,然后在主仓库中拉取更新
  • 在主仓库中修改子模块代码后提交远程仓库,然后在子模块仓库中拉取更新

2.1 主仓库更新子模块仓库中的修改

首先在子模块仓库 ModuleA 中新增一个文件,并提交到 ModuleA 的远程仓库中:

$ echo "updateModuleA-1">updateModuleA-1.txt
$ git add .
$ git commit -m "update ModuleA"
$ git push

image.png
此时子模块仓库中的 commit ID 值为 6026b48,再来看一下主仓库中的子模块的 Commit ID 值
image.png
发现此时主仓库的 Commit ID 值为 3474554,和子模块仓库中的 ID 值并不同步,所以需要在主仓库的子模块代码中同步子模块远程仓库的更新:

$ cd ModuleA
$ git checkout master
$ git pull origin master

然后在主仓库根目录中提交子模块仓库推送和更新:

$ cd ..
$ git add .
$ git commit -m "update ModuleA"
$ git push

此时发现远程主仓库已经同步子模块的更新内容,而且 Commit ID 值也同步成6026b48 ,和子模块仓库中最新的 Commit ID 保持一致:

image.png

2.2 子模块仓库更新主仓库中子模块代码的修改提交

首先在主仓库的子模块目录下修改代码:

//在主仓库中进入子模块ModuleA目录
$ cd ModuleA
//修改文件和提交和普通Git仓库提交流程一致:
//1.创建文件并提交
$ echo "ModuleA">updateModuleA.txt
$ git add .
$ git commit -m "update ModuleA"
//2.推送到远程ModuleA仓库
$ git push

发现远程子模块仓库也同步完成:

image.png

接着需要将主仓库中的子模块 ModuleA 的变化同步到远程主仓库中具体的操作和上一节主仓库更新子模块仓库中的修改类似,用 add 和 commit 方式提交主仓库的更新,这个时候就完成了子模块和主仓库代码一致。

$ cd ..
$ git add .
$ git commit -m "update ModuleA"
$ git push

在实际的 IDE 环境中,只需要在子模块目录下进行代码修改:

image.png
然后在提交时先更新子模块 ModuleB 的远程仓库:
image.png
然后再同步远程主仓库中的 ModuleB 目录变化,这一步需要用命令行,直接在主目录提交没法更新远程主目录,但是本地主仓库的 ModuleB 目录确实发生了变化:

$ 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 restore <file>..." to discard changes in working directory)modified:   ModuleB (new commits)no changes added to commit (use "git add" and/or "git commit -a")

需要命令行切换到主仓库目录执行 git add 后再用 IDE 集成的 Git 提交操作:

$ git add .

再点击提交发现 IDE 中出现了 ModuleB 的更新变化:
image.png
接着推送到远程主仓库即可完成主仓库和子模块仓库的更新

三、总结

本文通过实践介绍子模块:

  • 包括子模块的初始化,如何使用 git submodule add 命令在主仓库添加子模块
  • 如何在子模块和主仓库之间的更新和同步

子模块主要有以下应用场景

  • 不同项目间需要共享同一个公共代码,如基础类库或工具包;
  • 较大的项目需要拆分成多个子项目进行开发,通过子模块控制依赖关系;
  • 第三方开源库或组件的本地开发与项目进行绑定;
  • 需要隔离成组和组件版本的同时利用依赖关系,如微服务架构下的服务与组件;
  • 子项目有较强的独立性同时也存在一定的耦合关系,通过子模块进行管理。

同时从上面的时间可以看到,子模块和主仓库之间的同步比较复杂,维护成本高,子模块与主项目需要进行紧密的协调管理,否则很容易导致不同步的情况出现。在使用中要结合实际情况下操作,简单的项目就不要用子模块,采用分支管理可能更合适。

参考资料

公共模块管理之 Git Submodule 使用总结
Git - 子模块
《Git 权威指南 蒋鑫著》

这篇关于聊聊 Git SubModule(子模块)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/725394

相关文章

IDEA实现回退提交的git代码(四种常见场景)

《IDEA实现回退提交的git代码(四种常见场景)》:本文主要介绍IDEA实现回退提交的git代码(四种常见场景),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.已提交commit,还未push到远端(Undo Commit)2.已提交commit并push到

Python logging模块使用示例详解

《Pythonlogging模块使用示例详解》Python的logging模块是一个灵活且强大的日志记录工具,广泛应用于应用程序的调试、运行监控和问题排查,下面给大家介绍Pythonlogging模... 目录一、为什么使用 logging 模块?二、核心组件三、日志级别四、基本使用步骤五、快速配置(bas

Python datetime 模块概述及应用场景

《Pythondatetime模块概述及应用场景》Python的datetime模块是标准库中用于处理日期和时间的核心模块,本文给大家介绍Pythondatetime模块概述及应用场景,感兴趣的朋... 目录一、python datetime 模块概述二、datetime 模块核心类解析三、日期时间格式化与

Python如何调用指定路径的模块

《Python如何调用指定路径的模块》要在Python中调用指定路径的模块,可以使用sys.path.append,importlib.util.spec_from_file_location和exe... 目录一、sys.path.append() 方法1. 方法简介2. 使用示例3. 注意事项二、imp

Git可视化管理工具(SourceTree)使用操作大全经典

《Git可视化管理工具(SourceTree)使用操作大全经典》本文详细介绍了SourceTree作为Git可视化管理工具的常用操作,包括连接远程仓库、添加SSH密钥、克隆仓库、设置默认项目目录、代码... 目录前言:连接Gitee or github,获取代码:在SourceTree中添加SSH密钥:Cl

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

Python正则表达式语法及re模块中的常用函数详解

《Python正则表达式语法及re模块中的常用函数详解》这篇文章主要给大家介绍了关于Python正则表达式语法及re模块中常用函数的相关资料,正则表达式是一种强大的字符串处理工具,可以用于匹配、切分、... 目录概念、作用和步骤语法re模块中的常用函数总结 概念、作用和步骤概念: 本身也是一个字符串,其中

Python中的getopt模块用法小结

《Python中的getopt模块用法小结》getopt.getopt()函数是Python中用于解析命令行参数的标准库函数,该函数可以从命令行中提取选项和参数,并对它们进行处理,本文详细介绍了Pyt... 目录getopt模块介绍getopt.getopt函数的介绍getopt模块的常用用法getopt模

python logging模块详解及其日志定时清理方式

《pythonlogging模块详解及其日志定时清理方式》:本文主要介绍pythonlogging模块详解及其日志定时清理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录python logging模块及日志定时清理1.创建logger对象2.logging.basicCo