Git常用命令submodule

news2024/11/27 22:01:57

Git常用命令submodule

1、需求

当程序比较大参与开发人员较多时,代码管理就复杂起来。代码如果全员可见,可以创建 share 分支维护共用代

码,可以创建 core 分支维护核心算法代码,各进程分别占一个分支,定期同步 share 和 core 分支。代码如果不

能全员可见,可以仓库中包含子仓库,子仓库管理模块代码,主仓库定时更新。

同时有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。也许是第三方库,或者你独立开发

的,用于多个父项目的库。现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一

个。如果将另外一个项目中的代码复制到自己的项目中,那么你做的任何自定义修改都会使合并上游的改动变得困

难。Git 通过子模块来解决这个问题,允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。它能让你将另一个仓

库克隆到自己的项目中,同时还保持提交的独立。

2、常用命令

# 添加子模块
# 在主项目中添加子项目,URL为子模块的路径,path为该子模块存储的目录路径
git submodule add [repository_url] [path]

# 克隆含有子项目的主项目
git clone [repository_url]

# 递归的方式克隆整个项目
git clone <repository> --recursive 
# 当你在克隆这样的项目时,默认会包含该子项目的目录,但该目录中还没有任何文件

# 初始化本地配置文件
# 初始化子模块
git submodule init

# 从当前项目中抓取所有数据并检出父项目中列出的合适的提交
# 更新子模块
git submodule update

# 等价于git submodule init && git submodule update
git submodule update --init

# 自动初始化并更新仓库中的每一个子模块,包括可能存在的嵌套子模块
git clone --recurse-submodules [url]

# 拉取所有子模块
git submodule foreach git pull 

3、使用

3.1 创建带子模块的版本库

例如我们要创建如下结构的项目:

project
  |--moduleA
  |--readme.txt
$ mkdir submoduletest

$ cd submoduletest/

创建 project 版本库,并提交 readme.txt 文件:

$ git init --bare project.git
Initialized empty Git repository in C:/Users/zhangshixing/Desktop/submoduletest/project.git/

$ git clone project.git project1
Cloning into 'project1'...
warning: You appear to have cloned an empty repository.
done.

$ cd project1

$ echo "This is a project." > readme.txt

$ git add .

$ git commit -m "add readme.txt"
[master (root-commit) 50a6933] add readme.txt
 1 file changed, 1 insertion(+)
 create mode 100644 readme.txt

$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 229 bytes | 229.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To C:/Users/zhangshixing/Desktop/submoduletest/project.git
 * [new branch]      master -> master

$ cd ..

创建 moduleA 版本库,并提交 a.txt 文件:

$ git init --bare moduleA.git
Initialized empty Git repository in C:/Users/zhangshixing/Desktop/submoduletest/moduleA.git/

$ git clone moduleA.git moduleA1
Cloning into 'moduleA1'...
warning: You appear to have cloned an empty repository.
done.

$ cd moduleA1

$ echo "This is a submodule." > a.txt

$ git add .

$ git commit -m "add a.txt"
[master (root-commit) d0f22fb] add a.txt
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt

$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 224 bytes | 224.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To C:/Users/zhangshixing/Desktop/submoduletest/moduleA.git
 * [new branch]      master -> master

$ cd ..

project 项目中引入子模块 moduleA ,并提交子模块信息:

$ cd project1

$ git submodule add ../moduleA.git moduleA
Cloning into 'C:/Users/zhangshixing/Desktop/submoduletest/project1/moduleA'...
done.

$ ls
moduleA/  readme.txt

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   .gitmodules
        new file:   moduleA

$ git diff

$ git add .

$ git commit -m "add submodule"
[master 60d9847] add submodule
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 moduleA

$ git push origin master
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 352 bytes | 352.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To C:/Users/zhangshixing/Desktop/submoduletest/project.git
   50a6933..60d9847  master -> master

$ cd ..

使用 git status 可以看到多了两个需要提交的文件,其中 .gitmodules 指定submodule的主要信息,包括子

模块的路径和地址信息,moduleA 指定了子模块的commit id,使用git diff可以看到这两项的内容。这里需要

指出父项目的 git 并不会记录 submodule 的文件变动,它是按照 commit id 指定 submodule 的 git header,所

.gitmodulesmoduleA 这两项是需要提交到父项目的远程仓库的。

3.2 克隆带子模块的版本库

方法一,先 clone 父项目,再初始化 submodule,最后更新 submodule,初始化只需要做一次,之后每次只需

要直接 update 就可以了,需要注意 submodule 默认是不在任何分支上的,它指向父项目存储的 submodule

commit id。

$ git clone project.git project2
Cloning into 'project2'...
done.

$ cd project2

$ ls
moduleA/  readme.txt

$ ls moduleA/
# 没有内容

$ git submodule init
Submodule 'moduleA' (C:/Users/zhangshixing/Desktop/submoduletest/moduleA.git) registered for path 'moduleA'

$ ls moduleA/
# 没有内容

$ git submodule update
Cloning into 'C:/Users/zhangshixing/Desktop/submoduletest/project2/moduleA'...
done.
Submodule path 'moduleA': checked out 'd0f22fbfd4336480863ed232ec785c0e507cf944'

$ ls moduleA/
a.txt

$ cd ..

方法二,采用递归参数 --recursive,需要注意同样 submodule 默认是不在任何分支上的,它指向父项目存储

的 submodule commit id。

$ git clone project.git project3 --recursive
Cloning into 'project3'...
done.
Submodule 'moduleA' (C:/Users/zhangshixing/Desktop/submoduletest/moduleA.git) registered for path 'moduleA'
Cloning into 'C:/Users/zhangshixing/Desktop/submoduletest/project3/moduleA'...
done.
Submodule path 'moduleA': checked out 'd0f22fbfd4336480863ed232ec785c0e507cf944'

$ cd project3/

$ ls
moduleA/  readme.txt


$ ls moduleA/
a.txt

3.3 修改子模块

修改子模块之后只对子模块的版本库产生影响,对父项目的版本库不会产生任何影响,如果父项目需要用到最新的

子模块代码,我们需要更新父项目中 submodule commit id,默认的我们使用 git status 就可以看到父项目中

submodule commit id 已经改变了,我们只需要再次提交就可以了。

$ cd project1/moduleA

$ git branch
* master

$ echo "This is a submodule." > b.txt

$ git add .

$ git commit -m "add b.txt"
[master e9b6471] add b.txt
 1 file changed, 1 insertion(+)
 create mode 100644 b.txt

$ git push origin master
Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 230 bytes | 230.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To C:/Users/zhangshixing/Desktop/submoduletest/moduleA.git
   d0f22fb..e9b6471  master -> master

$ cd ..

$ 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 checkout -- <file>..." to discard changes in working directory)

        modified:   moduleA (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

$ git diff
diff --git a/moduleA b/moduleA
index d0f22fb..e9b6471 160000
--- a/moduleA
+++ b/moduleA
@@ -1 +1 @@
-Subproject commit d0f22fbfd4336480863ed232ec785c0e507cf944
+Subproject commit e9b647157369276e6e70fc148fc176676eab4476

$ git add .

$ git commit -m "update submodule add b.txt"
[master 312c8e0] update submodule add b.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git push origin master
Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 308 bytes | 308.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To C:/Users/zhangshixing/Desktop/submoduletest/project.git
   60d9847..312c8e0  master -> master

$ cd ..

3.4 更新子模块

更新子模块的时候要注意子模块的分支默认不是 master。

方法一,先pull父项目,然后执行 git submodule update,注意 moduleA 的分支始终不是master。

$ cd project2

$ git pull
remote: Counting objects: 2, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done.
From C:/Users/zhangshixing/Desktop/submoduletest/project
   60d9847..312c8e0  master     -> origin/master
Fetching submodule moduleA
From C:/Users/zhangshixing/Desktop/submoduletest/moduleA
   d0f22fb..e9b6471  master     -> origin/master
Updating 60d9847..312c8e0
Fast-forward
 moduleA | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git submodule update
Submodule path 'moduleA': checked out 'e9b647157369276e6e70fc148fc176676eab4476'

$ cd ..

方法二,先进入子模块,然后切换到需要的分支,这里是 master 分支,然后对子模块 pull,这种方法会改变子模

块的分支。

$ cd project3/moduleA

$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

$ cd ..

$ git submodule foreach git pull
Entering 'moduleA'
remote: Counting objects: 2, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done.
From C:/Users/zhangshixing/Desktop/submoduletest/moduleA
   d0f22fb..e9b6471  master     -> origin/master
Updating d0f22fb..e9b6471
Fast-forward
 b.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 b.txt

$ 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 checkout -- <file>..." to discard changes in working directory)

        modified:   moduleA (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

$ git diff
diff --git a/moduleA b/moduleA
index d0f22fb..e9b6471 160000
--- a/moduleA
+++ b/moduleA
@@ -1 +1 @@
-Subproject commit d0f22fbfd4336480863ed232ec785c0e507cf944
+Subproject commit e9b647157369276e6e70fc148fc176676eab4476

$ git add .

$ git commit -m "update submodule add b.txt"
[master 50e7e55] update submodule add b.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git push origin master | git push -f origin master
Counting objects: 8, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (8/8), 824 bytes | 824.00 KiB/s, done.
Total 8 (delta 0), reused 0 (delta 0)
To C:/Users/zhangshixing/Desktop/submoduletest/project.git
 + 6e1a3d3...50e7e55 master -> master (forced update)

$ cd ..

3.5 删除子模块

有时子模块的项目维护地址发生了变化,或者需要替换子模块,就需要删除原有的子模块。

网上有好多用的是下面这种方法:

$ cd project1/

$ ls
moduleA/  readme.txt

$ git rm --cached moduleA
rm 'moduleA'

$ rm -rf moduleA

$ rm .gitmodules

$ vim .git/config

在这里插入图片描述

# 删除submodule相关的内容
[submodule "moduleA"]
      url = C:/Users/zhangshixing/Desktop/submoduletest/moduleA.git
	  active = true

在这里插入图片描述

# 然后提交到远程服务器
$ git add .

$ git commit -m "remove submodule"
[master 93e32f8] remove submodule
 2 files changed, 4 deletions(-)
 delete mode 100644 .gitmodules
 delete mode 160000 moduleA
 
$ git push origin master
Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (1/1), done.
Writing objects: 100% (2/2), 234 bytes | 234.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To C:/Users/zhangshixing/Desktop/submoduletest/project.git
   312c8e0..93e32f8  master -> master

但是我自己本地实验的时候,发现用下面的方式也可以,服务器记录的是 .gitmodulesmoduleA,本地只要

用 git 的删除命令删除 moduleA,再用 git status 查看状态就会发现 .gitmodules 和 moduleA 这两项都已经改变

了,至于 .git/config,仍会记录 submodule 信息,但是本地使用也没发现有什么影响,如果重新从服务器克隆

则 .git/config 中不会有submodule信息。

$ git rm moduleA
rm 'moduleA'

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   .gitmodules
        deleted:    moduleA

$ git commit -m "remove submodule"
[master 6e1a3d3] remove submodule
 2 files changed, 4 deletions(-)
 delete mode 160000 moduleA

$ git push origin master | git push -f origin master
Counting objects: 11, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (11/11), 1.05 KiB | 1.05 MiB/s, done.
Total 11 (delta 0), reused 0 (delta 0)
To C:/Users/zhangshixing/Desktop/submoduletest/project.git
 + 93e32f8...6e1a3d3 master -> master (forced update)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何从 OpenAI 迁移到 Azure OpenAI(保姆级教程,包含如何兼容 JS 语言版 LangChain)

Azure OpenAI 和 OpenAI 一样&#xff0c;本质都是调用 api&#xff0c;Azure OpenAI 的使用会稍微复杂一点&#xff0c;但好处就是方便付费。 创建 Azure OpenAI 资源 首先&#xff0c;先登录 Azure 账号&#xff1a;https://azure.microsoft.com/zh-cn/ 接着创建 OpenAI 资…

硬件工程师-BOOST升压电源设计

一、Boost变换原理 开关闭合时&#xff0c;电感电压等于输入电压 开关断开时&#xff0c;电感电压输出电压-输入电压&#xff0c; 电感的感生电动势&#xff0c;N ΔΦ磁通的变化率&#xff0c;Δt时间 假设开关闭合与开关断开&#xff0c;开关断开时能量全部释放光 将第三个式…

MySQL(进阶篇1.0)

MySQL体系结构 1、连接层 最上层是一些客户端和连接服务&#xff0c;包含本地sock通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关安全方案。在该层上引入了线程池的概念&#xff0c;为通过认证安全接入的客户端提…

进程的通信方式有哪些?

目录 管道消息队列共享内存信号量信号套接字 管道 最初我们在学习Linux基本命令使用的时候&#xff0c;我们经常通过多个命令的组合来完成我们的需求。比如说我们想知道如何查看进程或者端口是否在使用&#xff0c;会使用下面的这条命令 netstat nlp | grep xxx 这里的"|“…

电子科技大学计算机系统结构复习笔记(四):存储系统

目录 前言 重点一览 Cache基本原理 三种映像方式 物理地址与Cache地址的映射计算 Cache块标识 Cache替换算法 Cache写策略 分离cache与一体cache Cache性能与优化 Cache性能计算 Cache性能优化 主存储器与虚拟存储器 主存储器性能优化 虚拟存储器 虚拟存储器与…

编译 ONNX 模型

本篇文章译自英文文档 Compile ONNX Models — tvm 0.13.dev0 documentation 作者是 Joshua Z. Zhang 更多 TVM 中文文档可访问 →TVM 中文站。 本文将介绍如何用 Relay 部署 ONNX 模型。 首先安装 ONNX 包&#xff0c;最便捷的方法推荐安装 protobuf 编译器&#xff1a; pi…

【资料分享】浪涌电流(Inrush Current)产生原因

1、对Inrush Current电流的直观感受 当电灯在电路中工作时&#xff0c;如果突然启动马达或者变压器时&#xff0c;会出现电灯暗一下&#xff0c;此时电灯出现暗的情况就是因为马达或者变压器启动时&#xff0c;在电路中产生较大Inrush Current&#xff0c;具体分析可以参考下图…

图解HTTP书籍学习

了解Web及网络基础 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09; Web是建立在HTTP协议上通信的 把SGML&#xff08;Standard Generalized Markup Language&#xff0c;标准通用标记语言&#xff09; HTML&#xff08;HyperText Mar…

大数据:spark任务调度,DAGscheduler,Taskscheduler

大数据&#xff1a;spark任务调度 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其s…

SpringBoot源码分析:SpringBoot自动装配(二)

一、概述 SpringBoot的启动流程入下图所示&#xff0c;它主要分为加载主启动类和解析启动类两个部分&#xff0c;我将从这两个部分分别开始介绍。 二、加载主启动类 首先点入SpringApplication.run方法 之后进入SpringApplication.prepareContext方法 之后进入SpringApplicat…

【JavaEE】简单前后端分离小项目-表白墙

plus版表白墙&#xff01;✿✿ヽ(▽)ノ✿ 文章目录 JavaEE & 简单前后端分离小项目 - 表白墙1. body格式约定 - 应用层协议2. 后端处理请求2.1 模板2.2 doGet方法2.3 doPost方法 3. 前端制作请求并解析响应3.1 原前端页面的代码3.2 刷新时发送GET请求3.3 点击发送时构造Pos…

40 KVM管理设备-配置磁盘IO悬挂

文章目录 40 KVM管理设备-配置磁盘IO悬挂40.1 总体介绍40.1.1 概述40.1.2 应用场景40.1.3 注意事项和约束限制 40.2 磁盘IO悬挂配置40.2.1 Qemu命令行配置40.2.2 xml配置方式 40 KVM管理设备-配置磁盘IO悬挂 40.1 总体介绍 40.1.1 概述 存储故障&#xff08;比如存储断链&am…

卡尔曼滤波与组合导航原理(三)连续随机系统的离散化与连续时间Kalman滤波

文章目录 一、连续时间系统方程离散化1、连续时间模型2、状态转移矩阵计算3、激励噪声的等效计算4、最终离散化结论5、常见简单随机过程离散化6、实际物理信号的噪声单位 二、连续时间量测方程离散化三、连续时间Kalman滤波1、连续状态空间模型2、离散时间Kalman滤波3、增益矩阵…

自学网络安全解决问题方法

自学网络安全很容易学着学着就迷茫了&#xff0c;找到源头问题&#xff0c;解决它就可以了&#xff0c;所以首先咱们聊聊&#xff0c;学习网络安全方向通常会有哪些问题&#xff0c;看到后面有惊喜哦 1、打基础时间太长 学基础花费很长时间&#xff0c;光语言都有几门&#xf…

《Java并发编程实战》课程笔记(十三)

并发容器 同步容器及其注意事项 Java 中的容器主要可以分为四个大类&#xff0c;分别是 List、Map、Set 和 Queue&#xff0c;但并不是所有的 Java 容器都是线程安全的。 例如&#xff0c;我们常用的 ArrayList、HashMap 就不是线程安全的。如何将非线程安全的容器变成线程安…

java双亲委派机制详解

1. 类加载流程 类加载机制其实就是虚拟机把Class文件加载到内存&#xff0c;并对数据进行校验&#xff0c;转换解析和初始化&#xff0c;形成可以虚拟机直接使用的Java类型&#xff0c;即java.lang.Class。 1.1 装载 Class文件 -- >二进制字节流 -->类加载器 1&#x…

(0.50mm)TF31-4S-0.5SH 4 位置 FFC,FPC 连接器、G846A10221T4EU(1.0MM)矩形连接器 互连器件

TF31-4S-0.5SH &#xff08;0.50mm&#xff09;脚距前开盖式FFC/FPC连接器的安装深度为5.7mm&#xff0c;可最大限度地节省电路板空间&#xff0c;并能够自动放置电路板。Hirose Electric TF31连接器具有高FPC保持力&#xff08;采用FPC侧拉手设计&#xff09;&#xff0c;易于…

Linux下进程及其进程地址空间以及一些进程的控制函数

目录 什么是进程&#xff1f;进程的状态Linux下进程的状态 进程地址空间什么是进程地址空间为什么需要进程地址空间&#xff1f; 进程控制进程控制函数forkwait/waitpid 进程等待进程替换&#xff0c;进程替换函数exe 今天我们来分享一下Linux下的进程和进程地址空间以及一些进…

进出口跨境电商软件平台系统开发,源码技术架构

一、进出口跨境电商软件平台系统开发需做好相应的前期准备&#xff0c;如确定市场、了解政策、推广宣传等。 欢迎名片沟通探讨 确定目标市场&#xff1a;选择合适的目标市场。需要了解目标市场的消费习惯、政策法规以及竞争情况。 了解海关相关政策&#xff1a;针对不同国家或…

python之函数(参数,匿名函数,局部变量和全局变量)

文章目录 前言一、函数的参数 1、形参和实参2、必传参数&#xff08;也叫&#xff1a;必须参数&#xff09;3、关键字传参4.、默认参数5、不定长参数6、传参的顺序二、匿名函数&#xff08;lambda函数&#xff09; 1. 定义及特点语法格式2. lambda函数的特点三、函数返回值retu…