为什么git子模块更新会失败并显示“fatal: remote error: upload-pack: not our ref”?

35

我有一个包含多个子模块的Git存储库。我已经尝试删除并添加有问题的子模块(scopatz的nanorc),但是在删除和重新添加后,错误仍然存在。当我将存储库克隆到新位置时,我会使用git submodule update --init --recursive自动更新,但是只对这个子模块失败...

下面是带有GIT_TRACE=2的相关命令输出:

23:01:26.918691 run-command.c:1569      run_processes_parallel: preparing to run up to 1 tasks
23:01:26.933567 run-command.c:1601      run_processes_parallel: done
23:01:26.934373 run-command.c:646       trace: run_command: git gc --auto
23:01:26.966805 git.c:344               trace: built-in: git gc --auto
23:01:26.991059 git.c:344               trace: built-in: git rev-parse --local-env-vars
23:01:27.015684 git.c:344               trace: built-in: git rev-parse --local-env-vars
23:01:27.032282 git.c:344               trace: built-in: git symbolic-ref -q HEAD
23:01:27.053948 git.c:344               trace: built-in: git config --get branch.master.remote
23:01:27.073636 git.c:344               trace: built-in: git fetch origin 151d94a8754b0a612315fc191c5373cc0055c13d
23:01:27.079657 run-command.c:646       trace: run_command: git-remote-https origin https://github.com/scopatz/nanorc.git
23:01:28.441725 run-command.c:646       trace: run_command: git rev-list --objects --stdin --not --all --quiet
23:01:28.452267 run-command.c:646       trace: run_command: git fetch-pack --stateless-rpc --stdin --lock-pack --thin https://github.com/scopatz/nanorc.git/
23:01:28.467757 git.c:344               trace: built-in: git fetch-pack --stateless-rpc --stdin --lock-pack --thin https://github.com/scopatz/nanorc.git/
fatal: remote error: upload-pack: not our ref 151d94a8754b0a612315fc191c5373cc0055c13d
fatal: The remote end hung up unexpectedly
Fetched in submodule path 'submodules/nano', but it did not contain 151d94a8754b0a612315fc191c5373cc0055c13d. Direct fetching of that commit failed.
希望这里有人可以帮忙,我现在有点迷茫。

=== 编辑:解决步骤如下 ===

cd {submodule path}
git reset --hard origin/master
cd -
git clean -n
git add {submodule path}
git commit
git submodule update --init --recursive

没有错误,太棒了。

7个回答

20
使用Git和子模块,您需要至少两个Git存储库。一个是“您”的存储库-主要的存储库,Git会将其称为超级项目。第二个Git存储库是另一个Git存储库:它没有任何特殊之处。只是您的超级项目包含以下两个部分:
  • 克隆子模块的说明。这使得您的Git在需要时运行git clone,例如在运行git submodule update --init期间。

  • 应该位于另一个Git存储库中的某个提交的原始哈希ID。在您克隆或在其他Git存储库的克隆中适当运行git fetch后,您的主存储库将使用此原始哈希ID运行git checkout hash

您的超级项目正在请求来自https://github.com/scopatz/nanorc.git可克隆的Git存储库中的哈希ID151d94a8754b0a612315fc191c5373cc0055c13d。该提交在该存储库中根本不存在,因此它也不在您进行的任何克隆中。

您知道为什么超级项目列出此提交哈希ID,即使它不存在吗?(我肯定不知道。)您无法从他们的Git获取它,因为他们没有它。这就是所有这些错误消息告诉您的内容。

你可以尝试在其他代码库(或者谷歌)中搜索151d94a8754b0a612315fc191c5373cc0055c13d(我刚用谷歌搜过了,但是搜不到)。或者,如果你并不关心特定的那个提交,你可以告诉你自己的Git超级项目去获取另一个存在的提交,这样就能拿到了。
你应该获取哪个提交?我不知道,这取决于你。请注意:超级项目中列出子模块的原始提交哈希值在每个提交中都有。你可以在超级项目中检出一些提交,可能是某个分支的尖端。然后你可以进入子模块,选择一个喜欢的提交,在子模块中使用git checkout命令(因为它是另一个Git克隆,所以你可以在那里执行任何Git命令)以检查所需的提交。然后退出子模块(返回到超级项目目录),运行git add命令处理子模块路径,并运行git commit记录新的所需哈希ID。这个新的提交现在请求相应的哈希ID。

谢谢!你帮我找到了解决方法,并在上面发布了适用于我的特定情况的步骤。仍然不知道那个哈希值是从哪里来的... - ifiht
1
我认为这通常是由于子模块更改已经进行了新的提交,然后哈希 ID 添加到主存储库并推送到远程,但意外地没有推送到自己的远程存储库所致。然后当您克隆主存储库时,您会发现此提交被遗漏了。简而言之,这是由于在不使用--recurse-submodules选项的情况下推送主存储库所导致的。 - Neal.Marlin

10
请尝试运行此命令:git submodule foreach --recursive git reset --hard

7

如果您没有完全提交和 推送 您的本地更改到子模块,则可能会发生此情况。

当我克隆带有子模块的一个仓库时,我遇到了这个错误,而原始本地仓库正常工作。问题是因为我忘记了推送子模块更改。

因此,请确保 提交并推送 所有子模块更改。


4
git submodule update --remote

那么

git commit && git push

一切都会好起来的。


1

当我试图在一个我之前创建的分支上更新子模块时,我遇到了这个问题。所以我有一个repo1 branch-x,它有一些子模块,而只有在某些子模块上创建了branch-x之后才有的。我的解决方法是循环子模块并重置分支:

cd the-main-repo-dir
foreach submodlue in submodules do {
   cd {submodule path}
   git reset --hard origin/brnach-x
   cd -
}
git submodule update --init --recursive
git push origin/branch-x

1

如果您在子模块上进行了提交

...那么一个常见的问题是您:

  • ...将该提交添加到了超级项目中,
  • 推送了超级项目,
  • 但没有推送子模块。

所以您的本地工作区一切正常,但超级项目引用了远程机器上尚不存在的子模块提交。这就是导致此消息的原因。

解决方案

git push --recurse-submodules=on-demand


0

我在 Submodules 中遇到了同样的错误。由于项目是公开的,为了解决这个问题,我用项目的 https 替换了 .git/config 中和它们各自的子模块配置中 urls 的所有值,而不是使用 ssh


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接