当前位置: 首页 > news >正文

【Git】Git Submodules 介绍(通俗易懂,总结了工作完全够用的 submodule 命令)

Git Submodules 介绍

  • 1、为什么你值得读这篇文章?
  • 2、为什么有 submodules?
  • 3、了解 Git Submodules
    • 3.1、如何让一个Git仓库变为另一个Git仓库的 submodule
    • 3.2、submodule 的父子关系存在哪里
      • 3.3、submodule 的父子关系信息怎么存
  • 4、submodule 开发常用操作
    • 4.1、添加子模块
    • 4.2、实际开发操作
      • 4.2.1、将远端包含有子模块的代码克隆下来
      • 4.2.2、建分支操作
      • 4.2.2、子模块开发合并到develop/test
      • 4.2.2、子模块和父模块开发合并到master
  • 5、总结

1、为什么你值得读这篇文章?

  • 一些技术博客写的很详细,但不适合新人学习。

  • 官方文档很全面,适合了解详细命令,但主次不分明。

本文会根据我的大量的 submodules 实践经验(包括工作和个人开发),只解释常用的命令。当你了解这些命令,你完全可以像我一样使用 Git Submodules。

2、为什么有 submodules?

  1. 解决公共代码问题。如果某些文件,在项目A和项目B中都会用到,例如组件库,那么这些文件可以作为 submodules 来管理,减少重复代码。(当然,该场景下npm包是另一解决方案,你需要选择一种方案。)

  2. 解决团队维护难题。如果一个大项目是一个大 Git 仓库,需要统一编译,不同的模块由不同团队维护,放在同一个 Git 仓库有诸多难处:例如多个团队的 MR 混在一起、权限难以区分等。这种情况即使公司内网 Git 权限做的足够精细,仓库管理员的学习成本也会很高,很难深度使用这种高级功能。为了解决多团队维护的难题,Git Submodules 也能大展身手,它可以让每个团队负责的模块就是一个 Git 仓库,这些 Git 仓库都被包含在同一个主 Git 项目下。(当然,微前端、微服务是另一种解决方案,你需要选择一种方案。)

3、了解 Git Submodules

有2个概念:主项目submodule(子模块)。这两者各自都是完整的 Git 仓库。

3.1、如何让一个Git仓库变为另一个Git仓库的 submodule

  1. 创建Git仓库A。
  2. 创建Git仓库B。
  3. 在Git仓库A中,通过git submodule add ...(仓库B的地址,即git clone时后面那串东西),可以把仓库B当作仓库A的submodule,此时A就成了主项目。【注:B也可以做A的主项目,通过在仓库B执行git submodule add ...(A地址)即可,因为二者都是完整Git仓库,在建立父子关系前,没有差异的。】

注意事项

  • 执行操作后,会在当前父项目下新建个文件夹,名字就是 submodule 仓库的名字。这个文件夹里面的内容,是 submodule 对应 Git 仓库的完整代码

  • 如果你希望换个名字,或者换个路径(例如放在某个更深的目录下),也是允许的,需要后面增加个路径参数,例如git submodule add ...(仓库地址) src/B(你希望 submodule 位于的文件夹路径)

3.2、submodule 的父子关系存在哪里

关系是保存在主项目的 Git 仓库中。

被当作 submodule 的 Git 仓库,其实不知道自己变成了 submodule,它更不知道爸爸们有谁。(意思是,当你打开某个被当作 submodule 的 Git 仓库首页时,或者拉下这个仓库时,没有任何痕迹表明它是个submodule。因为父子信息不存在这里,只存在爸爸那里。)

3.3、submodule 的父子关系信息怎么存

.gitmodules 文件

父子关系的信息保存在主项目的.gitmodules文件,如果不是新加 submodule,这个文件通常不必改变了,因为信息比较固定。

这个文件中主要记录了子模块的url,如果添加的时候使用的ssh链接,那这个url就是ssh,如果是https链接,这个url就是https

在这里插入图片描述

submodule 的版本号

主项目还保存了对应 submodule 的版本号(commit id),没有冗余存储 submodule 的代码。

可以看到,这其实是个跳转到另一个仓库的链接,指明了具体的 commit id。

这个版本号,是需要经常变更的。

在这里插入图片描述

4、submodule 开发常用操作

4.1、添加子模块

在github中创建了三个项目,其中git-learn为主项目,git-learn-submodules1和git-learn-submodules2为子项目
在这里插入图片描述

将git-learn克隆到本地,然后执行git submodule add ...(仓库B的地址,即git clone时后面那串东西)添加子模块到git-learn中

在这里插入图片描述
本地项目文件夹下面就多出来了两个文件夹(两个子项目)和一个文件(.gitmodules)

在这里插入图片描述
这是git上的目录,其中两个字模块用hash commit来维护,指向的是两个子仓库的地址

在这里插入图片描述

点击就跳转到对应子模块的目录:

在这里插入图片描述

到此,子模块初始化完成,接下来模拟实际工作场景

4.2、实际开发操作

4.2.1、将远端包含有子模块的代码克隆下来

git clone --recurse-submodules <主仓库url>

如:https://github.com/your-username/your-repository.git

在这里插入图片描述

4.2.2、建分支操作

下面以idea操作为例,使用idea打开git-learn文件夹

实际开发分为,develop、test、prod、master、feature、release和hotfix等,我们模拟简单建一下

在这里插入图片描述
从main新建一个prod分支,然后推送到远端,develop和test类似

建完后如下图:

在这里插入图片描述

4.2.2、子模块开发合并到develop/test

当我们要开发时,从最新的master新建一个feature分支,要注意的是,我们开发哪个模块,就只需要新建哪一个模块的feature就行,其他可以不用动

在这里插入图片描述
例如:我要开发git-learn-submodules1模块,从master新建一个feature/0716-xxxx分支

在这里插入图片描述
在这里插入图片描述
其中,git-learn-submodules1分支在feature/0716-xxxx分支,git-learngit-learn-submodules2在master分支

现在对git-learn-submodules1文件进行修改

在这里插入图片描述

提交修改,推送到远端开发分支

在这里插入图片描述
在这里插入图片描述

推送成功后,你的feature分支中就有了记录

在这里插入图片描述
现在,需要将你的代码,合到develop或者test分支,以develop为例

本地仓库切到develop分支,并且更新最新的develop代码(跟新最新代码,可以避免冲突):

在这里插入图片描述

merge最新的开发代码到develop环境中

在这里插入图片描述

成功以后develop会出现绿色小箭头,然后推送到远端仓库

在这里插入图片描述

在这里插入图片描述
这样你的开发环境中,就是最新的代码了,test同理

在这里插入图片描述

4.2.2、子模块和父模块开发合并到master

在这里插入图片描述

修改子模块和父模块

在这里插入图片描述

这个时候会出现下面情况

在这里插入图片描述
common-api.jsonsub1.txt是我们修改的文件是因为git-learn-submodules1子文件的hash不一致出现的问题(最新hash在develop,我们现在处与feature/0716-xxxx分支)

这种情况,我们先提交模块分支

在这里插入图片描述
然后推送到远端的feature/0716-xxxx分支

在这里插入图片描述
一般开发,没有合master权限,需要请求合并分支

在github (gitlab同理) 中子模块目录发起合并master请求

在这里插入图片描述

完成merge

在这里插入图片描述
这个时候,你的远端master上的git-learn-submodules1是最新的,需要拉到本地仓库,这个时候本地master就是最新的了

在这里插入图片描述
然后提交公共模块

在这里插入图片描述
然后按照同样的方法去发起merge请求操作。

到此,合并完成

5、总结

画了一个流程图,加深印象

在这里插入图片描述

通过官方文档,你可以了解到更多场景,但是我从来没使用过其它场景了,因为用不到。本文描述的完全满足了我所有日常使用场景。

而高级场景会导致协作变困难,因为不是所有开发者都懂这些更复杂的命令和配置

英文文档:https://www.git-scm.com/book/en/v2/Git-Tools-Submodules
中文文档:https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%AD%90%E6%A8%A1%E5%9D%97

GitHub地址:https://github.com/huang-hanson/git-learn

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 签名优化:请求数据类型不是`application/json`,将只对随机数进行签名计算,例如文件上传接口。
  • 网络编程-TCP 协议的三次握手和四次挥手做了什么
  • Spark安装
  • npm安装依赖包报错,npm ERR! code ENOTFOUND
  • 介绍下项目的架构
  • 【精简版】jQuery 中的 Ajax 详解
  • 大数据面试SQL题-笔记01【运算符、条件查询、语法顺序、表连接】
  • 如何用EXCEL自动解方程/方程组?利用 矩阵乘法X=A-*B,X=mmult(minverse(A), B)
  • PHP手边酒店多商户版平台小程序系统源码
  • 前缀匹配工具之IP-Prefix
  • Web控件进阶交互
  • 链路聚合概述
  • AutoMQ 生态集成 Redpanda Console
  • 【代码随想录|第十一章 图论part01 | 797.所有可能的路径 】
  • 基于深度学习的水果识别系统
  • [笔记] php常见简单功能及函数
  • 【技术性】Search知识
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • EventListener原理
  • FineReport中如何实现自动滚屏效果
  • Flex布局到底解决了什么问题
  • isset在php5.6-和php7.0+的一些差异
  • Javascripit类型转换比较那点事儿,双等号(==)
  • jquery ajax学习笔记
  • Laravel核心解读--Facades
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 从零开始学习部署
  • 对JS继承的一点思考
  • 记一次删除Git记录中的大文件的过程
  • 漂亮刷新控件-iOS
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • Java总结 - String - 这篇请使劲喷我
  • # include “ “ 和 # include < >两者的区别
  • $(this) 和 this 关键字在 jQuery 中有何不同?
  • (el-Date-Picker)操作(不使用 ts):Element-plus 中 DatePicker 组件的使用及输出想要日期格式需求的解决过程
  • (JS基础)String 类型
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (五)网络优化与超参数选择--九五小庞
  • (一)插入排序
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .net MySql
  • //usr/lib/libgdal.so.20:对‘sqlite3_column_table_name’未定义的引用
  • [20170713] 无法访问SQL Server
  • [C#]winform部署yolov5-onnx模型
  • [CareerCup] 17.8 Contiguous Sequence with Largest Sum 连续子序列之和最大
  • [Cesium学习]
  • [C语言]——函数递归
  • [Day 65] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
  • [Design Pattern] 工厂方法模式