如何修复 Git 错误 "object file ... is empty"?

629

当我尝试提交更改时,会出现以下错误:

error: object file .git/objects/31/65329bb680e30595f242b7c4d8406ca63eeab0 is empty
fatal: loose object 3165329bb680e30595f242b7c4d8406ca63eeab0 (stored in .git/objects/31/65329bb680e30595f242b7c4d8406ca63eeab0) is corrupt

我尝试了 git fsck,结果得到:

error: object file .git/objects/03/dfd60a4809a3ba7023cbf098eb322d08630b71 is empty
fatal: loose object 03dfd60a4809a3ba7023cbf098eb322d08630b71 (stored in .git/objects/03/dfd60a4809a3ba7023cbf098eb322d08630b71) is corrupt

我该如何解决这个错误?


3
如果此存储库存在于远程存储库中,您可以尝试将该文件从远程存储库复制到本地存储库(如果在远程存储库中存在该文件)。 - Attila Szeremi
2
当我的.git目录权限出了问题并且我没有读取权限时,我遇到了这个错误。所以在文件不为空但无法写入的情况下也可能会发生这种情况。修复权限并运行git fsck解决了这个问题。 - Jake Anderson
可能是重复的问题:如何处理损坏的git对象文件?(链接:https://dev59.com/Tm855IYBdhLWcg3w1oPa) - akostadinov
如果您在提交过程中遇到网络中断,就会出现这种情况。请按照被接受的答案步骤解决问题。 - RunningAdithya
1
一个简单的解决方案是:我将代码库克隆到另一个位置,并用新克隆的.git文件替换旧的.git文件。 - Shah Vipul
显示剩余6条评论
30个回答

1159

我遇到了类似的问题。我的笔记本在执行 Git 操作期间没电了。糟糕。

我没有任何备份。(顺便提一下,Ubuntu One 不是 Git 的备份解决方案;它会很有帮助地用你的损坏版本库覆盖你正常的版本库)

如果对于 Git 高手们来说这种修复方式不好,请留言告诉我。但是至少在我这里,它起到了作用…… 至少是暂时的。

步骤1:备份文件夹 .git(事实上,我在每个更改步骤之间都会这样做,但是会使用新的复制名称,例如 .git-old-1.git-old-2 等):

cd ~/workspace/mcmc-chapter
cp -a .git .git-old

步骤二:运行git fsck --full

git fsck --full

error: object file .git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e is empty
fatal: loose object 8b61d0135d3195966b443f6c73fb68466264c68e (stored in .git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e) is corrupt

步骤三:删除空文件。我想算了,反正里面什么也没有。

rm .git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e

rm: remove write-protected regular empty file `.git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e'? y

第三步:再次运行git fsck。继续删除空文件。您还可以进入.git目录并运行find . -type f -empty -delete -print来删除所有空文件。最终,Git开始告诉我它实际上正在处理对象目录:

git fsck --full

Checking object directories: 100% (256/256), done.
error: object file .git/objects/e0/cbccee33aea970f4887194047141f79a363636 is empty
fatal: loose object e0cbccee33aea970f4887194047141f79a363636 (stored in .git/objects/e0/cbccee33aea970f4887194047141f79a363636) is corrupt

第四步:在删除了所有空文件后,我最终执行了git fsck命令:

git fsck --full

Checking object directories: 100% (256/256), done.
error: HEAD: invalid sha1 pointer af9fc0c5939eee40f6be2ed66381d74ec2be895f
error: refs/heads/master does not point to a valid object!
error: refs/heads/master.u1conflict does not point to a valid object!
error: 0e31469d372551bb2f51a186fa32795e39f94d5c: invalid sha1 pointer in cache-tree
dangling blob 03511c9868b5dbac4ef1343956776ac508c7c2a2
missing blob 8b61d0135d3195966b443f6c73fb68466264c68e
missing blob e89896b1282fbae6cf046bf21b62dd275aaa32f4
dangling blob dd09f7f1f033632b7ef90876d6802f5b5fede79a
missing blob caab8e3d18f2b8c8947f79af7885cdeeeae192fd
missing blob e4cf65ddf80338d50ecd4abcf1caf1de3127c229

步骤 5:尝试使用git reflog命令。失败,因为我的 HEAD 损坏了。

git reflog

fatal: bad object HEAD

第六步: 使用谷歌。找到这个页面。手动获取reflog的最后两行:

tail -n 2 .git/logs/refs/heads/master

f2d4c4868ec7719317a8fce9dc18c4f2e00ede04 9f0abf890b113a287e10d56b66dbab66adc1662d Nathan VanHoudnos <nathanvan@gmail.com> 1347306977 -0400    commit: up to p. 24, including correcting spelling of my name
9f0abf890b113a287e10d56b66dbab66adc1662d af9fc0c5939eee40f6be2ed66381d74ec2be895f Nathan VanHoudnos <nathanvan@gmail.com> 1347358589 -0400    commit: fixed up to page 28

第七步:请注意,从第六步我们知道HEAD目前指向最后一个提交。因此,让我们尝试查看父提交:

git show 9f0abf890b113a287e10d56b66dbab66adc1662d

commit 9f0abf890b113a287e10d56b66dbab66adc1662d
Author: Nathan VanHoudnos <nathanvan@XXXXXX>
Date:   Mon Sep 10 15:56:17 2012 -0400

    up to p. 24, including correcting spelling of my name

diff --git a/tex/MCMC-in-IRT.tex b/tex/MCMC-in-IRT.tex
index 86e67a1..b860686 100644
--- a/tex/MCMC-in-IRT.tex
+++ b/tex/MCMC-in-IRT.tex

成功了!

第8步:现在我们需要将 HEAD 指向 9f0abf890b113a287e10d56b66dbab66adc1662d。

git update-ref HEAD 9f0abf890b113a287e10d56b66dbab66adc1662d

看看 fsck 说了什么:

git fsck --full

Checking object directories: 100% (256/256), done.
error: refs/heads/master.u1conflict does not point to a valid object!
error: 0e31469d372551bb2f51a186fa32795e39f94d5c: invalid sha1 pointer in cache-tree
dangling blob 03511c9868b5dbac4ef1343956776ac508c7c2a2
missing blob 8b61d0135d3195966b443f6c73fb68466264c68e
missing blob e89896b1282fbae6cf046bf21b62dd275aaa32f4
dangling blob dd09f7f1f033632b7ef90876d6802f5b5fede79a
missing blob caab8e3d18f2b8c8947f79af7885cdeeeae192fd
missing blob e4cf65ddf80338d50ecd4abcf1caf1de3127c229

步骤10:缓存树中的无效sha1指针似乎来自于一个现在已过时的索引文件(来源)。因此,我将其删除并重置了仓库。

rm .git/index
git reset

Unstaged changes after reset:
M    tex/MCMC-in-IRT.tex
M    tex/recipe-example/build-example-plots.R
M    tex/recipe-example/build-failure-plots.R

第11步:再次查看fsck...

git fsck --full

Checking object directories: 100% (256/256), done.
error: refs/heads/master.u1conflict does not point to a valid object!
dangling blob 03511c9868b5dbac4ef1343956776ac508c7c2a2
dangling blob dd09f7f1f033632b7ef90876d6802f5b5fede79a

悬空的blob不是错误。我不担心master.u1conflict,现在它已经工作了,我不想再碰它了!

步骤12:追赶我的本地编辑:

git status

# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#    modified:   tex/MCMC-in-IRT.tex
#    modified:   tex/recipe-example/build-example-plots.R
#    modified:   tex/recipe-example/build-failure-plots.R
#
< ... snip ... >
no changes added to commit (use "git add" and/or "git commit -a")


git commit -a -m "recovering from the git fiasco"

[master 7922876] recovering from the git fiasco
 3 files changed, 12 insertions(+), 94 deletions(-)

git add tex/sept2012_code/example-code-testing.R
git commit -a -m "adding in the example code"

[master 385c023] adding in the example code
 1 file changed, 331 insertions(+)
 create mode 100644 tex/sept2012_code/example-code-testing.R

1
哎呀,我的笔记本在进行git操作时死机了(SparkleShare试图在死机时提交我的笔记),之后仓库就以这种方式损坏了。我按照你的步骤一直做到第6步,但似乎最后几次提交实际上应该是我删除的空对象文件的一部分?事实上,最后3次提交基本上都是完全错误的,所以我想我无能为力了。幸运的是,我实际上并不需要来自SparkleShare的单独提交,我只需将脏文件从一台机器复制到另一台机器并合并即可。 - Ibrahim
4
谢谢,我学到了关于Git一些功能的知识,同时在重要的提交中也避免了出错!巧合的是,这也是因为电脑电量低导致的。 - HarbyUK
2
我们能否给这个人一个诺贝尔奖或者其他什么奖项?当我的可移动设备意外拔出时,我搞砸了一切,但是我很惊喜地发现我能够用这个方法清理干净。你太棒了! - David
1
如果在第11步(对于git fsck --name-object)之后错误仍然存在,例如git broken link from tree 61d013* to blob,可能需要按照https://dev59.com/XWfWa4cB1Zd3GeqPfUV1#11959590上的说明进行操作-这解决了我的问题。 - strpeter
1
步骤三中的危险操作 => 查找 . -type f -empty -delete -print Angular 项目需要一些空的 .css 文件才能正常工作。 - Gary Liao
显示剩余17条评论

463

Git对象文件已经损坏(正如其他答案所指出的那样)。这可能会发生在机器崩溃等情况下。

我也遇到了同样的问题。在阅读了其他顶部答案后,我找到了使用以下命令快速修复破损的Git存储库的方法(在包含.git文件夹的Git工作目录中执行):

(务必先备份您的Git存储库文件夹!)

find .git/objects/ -type f -empty | xargs rm
git fetch -p
git fsck --full

这将首先删除任何导致存储库损坏的空对象文件,然后从远程库中获取丢失的对象(以及最新更改),接着进行完整的对象存储检查。此时,应该可以成功地完成检查(尽管仍可能会有一些警告!)

PS. 此回答假设您在某个地方拥有您的Git存储库的远程副本(例如在GitHub上),而出问题的存储库是与仍然完好无损的远程存储库相关联的本地存储库。如果不是这种情况,请勿按照我推荐的方式修复。


3
谢谢您,我经常将代码推送到远端分支,您的解决方案让我受益匪浅。在尝试@mCorr的方法之后,我提交了新文件,但是仓库回滚并再次出现问题。我采用这种方法解决了它。 - mr_than
29
在关闭一个包含 Git 仓库的虚拟机后,我遇到了这个问题。这个解决方案完美地解决了我的问题。 - Giscard Biamby
2
谢谢Martin,这是一个非常出色且紧凑的解决方案。虽然我可能会将PS放在第一位,并用粗体警告来防止天真的用户在本地设置上尝试相同的操作。 像Giscard一样,当我关闭VM时也会遇到这个问题...如果我找到比每次都这样做更持久的解决方案,我会更新的。 - thclark
6
一台虚拟机也曾使我的本地Git存储库出现了这种情况,我可以证实这个解决方案在这种情况下是100%有效的。 - Amin.T
10
这种修复比其他方法更快。谢谢。 - Anton Perera
显示剩余12条评论

61

当我提交代码时,电脑卡住了,就会出现这个错误。

以下是我如何解决它的步骤。


解决步骤

git status

展示空/损坏的对象文件

rm .git/objects/08/3834cb34d155e67a8930604d57d3d302d7ec12

删除它

git status

我看到了 fatal: bad object HEAD 的错误信息。

rm .git/index

我将重置操作中的 index 删除。

git reset

致命错误:无法解析对象“HEAD”。

git status
git pull

只是为了检查正在发生的事情

tail -n 2 .git/logs/refs/heads/MY-CURRENT-BRANCH

它打印日志分支的最后两行tail -n 2,以显示我的最后两个提交哈希值

git update-ref HEAD 7221fa02cb627470db163826da4265609aba47b2

我选择最后一个提交哈希值

git status

它显示我所有的文件都被标记为已删除,因为我删除了.git/index文件。

git reset

继续进行重置

git status

验证我的修复


老兄,你就是那个人。救了我的一天。非常感谢你! - Michael Pacheco
我实际上是在 git status 中遇到了错误。 - Bex T.

37

我解决了这个问题,删除了各种空文件,这些文件是由 git fsck 检测到的,然后运行了一个简单的Git pull。

我发现令人失望的是,即使文件系统实现了日志记录和其他“事务性”技术来保持文件系统的健康状态,由于断电或设备空间不足,Git 也可能处于损坏状态(并且无法自行恢复)。


3
我相信上面那个答案在技术上更好,但在第6步就停止工作了,并且在技术上远高于我的水平。更为简单的方法是进行git pull。 - mblackwell8
2
我遇到了这样一种情况,在执行Nathan答案中的1-11步骤后(非常有效!),我遇到了一个错误,说refs/origin/master和refs/origin/head未定义(或类似的内容)。git pull解决了这个问题。所以我认为这两个解决方案可以一起使用。 - bchurchill
2
我知道通常使用的文件系统只记录元数据。你可以为数据打开日志记录,但我猜这不是默认设置,因为会增加开销。这可能就是为什么文件为空的原因。文件系统通常按文件事务进行观察,而Git每个事务涉及多个文件的修改。因此,即使文件系统保持每个文件的一致性,如果Git没有保持一致性,那么我猜Git将导致不一致的状态。 - Chang Hyun Park
这个答案对我有用,其他的太复杂了。 - ldog
1
比被接受的答案更快的解决方案。对于所有滚动到这里的人,如果你着急的话可以遵循这个答案。 - Sri Harsha Kappala

12

我之前遇到了同样的问题:在拉取远程仓库后,当我执行 git status 命令时,出现以下错误信息:

"error: object file (...) is empty"
"fatal: loose object (...) is corrupted"

我的解决方法如下:

  1. git stash
  2. 删除出错的Git文件(我不确定这一步是否必要)
  3. git stash clear

我不知道具体发生了什么事情,但是这些操作似乎让一切变得清晰了。


4
我喜欢简单的答案 :) 在这里的第2步,我使用了@Nathan VanHoudnos回答中提供的命令:cd .git/ && find . -type f -empty -delete - mopo922

10

我在虚拟机中经常遇到这个问题。

对我来说,以下方法有效:

cd /path/to/your/project
rm -rf .git

如果你想节省一些下载时间-请进入文件浏览器,删除已提交的文件夹中所有文件,只保留/vendor/node_modules文件夹(我使用PHP Composernpm)。

然后创建一个新的仓库:

git init

添加您的远程

git remote add origin ssh://git@github.com/YourUsername/repoName.git

获取分支/全部内容

git fetch origin somebranch

并检查它

git checkout somebranch

然后您应该在错误之前的位置。

8
因为我经常需要定期重启我的虚拟机,所以这个问题经常发生在我身上。几次后,我意识到每次出现这种情况都不能重复Nathan Vanhoudnos所描述的过程,尽管它总是有效的。然后我想出了以下更快的解决方案。 步骤1 将整个存储库移动到另一个文件夹中。
mv current_repository temp_repository

第二步

再次从源代码库克隆存储库。

git clone source_to_current_repository.git

步骤 3

除了 .git 文件夹外,删除新存储库下的所有内容

步骤 4

temp_repository 移动所有内容到新存储库,不包括 .git 文件夹。

步骤 5

删除 temp_repository,完成操作。

几次后,相信您可以很快地完成这些步骤。


4
或者不要移动您当前的存储库,1)创建一个新的克隆git clone source_to_current_repo.git clean_repo,2)备份旧的.git文件夹,3)复制干净的.git文件夹。 - moi
你说得对。我已经完成了。稍后会编辑答案。 - haoqiang
@haoqiang:你写道“由于我必须经常重启虚拟机,所以这个问题经常发生。”我们也有同样的经历。你在根本原因上是否取得了一些进展 - 是否通过更改虚拟机设置来减少问题发生的频率? - hansfn

6
  1. 将您的应用程序文件夹移动以进行备份,即使用 mv 命令将 app_folder 文件夹重命名为 app_folder_bk (类似于 git stash)。
  2. git clone 您的代码库
  3. 最后,打开一个合并工具(我在 Linux 上使用 Meld 差异查看器,在 Windows 上使用 WinMerge),并将右侧(app_folder_bk )的更改复制到左侧(新的app_folder )中(类似于 git stash apply)。

就是这样。也许这不是最好的方法,但我认为它非常实用。


1
当您将所有本地更改推送到上游或更改很小,因此克隆比恢复更快时,这是您应该执行的操作。 - Anshul Goyal

5
在一个脚本中
#! /bin/sh

# Save Git data
cp -r .git gitold

# Remove all empty Git object files
find .git -type f -empty -delete -print

# Get the current branch name
branchname=$(git branch --show-current)

# Get the latest commit hash
commit=$(tail -2 .git/logs/refs/heads/$branchname | awk '{ print $2 }' | tr -d '[:space:]')

# Set HEAD to this latest commit
git update-ref HEAD $commit

# Pull the latest changes on the current branch (considering remote is origin)
git pull origin $branchname

echo "If everything looks fine you remove the git backup running :\n\
      $ rm -rf gitold \n\
Otherwise restore it with: \n\
      $ rm -rf .git; mv gitold .git"

尽管第五个命令抛出了一个错误(fatal: 1390b51e0218e3b2bf87df572410533c368871fe985807939acae90b65dc5d53cec4225477bd2c3a: not a valid SHA1),但这解决了我的问题! - Philipp Honsel

4

让我们来简化……只有您将源代码上传至远程Git存储库的情况

  1. Backup your .git folder

  2. Check your Git repository

     git fsck --full
    
  3. Remove empty object files (all)

     rm .git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e
    
  4. Check your Git repository again.

     git fsck --full
    
  5. Pull your source from the remote Git repository

     git pull origin master
    

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