首页 > 其他分享 >git 子模块使用方法

git 子模块使用方法

时间:2024-04-22 23:13:02浏览次数:23  
标签:submodule sub -- xsuns git 模块 方法

git 子模块使用方法

目录

什么情况下使用子模块

如果想要在开发的项目中引入另外一个项目。那么除了直接将项目文件复制到主仓库目录下以外,还可以选择一种更优雅的方式,即本文所述的git子模块。这种方式可以将引入项目按照其本身的仓库状态进行管理。当引入项目有变更,不管是修复bug,还是更新功能,都可以方便的将其变更拉取到本地仓库中。

添加新的子模块

首先需要在主仓库中执行添加指令:

$ git submodule add https://github.com/Xsuns/xsuns_git_submodule_sub.git

拉取完毕后,主仓库将出现.gitmodules文件和子仓库的目录(直接存入index中)。

$ git diff --cached 
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..13fa722
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "xsuns_git_submodule_sub"]
+       path = xsuns_git_submodule_sub
+       url = https://github.com/Xsuns/xsuns_git_submodule_sub.git
diff --git a/xsuns_git_submodule_sub b/xsuns_git_submodule_sub
new file mode 160000
index 0000000..ba5bf6d
--- /dev/null
+++ b/xsuns_git_submodule_sub
@@ -0,0 +1 @@
+Subproject commit ba5bf6dad82173cded0d4fafe5e72c4a1643f611

其中记录的三行分别为子仓库的名称、本地目录和拉取地址,例子中的名称就是xsuns_git_submodule_sub, 本地目录就是主仓库根目录下的./xsuns_git_submodule_sub

提交更改后,就完成了子模块的添加。

$ git commit -am '新增:增加子模块'
[main 2896730] 新增:增加子模块
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 xsuns_git_submodule_sub
$ git log -1
commit 28967303375194f32c92122b3e7e43dff2441d67 (HEAD -> main)
Author: Xsuns <[email protected]>
Date:   Mon Apr 22 20:10:58 2024 +0800

    新增:增加子模块

克隆含有子模块的仓库

对于含有子模块的仓库,需要使用递归克隆命令。

$ git clone --recurse-submodules https://github.com/Xsuns/xsuns_git_submodule_main.git
Cloning into 'xsuns_git_submodule_main'...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 0), reused 6 (delta 0), pack-reused 0
Receiving objects: 100% (6/6), done.
Submodule 'xsuns_git_submodule_sub' (https://github.com/Xsuns/xsuns_git_submodule_sub.git) registered for path 'xsuns_git_submodule_sub'
Cloning into 'xsuns_git_submodule_sub' ...
remote: Enumerating objects: 6, done.        
remote: Counting objects: 100% (6/6), done.        
remote: Compressing objects: 100% (2/2), done.        
remote: Total 6 (delta 0), reused 6 (delta 0), pack-reused 0        
Receiving objects: 100% (6/6), done.
Submodule path 'xsuns_git_submodule_sub': checked out 'ba5bf6dad82173cded0d4fafe5e72c4a1643f611'

如果忘记了,也无需删除原仓库,直接使用指令就可以递归更新。

ps. --recursive 可以递归更新子模块中嵌套的子模块,如果不使用此选项,会导致仅更新直接关联的子模块。

$ git submodule update --init --recursive
Submodule 'xsuns_git_submodule_sub' (https://github.com/Xsuns/xsuns_git_submodule_sub.git) registered for path 'xsuns_git_submodule_sub'
Cloning into 'xsuns_git_submodule_sub' ...
Submodule path 'xsuns_git_submodule_sub': checked out 'ba5bf6dad82173cded0d4fafe5e72c4a1643f611'

主仓库更新子模块

如果只想要同步子模块默认的最新分支,那么只需要以下指令即可。

ps. 如果想要更改默认子模块远程分支,可以在.gitmodule中子模块对应位置增加branch = target

$ git submodule update --remote
Submodule path 'xsuns_git_submodule_sub': checked out 'ed54345e540890f5ebd258327757de805f5e028c'
$ git diff --submodule
Submodule xsuns_git_submodule_sub ba5bf6d..ed54345:
  > 修改:readme文档标题错误

同样地,如果要将子模块变更保存到主仓库中,需要在主仓库进行提交。

$ git commit -am '新增:更新子模块'
[main c057e0e] 新增:更新子模块
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git log -p --submodule -1
commit c057e0e5dea6e369801c2fce168c62438a9e7c69 (HEAD -> main)
Author: Xsuns <[email protected]>
Date:   Mon Apr 22 20:50:13 2024 +0800

    新增:更新子模块

Submodule xsuns_git_submodule_sub ba5bf6d..ed54345:
  > 修改:readme文档标题错误

如果你想更加自由,也可以进入子模块的目录中运行git fetchgit merge进行拉取。

拉取更新了子模块的主仓库

对于主仓库的协作者,当主仓库更新了子模块,仅仅使用git pull是不够的,它仅能修改主仓库中记录的子仓库版本,不能自动检出对应的版本。

$ git pull
Updating 2896730..c057e0e
Fast-forward
 xsuns_git_submodule_sub | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git status
On branch main
Your branch is up to date with 'origin/main'.

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:   xsuns_git_submodule_sub (new commits)

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

因此还需要如下指令。

$ git submodule update --init --recursive 
Submodule path 'xsuns_git_submodule_sub': checked out 'ed54345e540890f5ebd258327757de805f5e028c'

ps. init可以在主仓库增加了新的子模块时自动初始化并拉取,recursive则可以更新子模块的嵌套子模块。

还有一种特殊情况是,主仓库.gitmodules中子模块的url发生了改变,你需要更新主仓库引用,可以在git submodule update调用同步指令。

$ git submodule sync --recursive
Synchronizing submodule url for 'xsuns_git_submodule_sub'
$ git submodule update --init --recursive

ps. 同样地,如果你在本地修改了.gitmodules中的url,也要执行此同步指令

在子模块上工作

个人经验来说,不建议在开发主仓库的过程中,同步对子模块进行修改,特别是来自第三方的库。因为本地子模块改动如果无法推送到子模块仓库,会导致其他人拉取主仓库时无法拉取到子模块的修改。这时唯一的解决办法就只有对子模块仓库进行fork,并修改子模块urlfork后的仓库,然后去维护此仓库。

但如果你一定要这样做,首先你需要进入子仓库中检出一个工作分支,因为在前几个章节的操作后,子模块将属于游离态,不属于任何分支。

$ git status
HEAD detached at ed54345
nothing to commit, working tree clean
$ git checkout main 
Switched to branch 'main'

后续对子模块进行更新,需要加上选项--merge或者--rebase,如果忘记的话,子模块会重新变为游离态,此时只要在子模块目录下再次检出工作分支进行手动merge或者rebase即可。

$ git submodule update --remote --merge
Updating ba5bf6d..ed54345
Fast-forward
 readme.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Submodule path 'xsuns_git_submodule_sub': merged in 'ed54345e540890f5ebd258327757de805f5e028c'

如果你有权限将子模块推送到对应仓库,你可以在子模块目录下直接进行推送,然后在推送主仓库时使用选项--recurse-submodules,将其设置为check,这样主仓库推送时会进行检查,在子仓库改动未推送时推送失败。

$ git push --recurse-submodules=check
The following submodule paths contain changes that can
not be found on any remote:
  xsuns_git_submodule_sub

Please try

        git push --recurse-submodules=on-demand

or cd to the path and use

        git push

to push them to a remote.

fatal: Aborting.

推送失败的提示中也有提到将选项--recurse-submodules设置为on-demandgit将自动尝试推送子模块。

$ git push --recurse-submodules=on-demand 
Pushing submodule 'xsuns_git_submodule_sub'
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 301 bytes | 301.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/Xsuns/xsuns_git_submodule_sub.git
   ed54345..2631874  main -> main
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 32 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 271 bytes | 271.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/Xsuns/xsuns_git_submodule_main.git
   c057e0e..6718be9  main -> main

如果你在本地修改了子模块,远程主仓库的子模块也被人修改了,即子模块历史出现分叉。此时git pull拉取主仓库时将无法顺利合并.

$ git pull --recurse-submodules 
Fetching submodule xsuns_git_submodule_sub
Failed to merge submodule xsuns_git_submodule_sub
CONFLICT (submodule): Merge conflict in xsuns_git_submodule_sub
Automatic merge failed; fix conflicts and then commit the result.
$ git diff
diff --cc xsuns_git_submodule_sub
index 7ab5f6c,9670894..0000000
--- a/xsuns_git_submodule_sub
+++ b/xsuns_git_submodule_sub

这时就需要进入子仓库去进行手动合并,首先要根据第二个SHA1创建一个新的分支去合并。

$ cd xsuns_git_submodule_sub
$ git branch try-merge 9670894
$ git merge try-merge 
Auto-merging readme.md
CONFLICT (content): Merge conflict in readme.md
Automatic merge failed; fix conflicts and then commit the result.

此时得到了一个一般的合并冲突,然后就按照常规方式解决即可

$ git commit -am '合并:保留所有更改'
[main b342081] 合并:保留所有更改

$ cd ..

$ git diff
diff --cc xsuns_git_submodule_sub
index 7ab5f6c,9670894..0000000
--- a/xsuns_git_submodule_sub
+++ b/xsuns_git_submodule_sub
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit 7ab5f6cd6823c28650eb6f4c50c0d41686ba6f7e
 -Subproject commit 96708949bbc90b7b721880546ac6e82d500ac80a
++Subproject commit b342081a9666aab88e3141c115bb79c1894446b9

$ git commit -am '合并:上游更改'
[main 7385bba] 合并:上游更改

参考来源

[1] Scott Chacon, Ben Straub. Pro Git Book 2nd Edition

[2] 主仓库

[3] 子模块仓库

标签:submodule,sub,--,xsuns,git,模块,方法
From: https://www.cnblogs.com/xsuns/p/18151780

相关文章

  • Virtuoso绘制模拟模块Frame并导出LEF
    数模混合Flow时一些pin多的模拟模块可以通过导出lib和LEF,合并到数字flow中进行自动布线。第一步肯定是和后端那边确定macro的形状以及各个端口的出pin方向和metallayer。这些确认完了之后,就可以开始做lef了。网络上的教程交的是用abstract做,但实际上这是个很老旧的软件了,现在vi......
  • 最近对接通联支付第三方平台,支付成功后要回调方法告知支付是否成功,通知url必须为直接
    最近公司要做PC端,微信小程序端支付,对接的第三方是通联支付,因为需要用到回调方法,所以想到了natapp内网穿透的方法给通联支付提供回调的地址访问我本机项目第一步:打开natapp,注册账号https://natapp.cn/新手的话,需要购买免费隧道,不用花钱 我几年前已经申请账号也购买免费......
  • [ctfhub] git 泄漏
    题目描述当前大量开发人员使用git进行版本控制,对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。请尝试使用BugScanTeam的GitHack完成本题实验环境这里使用的是Ubuntu22.04.4LTS的环境sudoaptinstallgitsudoaptinstallp......
  • 配置Hexo的GitHub Actions自动推送
    还在用hexod来推送你的Blog到Github上吗?本文教您如何使用GithubActions自动推送!生成公私钥对首先,你需要准备一个ssh的公私钥匙对。你可以使用本地的ssh-keygen也可以使用在线网站,例如https://8gwifi.org/sshfunctions.jsp这样的公私钥生成器。生成完后,保存下你的公私钥(分......
  • CTFshow-Web入门模块-命令执行
    CTFshow-Web入门模块-命令执行by故人叹、web29考察点:php命令执行、正则匹配绕过题目源码:error_reporting(0);if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/flag/i",$c)){eval($c);}}else{highlight_file(__FILE__);......
  • 记录如何用php做一个网站访问计数器的方法
    简介创建一个简单的网站访问计数器涉及到几个步骤,包括创建一个用于存储访问次数的文件或数据库表,以及编写PHP脚本来增加计数和显示当前的访问次数。方法以下是使用文件存储访问次数的基本步骤:创建一个文本文件来存储计数:在网站的根目录下创建一个名为counter.txt的文件,这个文......
  • 有效防止u盘泄密的方法,u盘防泄密软件推荐
    在数字化办公环境中,U盘等移动存储设备的方便性使得它们成为了敏感数据泄漏的潜在途径。为了有效防止U盘泄密,企业应采取一系列综合性措施,并可以考虑引入专门的U盘防泄密软件。以下是一些推荐的方法和软件:1.分类管理与专盘专用:企业应将内部U盘按部门分类,实行专盘专用原则,以此来限......
  • Python实现下载文件的三种方法
    下面来看看三种方法是如何来下载zip文件的:方法一: importurllibprint"downloadingwithurllib"url='http://www.jb51.net//test/demo.zip'urllib.urlretrieve(url,"demo.zip") 方法二: importurllib2print"downloadingwithurllib2"u......
  • JTCR-模块-14
    JDK9引入了模块,用于描述代码之间的关系和依赖,控制某模块是否可以被其他模块访问。模块基础一个模块由一组包和资源组成。模块定义在名为module-info.java的文件中,javac将这个文件编译成类文件,称为moduledescriptor。该文件仅能包含一个模块定义。模块定义的一般形式为://......
  • 都2024年了,你还不知道git worktree么?
    三年前python大佬吉多·范罗苏姆(为Python程序设计语言的最初设计者及主要架构师)才知道gitworktree,我现在才知道,我觉得没啥丢人的。应用场景如果你正在feature的分支中开发新功能,线上版本紧急错误又需要你基于master做修复。可能有如下几种办法解决:解法1将本......