为什么 git 无法为给定的提交获取特定的有效子模块以及如何修复它?

Why does git fail to fetch specific valid submodule for a given commit and how to fix it?

我有一个 git 存储库,其中有另一个作为 submodule 依赖项。在我的项目的根目录中(.git.gitsubmodules 等所在的位置)我调用了

git submodule update

失败并显示以下消息:

Fetched in submodule path 'src/framework', but it did not contain cc8c38e9d853491c672452d8dbced4666fc73ec8. Direct fetching of that commit failed.

其中 src/framework 是我的项目 (PROJECT_ROOT/src/framework) 的子目录,应该是第三方存储库所在的位置。给定的提交哈希是有效的。

我也试过git clone --recursive <my-repo>,但也失败了。

.gitmodules的内容是

[submodule "src/framework"]
        path = src/framework
        url = git@gitlab-blah-internal.de:gh/framework.git

除此之外,我还必须注意以下重要事实:由于 framework 存储库中的最新更新,我的代码中断了,因此我真的需要检索它的特定版本,在那里一切正常。

Yes, I can follow the link in my web browser (using GitLab)

你能克隆那个 repo,包括那个提交吗?
GitLab 有 permission level 这将限制访问,因此请确保您的 git 克隆命令是使用正确的用户执行的,并使用上述 user home directory/.ssh.

中的 ssh 密钥

如果您无法自己克隆子模块存储库(在本地硬盘驱动器上的任何位置),这将解释错误消息。

The problem came from someone who has done a reset of the head to a commit prior to the one that was linked as a submodule in the repository I was working with. This rendered the reference invalid. I have no idea how to fix this

您可以make sure the submodule follows a branch(这里,例如master):

cd /path/to/parent/repo
git config -f .gitmodules submodule.bar1.branch master

然后在最后一次获取的提交处更新子模块master

git submodule update --remote

--remote option确保它将不会使用超级项目记录的 SHA-1 来更新子模块,但会使用子模块的远程跟踪分支的状态相反。

这样可以避免“did not contain cc8c38e9d853491c672452d8dbced4666fc73ec8”错误消息。


drlolly adds in :

The --remote switch was the key for me.
This worked for me:

git submodule  update --init --recursive --remote

我的问题是子模块指向托管在 github 上的个人(克隆)存储库。

我有多个包含对同一子模块的引用的主机存储库。 我已经更改了其中一个存储库中子模块的 HEAD 并提交了存储库。不幸的是,我忽略了将新的子模块 HEAD 推送到 github,因此存储库的其他实例没有最新头部的记录,即使在 git submodule update

之后

运行 克隆后的这个命令(并收到错误)解决了我的问题:

git submodule update --force --recursive --init --remote

当然这不是一个好的解决方案。最好找到并解决根本问题,但如果有人赶时间,这对我有用。

我的情况是子模块的 url 发生了变化,并且与父仓库不同步。我们注意到我们可以克隆父项,并且子项将初始化而不会失败,但是存储库的这个特定实例失败了。

修复者:

  1. 检查 url 是否在 .gitmodules 文件中是正确的
  2. 呼叫git submodule sync
  3. 调用git -C path/to/submodule fetch(如果子模块已经初始化)
  4. 调用git submodule update --init [--recursive] path/to/submodule(如果子模块已经deinit)

我不知道确切的问题是什么,但下面对我有用: (我认为第四步是关键)

  1. git 子模块更新 --init --recursive
  2. git pull --rebase --recurse-submodules
  3. git 子模块更新 --force --recursive --init --remote
  4. git 子模块同步
  5. git 子模块更新 --init --recursive

下面的命令解决了问题

  • git 子模块同步

在我的例子中,子模块的 git 配置已更新到 ssh。 我将父项目的 git 配置及其子模块更新为 http.

除此之外,我使用 window 的 Web 凭据更新了我的 git 凭据,您可以在 windows 设置中搜索它。

Manage Web Credentials in Windows

当我遇到这个错误时,它是由指向仅存在于本地的提交的子模块引用引起的。

自 2022 年 2 月以来,我开始在(github 托管的)存储库中间歇性地遇到这种情况。我从不配置或编辑子模块(构建时只需要它们)。没有更改任何 URL 或凭据。一个新的克隆遭遇同样的命运——它在更新一个随机子模块时搁浅。有时,错误之前会出现 network/server 超时。一旦子模块发生这种情况,git 会继续在同一子模块上报告相同的问题,而 Wireshark 表示它每次都会与服务器通信。 submodule sync/--init 个解决方案中的 None 个有帮助。

修复子模块 X:

  1. 删除 X 目录本身(假设您没有对它进行任何更改!)。
  2. 修复相应的目录。git/modules/X(通常)或在 .git/worktrees//modules/X 下(如果您在其他工作树中):
    • 要么完全删除 .git/modules/X(它将再次获取)
    • 或仅删除
      • .git/modules/X/浅
      • .git/modules/X/refs/remotes/origin
  3. git submodule update X

我最后只是去了:

  1. 进入子模块 repo
  2. git pull 最新
  3. 进入顶级 repo 根目录
  4. git commmit -m "updated submodule" 所以主回购是知道的。
  5. git push

之后我的问题都消失了。这也解决了我的 Netlify 问题。