Git:“腐败的松散对象”;

每当我从我的遥控器,我得到以下关于压缩的错误。当我运行手动压缩,我得到相同的:

$ git gc
error: Could not read 3813783126d41a3200b35b6681357c213352ab31
fatal: bad tree object 3813783126d41a3200b35b6681357c213352ab31
error: failed to run repack

有人知道该怎么做吗?

从cat文件中我得到了这个:

$ git cat-file -t 3813783126d41a3200b35b6681357c213352ab31
error: unable to find 3813783126d41a3200b35b6681357c213352ab31
fatal: git cat-file 3813783126d41a3200b35b6681357c213352ab31: bad file

从git fsck中我得到了这个(不知道它是否真的相关):

$ git fsck
error: inflate: data stream error (invalid distance too far back)
error: corrupt loose object '45ba4ceb93bc812ef20a6630bb27e9e0b33a012a'
fatal: loose object 45ba4ceb93bc812ef20a6630bb27e9e0b33a012a (stored in .git/objects/45/ba4ceb93bc812ef20a6630bb27e9e0b33a012a) is corrupted

有人能帮我解读一下吗?

318618 次浏览

看起来您有一个损坏的树对象。您需要从其他人那里获取该对象。希望他们会有一个未损坏的版本。

如果您无法从其他人那里找到有效的版本,您可以通过猜测应该在那里的文件来重新构建它。你可能想看看日期&物体的次数与之匹配。这些可能是相关的斑点。您可以从这些对象推断出树对象的结构。

看看关于git内部的Scott Chacon的Git截屏。这将向您展示git在引子下是如何工作的,以及如果您真的卡住了,并且无法从其他人那里获得该对象,如何进行此侦探工作。

试一试

git stash

这对我很管用。它会隐藏你没有提交的任何东西,从而解决了问题。

在我的(Windows)机器决定重新启动后,我得到了这个错误。

谢天谢地,我的远程存储库是最新的,所以我只是做了一个新的Git克隆…

我也有同样的问题(不知道为什么)。

此修复需要访问未损坏的存储库远程副本,并将保持本地工作副本的完整性。

但它也有一些缺点:

  • 您将丢失任何未推送的提交记录,并且必须重新提交它们。
  • 你会丢失所有的钱。

修复

从repo上面的父目录执行这些命令(将'foo'替换为项目文件夹的名称):

  1. 创建损坏目录的备份 李cp -R foo foo-backup < / >
  2. 创建一个远程存储库的新克隆到一个新目录:
    git clone git@www.mydomain.de:foo foo-newclone < / >
  3. 删除损坏的。git子目录 李rm -rf foo/.git < / >
  4. 将新克隆的。git子目录移动到foo:
    mv foo-newclone/.git foo < / >
  5. 删除临时克隆的剩余部分 李rm -rf foo-newclone < / >

在Windows上,你需要使用:

  • copy代替cp -R
  • rmdir /S代替rm -rf
  • move代替mv

现在foo恢复了它原来的.git子目录,但所有的本地更改仍然在那里。git statuscommitpullpush等等,它们应该再次工作。

我也有同样的问题在我的裸远程git回购。经过大量的故障排除后,我发现我的一个同事提交了。git/objects中的一些文件的权限是440 (r—r-----),而不是444 (r—r—r—)。在让同事用“chmod 444 -R objects”在裸git repo中更改权限后,问题得到了解决。

最好的办法可能是简单地从远程存储库(即GitHub或其他)重新克隆。不幸的是,你将失去任何未推送的提交和隐藏的更改,但你的工作副本应该保持完整。

首先对本地文件进行备份。然后从你的工作树的根开始:

rm -fr .git
git init
git remote add origin [your-git-remote-url]
git fetch
git reset --mixed origin/master
git branch --set-upstream-to=origin/master master

然后根据需要提交任何更改过的文件。

运行git stash; git stash pop解决了我的问题

我遵循了这里的许多其他步骤;Linus对如何查看git树/对象并找到缺失内容的描述尤其有用。git恢复损坏的blob

但最后,对我来说,由于部分磁盘故障,我有松散/损坏的树对象,并且树对象不容易恢复/不被那个文档覆盖。

最后,我移除了冲突的objects/<ha>/<hash>,并将git unpack-objects与来自最新克隆的包文件一起使用。它能够恢复丢失的树对象。

仍然给我留下了很多悬垂的blobs,这可能是解包以前存档的东西的副作用,并在其他问题在这里中解决

user1055643的回答缺少最后一步:

rm -fr .git
git init
git remote add origin your-git-remote-url
git fetch
git reset --hard origin/master
git branch --set-upstream-to=origin/master master

我刚刚经历了这种情况——我的机器在写到Git回购时崩溃了,它被损坏了。我是这样修正的。

我首先查看有多少提交没有推送到远程回购,如下所示:

gitk &

如果你不使用这个工具,它是非常方便的——据我所知,在所有操作系统上都可用。这表明我的远程缺少两次提交。因此,我单击了指示最新远程提交的标签(通常这将是/remotes/origin/master)来获得哈希值(哈希值是40个字符长,但为了简洁起见,我在这里使用10 -这通常是有效的)。

下面就是:

14 c0fcc9b3

然后我点击下面的提交(即远程没有的第一个),并获得哈希值:

04 d44c3298

然后我使用这两个来为这次提交做一个补丁:

git diff 14c0fcc9b3 04d44c3298 > 1.patch

然后我对另一个缺失的提交也做了同样的处理,即我使用了之前提交的哈希值和提交本身的哈希值:

git diff 04d44c3298 fc1d4b0df7 > 2.patch

然后我移动到一个新的目录,从远程复制回购:

git clone git@github.com:username/repo.git

然后我将补丁文件移动到新文件夹中,并应用它们并提交它们与它们确切的提交消息(这些可以从git loggitk窗口中粘贴):

patch -p1 < 1.patch
git commit


patch -p1 < 2.patch
git commit

这为我恢复了东西(注意,对于大量的提交,可能有更快的方法来做到这一点)。然而,我很想看看损坏的回购树是否可以修复,答案是可以。使用如上所述的修复的repo,在损坏的文件夹中运行这个命令:

git fsck

你会得到这样的结果:

error: object file .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d is empty
error: unable to find ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
error: sha1 mismatch ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d

要进行修复,我将在损坏的文件夹中这样做:

rm .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
cp ../good-repo/.git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d

即删除损坏的文件,并用一个好的文件替换它。你可能要做几次。最后,会有一个点,你可以运行fsck而没有错误。你可能会在报告中出现“悬空提交”和“悬空blob”行,这是你在这个文件夹中重新创建和修改的结果,这是OK的。垃圾收集器将在适当的时候清除它们。

因此(至少在我的情况下)损坏的树并不意味着丢失未推送的提交。

我在写提交信息的时候电脑死机了。重新启动后,工作树就像我离开时一样,我能够成功提交我的更改。

然而,当我试图运行git status时,我得到

error: object file .git/objects/xx/12345 is empty
fatal: loose object xx12345 (stored in .git/objects/xx/12345 is corrupt

与大多数其他答案不同,我并没有试图恢复任何数据。我只是需要Git停止抱怨空对象文件。

概述

对象文件;是Git对您所关心的真实文件的散列表示。Git认为它应该将some/file.whatever的散列版本存储在.git/object/xx/12345中,而修复这个错误主要是要弄清楚“松散对象”是哪个文件;应该代表。

细节

可能的选择似乎是

  1. 删除空文件
  2. 将文件转换为Git可以接受的状态

方法1:删除目标文件

我尝试的第一件事就是移动object文件

mv .git/objects/xx/12345 ..

但这并没有起作用——Git开始抱怨断开的链接。关于方法二。

方法2:修复文件

Linus Torvalds写了一个很棒的如何恢复目标文件,为我解决了这个问题。这里总结了关键步骤。

$> # Find out which file the blob object refers to
$> git fsck
broken link from    tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
to    blob xx12345
missing blob xx12345


$> git ls-tree 2d926
...
10064 blob xx12345    your_file.whatever

这告诉你空对象应该是哪个文件的哈希值。现在你可以修理了。

$> git hash-object -w path/to/your_file.whatever

在这样做之后,我检查了.git/objects/xx/12345,它不再是空的,Git停止抱怨。

这里有个箱子。碰巧的是,问题是损坏文件的所有权是root而不是我们的正常用户。这是由于在有人执行了“sudo su——”之后在服务器上进行的提交造成的。

首先,用以下方法识别损坏的文件:

$> git fsck --full

你应该会收到这样的回答:

fatal: loose object 11b25a9d10b4144711bf616590e171a76a35c1f9 (stored in .git/objects/11/b25a9d10b4144711bf616590e171a76a35c1f9) is corrupt

进入损坏文件所在的文件夹,并执行以下操作:

$> ls -la

检查损坏文件的所有权。如果这是不同的,只要回到你的回购的根,并执行:

$> sudo chown -R YOURCORRECTUSER:www-data .git/

希望能有所帮助!

我也得到了一个损坏的松散对象错误。

./objects/x/x

我通过进入损坏对象的目录成功地修复了它。我看到分配给该对象的用户是我的git用户。我不知道它是如何发生的,但我在该文件上运行了chown git:git,然后它又工作了。

这可能是解决某些民族问题的潜在办法,但不是解决所有问题的必要办法。

A 垃圾收集修复了我的问题:

git gc --aggressive --prune=now

它需要一段时间才能完成,但是每个松散的对象和/或损坏的索引都是固定的。

我刚遇到过这样的问题。我的特殊问题是由系统崩溃引起的,它破坏了最近的提交(因此也破坏了主分支)。我没有强迫自己,想要重新做出承诺。在我的特殊情况下,我可以这样处理:

  1. 备份.git/: rsync -a .git/ git-bak/
  2. 检查.git/logs/HEAD,并找到具有有效提交ID的最后一行。对我来说,这是最近的第二次提交。这很好,因为我仍然有文件的工作目录版本,所以我想要的每个版本。
  3. 在那个提交处创建一个分支:git branch temp <commit-id>
  4. 对工作目录中的文件重新执行损坏的提交。
  5. git reset master temp将主分支移动到第2步中所做的新提交。
  6. git checkout master并检查它与git log是否正确。
  7. git branch -d temp
  8. git fsck --full,现在应该可以安全地删除fsck找到的任何损坏的对象。
  9. 如果看起来不错,试试推一下。如果可行,

这对我很管用。我怀疑这是一个相当常见的场景,因为最近的提交是最有可能被损坏的,但如果你在更早的时候丢失了一个,你可能仍然可以使用这样的方法,仔细使用git cherrypick.git/logs/HEAD中的reflog。

只需删除。git文件夹并重新添加。这个简单的解决方法对我很有效。

对我来说,这是因为在做git push时发生了电源故障。

这些信息是这样的:

$ git status
error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
fatal: loose object c238824eb3fb602edc2c49fccb535f9e53951c74 (stored in .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74) is corrupt
我尝试了像git fsck这样的东西,但没有帮助。 由于崩溃发生在git push期间,它显然发生在客户端重写期间,发生在服务器更新之后。我环顾四周,发现在我的例子中c2388是一个提交对象,因为它是由.git/refs中的条目引用的。所以我知道当我查看历史(通过web界面或第二个克隆)时,我将能够找到c2388 在第二个克隆中,我执行了git log -n 2 c2388来标识c2388的前身。然后我手动修改了.git/refs/heads/master.git/refs/remotes/origin/master,使其成为c2388的前身,而不是c2388。 然后我可以做git fetchgit fetch因为空对象上的冲突失败了几次。我删除了这些空对象,直到git fetch成功。

在虚拟机上工作,在我的笔记本上,电池没电了,得到这个错误;

error: object file .git/objects/ce/theRef is empty error: object .git/objects/ce/theRef is empty 文件.git/objects/ce/theRef是空的 (存储在.git/objects/ce/theRef)被损坏

我设法让回购再次工作,只有2个命令和不会失去我的工作(修改文件/未提交的更改)

find .git/objects/ -size 0 -exec rm -f {} \;
git fetch origin

之后,我运行了git status,回购很好,有我的更改(等待提交,现在就做..)。

Git版本1.9.1

请记住备份您所记得的所有更改,以防此解决方案不起作用,需要更激进的方法。

我是这样解决的: 我决定简单地将未损坏的对象文件从备份的克隆复制到原始存储库。这个方法同样有效。(顺便说一下:如果你在.git/objects/中找不到它的名字,它可能已经被[打包][包]以节省空间。)

当我遇到这个问题时,我备份了我最近的更改(因为我知道我已经更改了什么),然后删除了它在.git/location中抱怨的文件。然后我做了一个“少不再来”的动作。不过要小心,这可能不适合你。

简单地运行git prune为我修复了这个问题

当我的系统崩溃时,我遇到了这种情况。我所做的是:

(请注意,您的损坏提交将丢失,但更改将保留。你可能必须在这个过程结束时重新创建这些提交)

  • 备份代码。
  • 转到你的工作目录并删除.git文件夹。
  • 现在在另一个位置克隆遥控器,并复制其中的.git文件夹。
  • 将其粘贴到工作目录中。
  • 做你想做的事。

创建备份并将存储库克隆到一个新目录

cp -R foo foo-backup
git clone git@url:foo foo-new

(可选)如果你在不同的分支上工作,切换它。

cd foo-new
git checkout -b branch-name origin/branch-name

同步除.git目录外的更改

rsync -aP --exclude=.git foo-backup/ foo-new

当在同一个git签出中使用不同版本的不同git客户端时,通常会出现此问题。认为:

  • 命令行
  • IDE内置git
  • docker / vm容器内部
  • GIT gui工具

确保您使用创建提交的同一客户端进行推送。

我没有失去其他未推送的分支: 对破碎对象的引用应该在refs/heads/<current_branch>中。如果你去.git\logs\refs\heads\<current_branch>,你可以看到最后一次提交有完全相同的值。我将之前提交的文件复制到第一个文件中,它解决了这个问题

Felipe Pereira(上图)提供的解决方案,加上Stephan对当对象被损坏时,我所在的分支的名称的回答的评论,对我来说是有效的。

find .git/objects/ -size 0 -exec rm -f {} \;
git fetch origin
git symbolic-ref HEAD refs/heads/${BRANCH_NAME}

您不需要克隆,也不需要丢失未提交的更改。只需使用git rm -rf .git/删除。git文件夹,然后通过启动一个新的repo,设置remote和重置head来恢复git文件夹。我在这里添加了恢复已删除git文件夹的说明:

https://stackoverflow.com/a/67610397/7584643 < a href = " https://stackoverflow.com/a/67610397/7584643 " > < / >

这似乎是Dropbox或符号链接文件夹出Dropbox为我的一个问题。其他类似的服务可能也是如此。当我转到git push时,我会得到损坏的松散物体错误。对我来说,在macOS Big Sur上,修复方法只是将回购的递归副本复制到Dropbox之外的目录中。我相信这导致Dropbox为损坏的动态引用拉出实时文件。在复制之后,我立即能够正确地git push

我在一台Windows 10电脑上遇到了类似的问题,其中一个驱动器备份了我的文档文件夹,其中有我的git存储库。

查看git对象目录中的对象,我没有看到绿色的复选标记,而是该文件的蓝色同步图标。所有其他目标文件似乎都有绿色的复选标记。玩周围,尝试的东西,我尝试选择选项始终保持此文件夹在此设备上,但得到一个错误:错误0x80071129标签存在于重解析点缓冲区是无效的。

这个链接(https://answers.microsoft.com/en-us/msoffice/forum/all/error-0x80071129-the-tag-present-in-the-reparse/b8011cee-98c5-4c33-ba99-d0eec7c535a0)建议以管理员身份运行chkdsk /r /f来解决这个问题(必须重新启动计算机)。我这么做了,问题就解决了。

我以前也遇到过同样的问题。 我只是通过从.git/objects目录中删除目标文件来传递它

对于下面的错误。

$ git fsck
error: inflate: data stream error (invalid distance too far back)
error: corrupt loose object '45ba4ceb93bc812ef20a6630bb27e9e0b33a012a'
fatal: loose object 45ba4ceb93bc812ef20a6630bb27e9e0b33a012a (stored in .git/objects/45/ba4ceb93bc812ef20a6630bb27e9e0b33a012a) is corrupted

解决方案:

  1. 转到顶部目录并取消隐藏.git文件夹
  • 在windows上,你可以通过在cmd: attrib +s +h .git上运行这个命令来做到这一点
  1. 然后进入< <强> . /对象/强>文件夹

  2. 如上所述的错误消息(存储在.git/objects/45/ba4ceb93bc812ef20a6630bb27e9e0b33a012a) is corrupted中 你可以看到该对象是在名为“45”;的指针上找到的。因此,请进入目录.git/objects/45/

  3. 最后找到名为< >强ba4ceb93bc812ef20a6630bb27e9e0b33a012a < / >强的对象并删除它。

现在,您可以继续使用git statusgit add .检查您的更改并继续。

有同样的问题后,我的linux薄荷崩溃,我按下电源按钮关闭我的笔记本电脑,这就是为什么我的。git是腐败的

find .git/objects/ -empty -delete

在那之后,我得到致命错误:坏对象头。我刚刚重新初始化了我的git

git init

并从远程repo获取

git fetch

要检查git,请使用

git status

又是工作。我不会丢失局部更改,所以我可以在不重写代码的情况下提交

我有完全相同的错误和想办法拿回了我的回购,又没弄丢零钱。

我不知道这是否适用于其他人,因为腐败的原因可能是多方面的,但值得一试

我:

  • 为以防万一,对损坏的git存储库进行了多次备份
  • 从远程存储库克隆最近的推送版本
  • 从损坏的。git文件夹中复制了所有文件,除了所有与HEAD, FETCH_HEAD, ORG_HEAD等相关的文件…最重要的是refs, obj和index
  • 最终得到了一个有效的历史记录,但腐败的索引,应用了这个帖子如何解决“错误:坏索引-致命:索引文件腐败”;使用Git时的解决方案

我的存储库又开始工作了……

为了确保我没有推送任何错误,我再次从远程复制,检出我想要从恢复的存储库保存的更改,并将它们提交为新的。