子模块git submodule基础知识及易踩的坑

git submodule

子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。

比如我们想抽象出一个组件库供多个项目使用

git submodule add <子模块git地址> <存放的文件名>

会生成: .gitmodules 和 子模块文件夹

  • .gitmodules 文件保存了项目 URL 与已经拉取的本地目录之间的映射,这样就能知道子模块在哪获取。如果有多个子模块,该文件中就会有多条记录。

  • 子模块文件夹只存子项目的commit id,就能指定到对于的git header上, 父项目的git并不会记录Submodule的文件变动,它是按照commitid指定Submodulegit header

    当你不在那个目录中时,Git 并不会跟踪它的内容, 而是将它看作子模块仓库中的某个具体的提交。

注意的是,这两个文件也像 .gitignore 文件一样受到(通过)版本控制。 它会和该项目的其他部分一同被拉取推送。

克隆含有子模块的项目

克隆一个含有子模块的项目时,默认会包含该子模块目录,但其中还没有任何文件,是空目录。 必须运行:

  • git submodule init 用来初始化本地配置文件

  • git submodule update 则从该项目中抓取所有数据并检出父项目中列出的合适的提交。

合成一步就是: git submodule update --init

如果还要初始化、抓取并检出任何嵌套的子模块:git submodule update --init --recursive

或者在克隆的时候加上参数: git clone --recurse-submodules

它就会自动初始化并更新仓库中的每一个子模块, 包括可能存在的嵌套子模块。

修改submodule

进入submodule目录里修改后add 、commit 、push到远程服务器,然后要回到父目录,提交submodule在父项目中的改动(submodule commit id 会更新),再push

坑:子模块的分支默认不是master,也不会切到任何branch

当我们运行 git submodule update 从子模块仓库中抓取修改时, Git 将会获得这些改动并更新子目录中的文件,但是会将子仓库留在一个称作“游离的 HEAD”的状态。 这意味着没有本地工作分支(例如 “master” )跟踪改动。 如果没有工作分支跟踪更改,也就意味着即便你将更改提交到了子模块,这些更改也很可能会在下次运行 git submodule update 时丢失。

因此,在修改前先进入子模块,然后切换到需要的分支(eg. git checkout master),然后再对子模块做修改、提交。

更新submodule (未完待续)

from : git 官方文档

1、从子模块的远端拉取上游修改

方法一:手动抓取并合并

进入到子目录中运行 git fetchgit merge( = git pull),合并上游分支来更新本地代码。

方法二:交给Git抓取更新

git submodule update --remote,Git 将会进入子模块然后抓取并更新,Git 默认会尝试更新 所有 子模块, 所以如果有很多子模块的话,你可以传递想要更新的子模块的名字。

2、从项目远端拉取上游更改

默认情况下,git pull 命令会递归地抓取子模块的更改。 然而,它不会 更新 子模块。 为了完成更新,你需要运行 git submodule update

注意,为安全起见,如果主项目提交了你刚拉取的新子模块,那么应该在 git submodule update 后面添加 --init 选项,如果子模块有嵌套的子模块,则应使用 --recursive 选项。

如果你想自动化此过程,那么可以为 git pull 命令添加 --recurse-submodules 选项(从 Git 2.14 开始)

坑 ( from: 唐巧-Git submodule的坑 )

如果你的同事更新了 submodule,然后更新了父项目中依赖的版本号。你需要在 git pull 之后,调用 git submodule update 来更新 submodule 信息。

这儿的坑在于,如果你 git pull 之后,忘记了调用 git submodule update,那么你极有可能再次把旧的 submodule 依赖信息提交上去。

如果你不慎忘记切换到 master 分支,又做了提交,可以用 cherry-pick 命令挽救。具体做法如下:

  1. git checkout master 将 HEAD 从游离状态切换到 master 分支 , 这时候,git 会报 Warning 说有一个提交没有在 branch 上,记住这个提交的 change-id(假如 change-id 为 aaaa)
  2. git cherry-pick aaaa 来将刚刚的提交作用在 master 分支上
  3. git push 将更新提交到远程版本库中

当子模块的URL改变时

# 将新的 URL 复制到本地配置中
$ git submodule sync --recursive
# 从新 URL 更新子模块
$ git submodule update --init --recursive

实谈

在实际项目中,在子项目我们的分支上做好修改后,要将分支合并到子项目仓库。同时,不要忘了主项目上的分支也要合并(毕竟我就忘了Orz)!!否则主项目保存的子项目的引用还是旧的版本,同事拉取时如果没有进入到子项目中去更新,就得不到新的代码,那么在他修改推送后很可能又将之前自己做的修改覆盖了。

以上很多内容来自官方文档。看的有点懵。但其实主要的命令就是那几条,拉取时不要忘记更新子项目,推送时不要忘记更改主项目中引用的子项目commitid。

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要更新git submodule,你可以使用以下两个命令的组合来完成: 1. 在父仓库中运行以下命令: `git submodule update --init --recursive`。将更新父仓库中的所有模块,并将它们初始化为最新的状态。 2. 进入到modules目录(模块生成的目录),然后运行以下命令:`git pull origin master`。这将从模块的远程仓库中拉取最新的代码到本地。 请注意,这两个命令分别用于更新父仓库模块,确保你在正确的目录中运行相应的命令。 引用: git submodule update --init --recursive 引用: git pull origin master<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [git submodule 如何同步更新](https://blog.csdn.net/zhiyuan_2007/article/details/124447396)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [详解git submodule HEAD detached 的问题](https://download.csdn.net/download/weixin_38621150/12923886)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值