推送时Git无法解决引用问题

23

我在使用Git时遇到了问题。由于未知原因,我的主分支出现了损坏。我有一个本地提交,想要进行推送,但在推送时出现以下错误:

git push origin master
error: unable to resolve reference refs/remotes/origin/master: No such file or directory
error: cannot lock the ref 'refs/remotes/origin/master'.
Everything up-to-date

我在其他论坛上看到过类似的问题,但通常是关于pull而不是push。 尽管如此,我已经尝试了他们的解决方案,但都没有成功:

  1. 尝试修改我的当前提交并推送
  2. 使用git gc --prune=now清理我的git存储库
  3. 尝试rm .git/refs/removes/origin/master

以上方法都未能解决我的问题。 有什么想法或建议吗?


1
git for-each-ref '**/master' 是什么意思?具体来说,我怀疑你有一个 refs/heads/refs/remotes/origin/master - jthill
不幸的是,似乎没有起作用:命令的第一部分(update-ref)抛出了一个错误:error: unable to resolve reference refs/remotes/origin/master: No such file or directory。有趣的是,只运行 git for-each-ref 就显示了 fatal: missing object 0000000000000000000000000 for refs/remotes/origin/HEAD。我...我失去了我的头吗? - cidthecoatrack
6
是时候采取强硬措施了。这些是远程引用,当你获取时它们会被刷新。rm -rf .git/refs/remotes/origin - jthill
没错,就我一个人。我会尝试的! - cidthecoatrack
对于未来的读者 - 如果您拥有“sudo”权限,那可能会解决您的问题(例如,“sudo git push ...”) - Peter
显示剩余5条评论
10个回答

46

(@NeTeInStEiN的简短版解释:这里使用了核选项rm -rf .git/refs/remotes/origin)

编辑:我在自己的一个仓库中遇到了部分此行为,我可以让git在不使用rm .git/refs/remotes/origin/master的情况下重现f-e-r故障:

  • 克隆一个仓库
  • 删除原始分支(它的HEAD所附属的分支)
  • 在克隆中运行git fetch --prune

抓取将产生悬空引用警告,git for-each-ref将失败并显示一个熟悉的消息:

~/sandbox/20/buddy$ git fetch --prune
From /home/jthill/sandbox/20/source/.
 x [deleted]         (none)     -> origin/master
   (refs/remotes/origin/HEAD has become dangling)
~/sandbox/20/buddy$ git f-e-r
fatal: missing object 0000000000000000000000000000000000000000 for refs/remotes/origin/HEAD

但这并没有破坏推送,我已经尝试了每个push.default设置,也没有破坏git update-ref -d

然而,在谷歌搜索推送消息时,我找到了这个:

我前几天从一次蓝屏重新启动了计算机[...] 然后执行git push。这就是我收到“无法解析参考refs/remotes/origin/master……”的投诉的时候。 [...] 所以,我打开了主文件,发现里面全是空格!这不行。为了修复它,我做了这个:[你的rm,然后git fetch]


查看上面的评论以获取详细信息,tl; dr 是,因为这些是远程引用,git fetch完全刷新了它们,并且由于损坏如此严重,以至于for-each-refgit update-ref根本无法工作,原子选项rm -rf refs/remotes/origin; git fetch保证能恢复远程引用正确。

在其他情况下,如果没有简单的方法可以恢复损坏的引用或者出于好奇心,find .git/refs/remotes/origin -type f以检查锁定文件或使用reflogs(这些文件在.git/logs中)来恢复内容会有所帮助,但在这里不是必要的。我认为我错过了一个赌注,没有先执行find,之前被kill -9命令杀死的*.lock文件在这里看起来很可能存在,但我怀疑是一个模棱两可的引用,因此f-e-r是我处理此类情况的第一步。



2
对我来说,需要额外的 rm .git/packed-refs 来解决这个错误。 - scai
一如既往,核心选项是最好的选择,对我有用! :) - Roni Antonio

7

从.git文件夹中删除以下目录 -> .git/refs/remotes/origin

这将删除所有远程分支,您需要使用 -> git fetch 再次获取它们。 这应该解决问题。


这是非常危险的操作。不建议编辑git目录。 - Arci
@Arci 是的,但那是唯一有效的方法。 - سعيد

4
  1. 只需进入您项目中的此目录,然后从项目中删除原始文件夹:

.git/refs/remotes/origin

现在只需运行以下命令:
git fetch --prune

您可以使用 git fetch --all 获取您所有的分支。

现在用以下命令 pushpull 您的代码,
这对我来说行得通。


2
注意:从Git 2.5(2015年7月)开始,git for-each-ref 在遇到“丢失对象”时会更加精确。请参见提交501cf47提交f551707(2015年6月3日)以及提交8afc493提交c3e23dc(2015年6月2日),作者为Michael Haggerty (mhagger)
(由Junio C Hamano -- gitster --提交9d71c5f,2015年6月24日合并)

for-each-ref:正确报告损坏的引用

如果存在具有无效内容的松散引用文件,“git for-each-ref”会错误地将问题报告为缺少名称为NULL_SHA1的对象:

$ echo '12345678' >.git/refs/heads/nonsense
$ git for-each-ref
fatal: missing object 0000000000000000000000000000000000000000 for refs/heads/nonsense

通过显式的“--format”字符串,它甚至可以报告引用有效地指向NULL_SHA1:
$ git for-each-ref --format='%(objectname) %(refname)'
0000000000000000000000000000000000000000 refs/heads/nonsense
$ echo $?
0

NULL_SHA1 用于表示代码中(以及其他 Git 实现的代码中)的“无效对象名称”,因此更有可能是由于软件错误而将磁盘上的引用设置为该值,而不是 NULL_SHA1 是实际对象的合法 SHA-1 值。
因此,如果松散引用具有值 NULL_SHA1,请考虑它已损坏。


1

删除 .git/refs/remotes/origin/master

运行 git fetch --prune


0

我可能晚了一天,并且少了一美元,但最近在为学校设置第一个存储库时遇到了相同的错误消息。我已经查看了上面的答案,但没有解决我的问题。解决我的问题的是:sudo git push并输入管理员密码...


0
在本地存储库的基本目录中,您将找到.git/refs/remotes/origin。在此目录中,您的分支同名文件应包含该分支最新提交的提交ID(40个字母数字字符)。如果不是这种情况,请获取您的分支的最后一个提交ID并更新文件的内容。这为我解决了问题。

0

粗糙,但对我来说是唯一有效的解决方案:

  • 将“origin”远程重命名为“另一个名称”,并使用该名称

1
你的回答可以通过提供额外的支持信息来改进。请[编辑]以添加更多详细信息,如引用或文档,以便其他人可以确认您的答案是否正确。您可以在帮助中心中找到有关撰写良好答案的更多信息。 - Community

0
警告:我是唯一使用该存储库的开发人员。我无法评论此黑客攻击对于更多用户/复杂性的存储库的影响。请先备份所有内容。
在尝试了本主题和其他主题中的所有方法后,我最终删除了位于\refs\heads\的远程服务器文件系统中的分支文件。我首先尝试了Prateek建议的从本地计算机中删除它,但没有效果。
例如: 假设我的Repo名称为“Foo”,我的分支名称为“Bar”。 在托管GIT repo的系统上打开repo目录(Foo),然后导航到文件“Foo\refs\heads\”。然后重命名(最终删除)名为Bar的分支文件。
Git将在推送操作期间重新创建分支文件。
推送后,我切换到主分支并成功合并了“Bar”分支。

0
解决这个问题的简单方法是首先检查您推送提交的Git存储库是否正在更新您的提交。如果是,则可以在本地计算机上删除克隆的存储库,然后再次克隆它。这样错误就会消失了。这对我有用!

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