多模块开发

简介

Git 通过子模块来解决复用模块的问题。 submodule允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。而subtree可以将子模块合并到主模块由主模块完全管理。

git subModule

Git地址:https://www.git-scm.com/docs/git-submodule

1、拉取子模块仓库
  • git submodule add <repository_url> <submodule_path>

repository_url:克隆子模块的Url地址:ssh/http的都可以,默认拉取master分支
submodule_path: 位于主模块的那个目录位置,默认和src同级,
执行add指令后,主要是两个步骤:

  • 会拉取配置git仓库的默认分支和merged状态的最新commit,并克隆在主模块的指定目录中,(为了保证子模块的可追述性和稳定性,git默认拉取远程仓库的merge状态下最新的commit,不支持直接配置commit hash来获取指定提交,可以在主模块手动chekout到指定commit)
  • 添加引用,会将克隆基于的commit hash、URL、Branch等配置信息记录在主模块的.gitmodule文件(新建)中以及主模块的索引.git文件夹中记录当前子模块的 commit hash。

.gitmodule文件:
image.png
.git/config文件:
image.png
这里就有一个疑问,为啥要将子模块信息放在这两个地方:

  • .gitmodules: 主要用于描述项目中的子模块信息,并且这个文件是版本化的,会根据主模块提交到远程。因此,当其他人克隆主模块时,他们会得到相同的 .gitmodules 文件内容,可以正确地初始化子模块。
  • .git/config: 包含子模块的本地配置,主要用于本地环境的配置。每次你初始化或add更新子模块时,这个文件会被自动更新。

执行git ls-tree HEAD查看克隆的子模块文件夹会显示类似这样的信息:
160000 commit d6032c3e83106319e5410738055071954193724a common-web

  • 各部分含义
  1. 160000
    • 这个数字是文件模式(file mode),160000 表示这是一个 Git 子模块(submodule)。
    • 在 Git 中,常见的文件模式包括:
      • 100644:普通文件(非可执行)
      • 100755:可执行文件
      • 120000:符号链接
      • 160000:子模块
      • 040000: 文件目录
  2. commit
    • 这表明后面跟随的是一个 Git commit hash,这个 hash 引用的是子模块 common-web 在主模块中的特定版本。
    • 在普通的 git ls-tree 输出中,这个位置可能是 blob(表示文件)或 tree(表示目录)。对于子模块,它是 commit。
  3. d6032c3e83106319e5410738055071954193724a
    • 这是子模块的 commit hash,它标识了子模块 common-web 的特定版本(提交)。确保当子模块有更新时,主模块能拉取正确的子模块信息。
  4. common-web
    • 这是文件名。在这里,common-web 是子模块在主模块中的目录名。
2、开发之后提交代码

由于子模块是独立的git仓库,所以每次更新子模块之后要回到主模块,通过git add .来更新主模块对子模块的引用,然后通过commit、push操作,将子模块记录跟着主模块提交到远程,以便其他人拉取主模块时也能获取正确的子模块内容
git add: 如果子模块有更改,会在本地.git配置中更新子模块的应用commit hash…
git commit: 会将子模块的引入和主模块一起commit,即占位的空白文件夹。

3、克隆主模块

克隆主模块之后,子模块是一个空白文件夹,commit类型的引用链接。需要init、update拉取子模块代码

  • git submodule init: 读取commit hash和.gitmodule文件信息,更新主模块中.git配置文件,以便知道在哪里拉取子模块代码
  • git submodule update:根据本地.git配置拉取子模块的特定commit。
4、总结

不管在主模块还是在子模块,只要子模块有更新,主模块都要更新子模块的引用才能获取到最新的代码,所以使用git submodule来进行多模块开发进行子模块更新时,一般需要两步:

  1. 在子模块 B 中进行更改和提交:
    • 进入子模块 B 的目录。
    • 进行代码更改、添加文件到暂存区,并提交到子模块 B 的仓库。
    • 这些提交只会影响子模块 B 自身,不会自动更新主项目 A 中的子模块引用。
  2. 在主项目 A 中更新子模块 B 的引用:
    • 进入主项目 A 的根目录。
    • 更新子模块的引用,使其指向子模块 B 的最新提交。
    • 将这个子模块引用的更改提交到主项目 A 的仓库。

整体流程图:
image.png

PS: 每次更新子模块都要进入子模块,然后回到主模块在更新引用,很麻烦。

5、常用指令合集
// 子模块初始化
git submodule init
// 子模块更新
git submodule update
// 更新某个子模块代码
git submodule update --remote path/to/submodule
// 更新主模块下所有子模块代码
git submodule update --remote
// 子模块更新之后,同步主模块更新子模块的引用commit hash
git add .
// 递归克隆整个项目submodule
// --recursive表示递归地克隆git_parent依赖的所有子版本库。
git clone https://github.com/demo.git assets --recursive 
// 递归更新整个项目submodule
git submodule foreach git pull

git subtree

因为submodule有着每次更新子模块都要进入子模块然后回到主模块并同步主模块更新子模块引用,并且克隆主模块时需要依赖.gitmodule等配置拉取子模块,比较麻烦。为了避免这个,第三方基于Git底层开发了git subtree工具脚步来解决,Git在1.7.11版本后包含在发行版中。
git subtree采用合并的方式,将子模块代码作为普通文件夹直接合并到主模块的目录,这样就提供了主模块完全控制子模块的能力,可以直接在主模块对子模块进行修改更新,然后推送到子模块B的仓库,其他引入模块B的主模块通过更新即可获取最新的模块B代码。然后本地子模块的更新会随着主模块一起上传到远程。

1、问题以及解决

由于是合并的方式,所以主模块会随着引入子模块的增多,而导致主模块代码变得冗余,并且合并子模块也会将子模块所有的历史记录合并到主模块中,会导致主模块历史记录混乱。
随着引入子模块导致主模块代码增多,合理配置目录结构,将子模块和主模块结构清晰划分,更好的管理文件。
子模块合并历史记录导致主模块历史记录混乱:

  • 使用工具过滤历史记录: 可以使用 Git 提供的工具(如 git log --submodule 或者 git log --grep=)来过滤和查看主模块与子模块的提交记录,避免混淆。
  • 分支和标签的策略性使用: 在主模块中,可以使用分支和标签来标识子模块合并的时间点和版本。以便于更好地追踪和管理子模块的合并历史。
2、指令合集
// 主模块引入子模块
// --prefix 指定了子项目 B 应该放在主项目 A 中的哪个子目录。
// --squash 将子项目 B 的所有历史记录合并为一个提交,以减少主项目 A 的历史记录复杂性。
git subtree add --prefix=path/to/moduleB https://example.com/repoB.git main --squash
// 提交子模块代码
git subtree push --prefix=path/to/moduleB <remote-url> <branch>
// 拉取子模块代码
git subtree pull --prefix=path/to/moduleB <remote-url> <branch>
// 更新主模块下所有子模块代码
git submodule update --remote

git submodule和git subtree的区别

image.png
上图可知,主要区别:
1、subtree是将子模块合并到主模块中,完全属于主模块,会和主模块一起提交到远程。而submodule是将子模块作为独立仓库通过.gitmodule配置链接到主模块的,主模块提交的是子模块的引用。
2、使用上subtree可以完全受主模块控制,而submodule需要进入子模块然后进行更新,之后再回到主模块同步更新引用。

  • Git Submodule:
    • 子模块的代码独立存在,主模块只记录子模块的特定版本(commit hash)。
    • 推送主模块时,不包含子模块的实际代码,只推送子模块的引用更新。
    • 子模块的实际代码变动需要单独推送到子模块的远程仓库。
  • Git Subtree:
    • 子模块的代码整合到主模块中,成为主模块代码的一部分。
    • 推送主模块时,子模块的代码和主模块的代码一起推送到远程仓库。
    • 子模块的历史记录和变动直接体现在主模块的提交中。

简单理解为:submodule is link(commit hash), subtree is copy

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Kafka】Kafka生产者数据重复、数据有序、数据乱序-07

【Kafka】Kafka生产者数据重复、数据有序、数据乱序-07 1. 数据重复1.1 数据传递语义1.2 幂等性1.2.1 如何开启幂等性1.2.2 同一个消息&#xff0c;多个分区都会存在吗&#xff1f; 1.3 事务1.3.1 Kafka 事务原理1.3.2 Kafka事务的作用和意义作用具体应用场景 2. 数据有序3. 数…

Docker 部署项目,真的太雅了~

大家好&#xff0c;我是南城余&#xff01; 最近在找工作&#xff0c;正好手里有台服务器&#xff0c;之前项目上线用的宝塔部署项目上线&#xff0c;在公司实习了一年后&#xff0c;发现如今项目部署都使用的是容器化部署方案&#xff0c;也就是类似于和 Docker 一样的部署方案…

鸿蒙开发通信与连接:【@ohos.nfc.cardEmulation (标准NFC-cardEmulation)】

标准NFC-cardEmulation 本模块主要用于操作及管理NFC卡模拟。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import cardEmulation from ohos.nfc.cardEmulation;cardEmulation.is…

全网最易懂,开源时序数据库influxDB,实际应用评测

前言&#xff1a; 当今是信息爆炸的时代&#xff0c;在处理高频数据时&#xff0c;关系型数据库oracle/mysql明显表现出乏力&#xff0c;因秒级、毫秒级高频数据&#xff0c;分分钟可以把关系型数据库的表塞爆。在日常生活工作中&#xff0c;我们经常会遇到哪些需要高频分析的场…

NXP实战笔记(十四):32K3xx基于RTD-SDK在S32DS实现HSE的安装。

目录 1、概述 1.1、什么是HSE&#xff1f; 1.2、如何实现HSE的OTA功能 1.3、S32K3放置HSE的地址 2、通过调试器安装HSE 3、通过IVT方式安装HSE 4、坑点慎重踩 4.1、优化等级 4.2、Flash放RAM 4.3、C40_Ip配置更改 4.4、程序烧录 5、测试结果 6、代码链接 1、概述 首…

innovus:如何设置timing报告格式

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 在flow中添加如下设置即可设置好timing report的格式。 set report_timing_format [list timing_point arc net cell fanout load slew incr_delay delay arrival total_derate…

0 简单的图像分类

本文主要针对交通标识图片进行分类&#xff0c;包含62类&#xff0c;这个就是当前科大讯飞比赛&#xff0c;目前准确率在0.94左右&#xff0c;难点如下&#xff1a; 1 类别不均衡&#xff0c;有得种类图片2百多&#xff0c;有个只有10个不到&#xff1b; 2 像素大小不同&…

超越Llama3,多模态比肩GPT4V:GLM-4智能体,新一代语言处理利器

在人工智能领域&#xff0c;自然语言处理技术一直备受关注。就在昨日,今年备受关注的国内AI公司北京智谱AI发布了第四代 GLM 系列开源模型&#xff1a;GLM-4-9B。这是一个集成了先进自然语言处理技术的创新平台&#xff0c;它凭借清华大学KEG实验室提出的GLM模型结构&#xff0…

18V-180V降12V500mA恒压模块WT5118

18V-180V降12V500mA恒压模块WT5118 WT5118是一款能够将输入电压范围从18V至180V降低至12V并保持恒定输出电流500mA的恒压模块。 WT5118 是一款专为开关电源设计的集成了 180V 高电压 MOSFET 的 DC-DC 控制器。这个设备具备内置高压启动和自供电功能&#xff0c;能够满足快速启…

OpenAI 推出“模型规范”:塑造责任制的人工智能的框架

为了提升人工智能开发的责任性和透明度&#xff0c;OpenAI 最近发布了一份名为“模型规范”的初步草案。这份文件首次明确了其 API 和 ChatGPT 模型行为的指导原则&#xff0c;并通过博客形式对外公布。 OpenAI 在博客中解释说&#xff1a;“我们之所以发布此文档&#xff0c;…

「Python-docx 专栏」docx 设置页面边距、页眉页脚高度

本文目录 前言一、docx 页面边距在哪里二、对 <w:pgMar> 的详细说明1、上边距的说明2、右边距的说明3、下边距的说明4、左边距的说明5、页眉高度的说明6、页脚高度的说明三、设置 docx 页边距、页眉页脚高度1、完整代码2、代码执行效果图四、补充一些内容1、页面边距的两…

图解Sieve of Eratosthenes(埃拉托斯特尼筛法)算法求解素数个数

1.素数的定义 素数又称质数。质数是指在大于1的自然数中&#xff0c;除了1和它本身以外不再有其他因数的自然数。一个大于1的自然数&#xff0c;除了1和它自身外&#xff0c;不能被其他自然数整除的数叫做质数&#xff1b;否则称为合数&#xff08;规定1既不是质数也不是合数&…

【绝对有用】刚刚开通的GPT-4o计算这种数学题目出现问题了

欢迎关注如何解决以上问题的方法&#xff1a;查看个人简介中的链接的具体解决方案

Nvidia Isaac Sim搭建仿真环境 入门教程 2024(4)

Nvidia Isaac Sim 入门教程 2024 版权信息 Copyright 2023-2024 Herman YeAuromix. All rights reserved.This course and all of its associated content, including but not limited to text, images, videos, and any other materials, are protected by copyright law. …

【iOS】#include、#import、@class、@import

文章目录 #include#importclassimport总结 #include #include是c\c中的预处理器指令&#xff0c;用于包含头文件的内容 但是使用#include可能会出现重复包含文件的问题&#xff0c;因此需要使用&#xff08;#ifndef/#define/#endif&#xff09;。 #import //导入系统头文件…

候选键的确定方法-如何判断属性集U的子集K是否为候选键、如何找到关系模式的候选键

一、候选键的定义 在关系模式R(U,F)中&#xff0c;若&#xff0c;且K满足&#xff0c;则K为关系模式R的候选键 关系模式R的候选键必须满足以下两个条件&#xff1a; &#xff08;1&#xff09;必须是属性集U的子集 &#xff08;2&#xff09;完全函数决定属性集U 二、如何…

【网络安全的神秘世界】已解决Failed to start proxy service on 127.0.0.1:8080

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 解决burpsuite无法在 127.0.0.1&#xff1a;8080 上启动代理服务端口被占用以及抓不到本地包的问题 Burpsuite无法启动proxy…

令人震撼的人类智慧的科学领域-AI技术

AI&#xff0c;全称为人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;是一门致力于让机器模仿人类智慧的科学领域。其核心技术涵盖了机器学习、自然语言处理、计算机视觉及专家系统等多个方面。AI旨在开发能够感知环境、进行逻辑推理、自主学习并做出决策…

Python数据可视化:直方图、核密度估计图、箱线图、累积分布函数图

本文使用数据来源自2023年数学建模国赛C题&#xff0c;以附件1、附件2数据为基础&#xff0c;通过excel的数据透视表等功能重新汇总了一份新的数据表&#xff0c;从中截取了一部分数据为例用于绘制图表。绘制的图表包括一维直方图、一维核密度估计图、二维直方图、二维核密度估…

godot所有2D节点介绍

五十个2D节点介绍 2D节点介绍 前言一、Node2D二、sprite2D三、AnimatedSprite2D四、Camera2D五、PhysicsBody2D六、 RigidBody2D七、CharacterBody2D八、StaticBody2D九、joint2D十、DampedSpringJoint2D十一、GrooveJoint2D十二、PinJoint2D十三、Area2D十四、AnimatableBody2…