Git:“腐败的松散物体”

每当我从我的远程拉,我得到有关压缩的以下错误。 当我运行手动压缩时,我得到了相同的结果:

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

有谁知道,该怎么办?

从猫文件我得到这个:

 $ 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 

任何人都可以帮我解密这个?

看起来你有一个腐败的树木对象。 你需要从其他人那里获得这个对象。 希望他们将有一个完整的版本。

如果你不能从其他人那里find一个有效的版本,那么你可以重新构build它,通过猜测哪些文件应该在那里。 你可能想看看对象的date和时间是否匹配。 那些可能是相关的斑点。 你可以从这些对象推断出树对象的结构。

看看Scott Chacon关于git 内幕的Git Screencast 。 这会告诉你如何git在引擎盖下工作,如果你真的被卡住,不能从其他人得到这个对象如何去做这个侦探工作。

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

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

但是它有一些缺点:

  • 你将失去任何未被推送的提交logging,并将不得不重新提交。
  • 你会失去任何的信息。

修复

从repo上面的父目录执行这些命令(用项目文件夹的名称replace“foo”):

  1. 创build损坏目录的备份:
    cp -R foo foo-backup
  2. 将远程存储库的新克隆创build到新目录:
    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等工作,他们应该再次。

您最好的select可能是简单地从远程回购(即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 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的散列版本, some/file.whatever存储在.git/object/xx/12345 ,并且修复错误主要是确定“松散对象”应该代表哪个文件。

细节

可能的select似乎是

  1. 删除空文件
  2. 把文件变成Git可以接受的状态

方法1:删除目标文件

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

 mv .git/objects/xx/12345 .. 

这不起作用 – git开始抱怨断开的链接。 方法2。

方法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停止抱怨。

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

错误:目标文件.git / objects / ce / theRef为空错误:目标文件.git / objects / ce / theRef为空致命:松散对象theRef(存储在.git / objects / ce / theRef中)损坏

我设法得到repo工作只有2个命令, 而不会失去我的工作 (修改文件/未提交的更改)

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

之后,我跑了一个git status ,回购是好的,有我的变化(等待承诺,现在就做..)。

git版本1.9.1

请记住备份所有您所记得的更改,以防万一此解决scheme无法正常工作,并需要更激进的方法。

尝试

 git stash 

这对我有效。 它存储了你没有犯下的任何事情,并且解决了这个问题。

在@ 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回购时崩溃,并且已经损坏。 我把它固定如下。

我开始看看有多less提交没有推到远程回购,因此:

 gitk & 

如果你不使用这个工具,就可以在所有的操作系​​统上使用它。 这表明我的遥控器错过了两次提交。 因此,我点击了指示最新的远程提交(通常这将是/remotes/origin/master )的标签来获得散列(散列是40个字符长,但为简洁起见,我在这里使用10 – 这通常工作)。

这里是:

14c0fcc9b3

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

04d44c3298

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

 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 

这为我恢复了一些东西(并注意到可能有更快的方法来处理大量的提交)。 不过,我很想看看腐败回购的树是否可以修复,答案是可以的。 使用上面提供的修复后的回购,在破损的文件夹中运行此命令:

 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 

即删除损坏的文件,并用一个好的replace它。 您可能需要多次这样做。 最后会有一个你可以运行fsck而没有错误的地方。 报告中可能会出现“悬挂提交”和“晃来晃去”的字样,这些都是你在这个文件夹中改版和修改的结果。 垃圾收集器将在适当的时候删除它们。

因此(至less在我的情况下)一个损坏的树并不意味着失去了提交的承诺。

我也遇到了一个腐败的松散物体错误。

 ./objects/x/x 

我通过进入损坏的对象的目录成功修复它。 我看到分配给该对象的用户不是我的git用户的。 我不知道它是怎么发生的,但是我在这个文件上运行了一个chown git:git ,然后再次运行。

这可能是一些人们的问题的一个可能的解决办法,但不是所有的人都需要。

垃圾回收解决了我的问题:

 git gc --aggressive --prune=now 

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

我的(Windows)机器决定重新启动后出现此错误。 幸运的是,我的远程回购是最新的,所以我只是做了一个新的git克隆..

我在这里跟着许多其他的步骤。 Linus关于如何查看git树/对象的描述以及find缺less的内容特别有帮助。 git-git恢复损坏的blob

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

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

还留下了很多晃来晃去的斑点,这可能是拆包以前存档的东西的副作用,并在这里解决其他问题

Runnning git stash; git stash pop git stash; git stash pop解决了我的问题

对我来说,这是由于电源故障,而做一个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在我的情况下, c2388是一个提交对象,因为它是由.git/refs条目.git/refs 。 所以我知道,当我查看历史(通过networking界面或第二个克隆)时,我将能够findc2388

在第二个克隆上,我做了一个git log -n 2 c2388来识别git log -n 2 c2388的前身。 然后我手动修改.git/refs/heads/master.git/refs/remotes/origin/master作为c2388的前身,而不是c2388 。 然后我可以做一个git fetch 。 对于空对象的冲突, git fetch失败了几次。 我删除了每个这些空的对象,直到git fetch成功。 这已经愈合了储存库。

我解决了这个问题:我决定简单地将未损坏的对象文件从备份的克隆复制到我的原始存储库。 这工作也一样。 (顺便说一句:如果你不能在.git / objects /中find它的名字,那么它可能已经[packed] [pack]来节省空间。)

我在我的远程git仓库中也遇到了同样的问题。 经过很多故障排除之后,我发现我的一个同事做了一个提交,其中.git / objects中的某些文件的权限为440(r – r —–),而不是444(r – r – r – )。 在请求同事在裸Git仓库中用“chmod 444 -R objects”更改权限后,问题就解决了。

我们刚刚在这里的情况。 它发生的问题是腐败文件的所有权是根,而不是我们的普通用户。 这是由于某人完成了“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/ 

希望它有帮助!

我只是有这样的问题。 我特别的问题是由于系统崩溃导致最近的提交(因此也是主分支)。 我没有推,并想重新作出这一承诺。 在我个人的情况下,我能够像这样对付它:

  1. 备份.git/rsync -a .git/ git-bak/
  2. 检查.git/logs/HEAD ,并find有效提交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文件夹并再次添加。 这个简单的解决scheme为我工作。