Git:“损坏的松散物体”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4254389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git: "Corrupt loose object"
提问by asgerhallas
Whenever I pull from my remote, I get the following error about compression. When I run the manual compression, I get the same:
每当我从遥控器拉出时,我都会收到以下有关压缩的错误。当我运行手动压缩时,我得到相同的结果:
$ git gc
error: Could not read 3813783126d41a3200b35b6681357c213352ab31
fatal: bad tree object 3813783126d41a3200b35b6681357c213352ab31
error: failed to run repack
Does anyone know, what to do about that?
有谁知道,该怎么办?
From cat-file I get this:
从 cat-file 我得到这个:
$ git cat-file -t 3813783126d41a3200b35b6681357c213352ab31
error: unable to find 3813783126d41a3200b35b6681357c213352ab31
fatal: git cat-file 3813783126d41a3200b35b6681357c213352ab31: bad file
And from git fsck I get this ( don't know if it's actually related):
从 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
Can anyone help me decipher this?
谁能帮我破译这个?
采纳答案by Adam Dymitruk
Looks like you have a corrupt tree object. You will need to get that object from someone else. Hopefully they will have an uncorrupted version.
看起来你有一个损坏的树对象。您需要从其他人那里获取该对象。希望他们会有一个未损坏的版本。
You could actually reconstruct it if you can't find a valid version from someone else by guessing at what files should be there. You may want to see if the dates & times of the objects match up to it. Those could be the related blobs. You could infer the structure of the tree object from those objects.
如果您无法通过猜测应该在那里的文件来从其他人那里找到有效版本,您实际上可以重建它。您可能想查看对象的日期和时间是否与其匹配。这些可能是相关的斑点。您可以从这些对象推断出树对象的结构。
Take a look at Scott Chacon's Git Screencastsregarding git internals. This will show you how git works under the hood and how to go about doing this detective work if you are really stuck and can't get that object from someone else.
看看Scott Chacon 的关于 git 内部结构的 Git Screencasts。这将向您展示 git 在底层是如何工作的,以及如果您真的陷入困境并且无法从其他人那里获得该对象,如何进行这项侦探工作。
回答by cubic lettuce
I had the same problem (don't know why).
我有同样的问题(不知道为什么)。
This fix requires access to an uncorrupted remote copy of the repository, and will keep your locally working copy intact.
此修复需要访问未损坏的存储库远程副本,并将保持本地工作副本完整无缺。
But it has some drawbacks:
但它有一些缺点:
- You will lose the record of any commits that were not pushed, and will have to recommit them.
- You will lose any stashes.
- 您将丢失任何未推送的提交记录,并且必须重新提交它们。
- 您将丢失任何藏品。
The fix
修复
Execute these commands from the parent directory above your repo (replace 'foo' with the name of your project folder):
从存储库上方的父目录执行这些命令(将“foo”替换为项目文件夹的名称):
- Create a backup of the corrupt directory:
cp -R foo foo-backup
- Make a new clone of the remote repository to a new directory:
git clone [email protected]:foo foo-newclone
- Delete the corrupt .git subdirectory:
rm -rf foo/.git
- Move the newly cloned .git subdirectory into foo:
mv foo-newclone/.git foo
- Delete the rest of the temporary new clone:
rm -rf foo-newclone
- 创建损坏目录的备份:
cp -R foo foo-backup
- 将远程存储库的新克隆复制到新目录:
git clone [email protected]:foo foo-newclone
- 删除损坏的 .git 子目录:
rm -rf foo/.git
- 将新克隆的 .git 子目录移动到 foo 中:
mv foo-newclone/.git foo
- 删除其余的临时新克隆:
rm -rf foo-newclone
On Windows you will need to use:
在 Windows 上,您需要使用:
copy
instead ofcp -R
rmdir /S
instead ofrm -rf
move
instead ofmv
copy
代替cp -R
rmdir /S
代替rm -rf
move
代替mv
Now foo has its original .git
subdirectory back, but all the local changes are still there. git status
, commit
, pull
, push
, etc. work again as they should.
现在 foo.git
恢复了其原始子目录,但所有本地更改仍然存在。git status
、commit
、pull
、push
等再次正常工作。
回答by user1055643
Your best bet is probably to simply re-clone from the remote repo (ie. Github or other). Unfortunately you will lose any unpushed commits and stashed changes, however your working copy should remain intact.
您最好的选择可能是简单地从远程存储库(即 Github 或其他)重新克隆。不幸的是,您将丢失任何未推送的提交和隐藏的更改,但是您的工作副本应该保持完整。
First make a backup copy of your local files. Then do this from the root of your working tree:
首先制作本地文件的备份副本。然后从工作树的根执行此操作:
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
Then commit any changed files as necessary.
然后根据需要提交任何更改的文件。
回答by Felipe Pereira
Working on a VM, in my notebook, battery died, got this error;
在虚拟机上工作,在我的笔记本中,电池没电了,出现这个错误;
error: object file .git/objects/ce/theRef is empty error: object file .git/objects/ce/theRef is empty fatal: loose object theRef (stored in .git/objects/ce/theRef) is corrupt
错误:对象文件 .git/objects/ce/theRef 为空 错误:对象文件 .git/objects/ce/theRef 为空 致命:松散对象 theRef(存储在 .git/objects/ce/theRef 中)已损坏
I managed to get the repo working again with only 2 commands and without losing my work(modified files/uncommitted changes)
我设法让 repo 只用 2 个命令再次工作,而不会丢失我的工作(修改过的文件/未提交的更改)
find .git/objects/ -size 0 -exec rm -f {} \;
git fetch origin
After that I ran a git status
, the repo was fine and there were my changes (waiting to be committed, do it now..).
之后我运行了一个git status
,repo 很好并且有我的更改(等待提交,现在做..)。
git version 1.9.1
版本 1.9.1
Remember to backup all changes you remember, just in case this solution doesn't works and a more radical approach is needed.
请记住备份您记得的所有更改,以防万一此解决方案不起作用并且需要更激进的方法。
回答by declan
My computer crashed while I was writing a commit message. After rebooting, the working tree was as I had left it and I was able to successfully commit my changes.
我在写提交信息时我的电脑崩溃了。重新启动后,工作树和我离开时一样,我能够成功提交我的更改。
However, when I tried to run git status
I got
但是,当我尝试跑步时,git status
我得到了
error: object file .git/objects/xx/12345 is empty
fatal: loose object xx12345 (stored in .git/objects/xx/12345 is corrupt
Unlike most of the other answers, I wasn't trying to recover any data. I just needed Git to stop complaining about the empty object file.
与大多数其他答案不同,我并没有试图恢复任何数据。我只需要 Git 停止抱怨空的目标文件。
Overview
概述
The "object file" is git's hashed representation of a real file that you care about. Git thinks it should have a hashed version of some/file.whatever
stored in .git/object/xx/12345
, and fixing the error turned out to be mostly a matter of figuring out which file the "loose object" was supposed to represent.
“目标文件”是您关心的真实文件的 git 散列表示。Git 认为它应该有一个散列版本的some/file.whatever
存储在 中.git/object/xx/12345
,并且修复错误主要是弄清楚“松散对象”应该代表哪个文件。
Details
细节
Possible options seemed to be
可能的选择似乎是
- Delete the empty file
- Get the file into a state acceptable to Git
- 删除空文件
- 使文件进入 Git 可接受的状态
Approach 1: Remove the object file
方法一:删除目标文件
The first thing I tried was just moving the object file
我尝试的第一件事就是移动目标文件
mv .git/objects/xx/12345 ..
That didn't work - git began complaining about a broken link. On to Approach 2.
那没有用 - git 开始抱怨链接断开了。进入方法 2。
Approach 2: Fix the file
方法二:修复文件
Linus Torvalds has a great writeup of how to recover an object filethat solved the problem for me. Key steps are summarized here.
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
This tells you what file the empty object is supposed to be a hash of. Now you can repair it.
这会告诉您空对象应该是哪个文件的散列。现在您可以修复它。
$> git hash-object -w path/to/your_file.whatever
After doing this I checked .git/objects/xx/12345
, it was no longer empty, and git stopped complaining.
这样做后,我检查了.git/objects/xx/12345
,它不再是空的,并且 git 停止抱怨。
回答by Arthur
Try
尝试
git stash
This worked for me. It stashes anything you haven't committed and that got around the problem.
这对我有用。它隐藏了您尚未提交的任何内容,从而解决了问题。
回答by Jago
A garbage collectionfixed my problem:
一个垃圾收集固定我的问题:
git gc --aggressive --prune=now
Takes a while to complete, but every loose object and/or corrupted index was fixed.
需要一段时间才能完成,但每个松散的对象和/或损坏的索引都已修复。
回答by Tyler Gauch
simply running a git prune
fixed this issue for me
只需git prune
为我运行修复此问题
回答by halfer
I just experienced this - my machine crashed whilst writing to the Git repo, and it became corrupted. I fixed it as follows.
我刚刚经历了这个 - 我的机器在写入 Git 存储库时崩溃了,它被损坏了。我按如下方式修复了它。
I started with looking at how many commits I had not pushed to the remote repo, thus:
我首先查看我没有推送到远程仓库的提交数量,因此:
gitk &
If you don't use this tool it is very handy - available on all operating systems as far as I know. This indicated that my remote was missing two commits. I therefore clicked on the label indicating the latest remote commit (usually this will be /remotes/origin/master
) to get the hash (the hash is 40 chars long, but for brevity I am using 10 here - this usually works anyway).
如果你不使用这个工具,它非常方便——据我所知,它在所有操作系统上都可用。这表明我的遥控器缺少两次提交。因此,我单击了指示最新远程提交的标签(通常是/remotes/origin/master
)以获取散列(散列长度为 40 个字符,但为简洁起见,我在这里使用 10 个字符 - 这通常可以正常工作)。
Here it is:
这里是:
14c0fcc9b3
14c0fcc9b3
I then click on the following commit (i.e. the first one that the remote does not have) and get the hash there:
然后我单击以下提交(即远程没有的第一个提交)并在那里获取哈希:
04d44c3298
04d44c3298
I then use both of these to make a patch for this commit:
然后我使用这两个来为此提交制作补丁:
git diff 14c0fcc9b3 04d44c3298 > 1.patch
I then did likewise with the other missing commit, i.e. I used the hash of the commit before and the hash of the commit itself:
然后我对另一个丢失的提交做了同样的处理,即我使用了之前提交的哈希值和提交本身的哈希值:
git diff 04d44c3298 fc1d4b0df7 > 2.patch
I then moved to a new directory, cloned the repo from the remote:
然后我移动到一个新目录,从远程克隆 repo:
git clone [email protected]:username/repo.git
I then moved the patch files into the new folder, and applied them and committed them with their exact commit messages (these can be pasted from git log
or the gitk
window):
然后我将补丁文件移动到新文件夹中,并应用它们并使用它们的确切提交消息提交它们(这些可以从git log
或gitk
窗口粘贴):
patch -p1 < 1.patch
git commit
patch -p1 < 2.patch
git commit
This restored things for me (and note there's probably a faster way to do it for a large number of commits). However I was keen to see if the tree in the corrupted repo can be repaired, and the answer is it can. With a repaired repo available as above, run this command in the broken folder:
这为我恢复了东西(请注意,对于大量提交,可能有一种更快的方法)。但是,我很想知道损坏的 repo 中的树是否可以修复,答案是可以。使用上述可用的修复存储库,在损坏的文件夹中运行此命令:
git fsck
You will get something like this:
你会得到这样的东西:
error: object file .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d is empty
error: unable to find ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
error: sha1 mismatch ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
To do the repair, I would do this in the broken folder:
要进行修复,我会在损坏的文件夹中执行此操作:
rm .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
cp ../good-repo/.git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
i.e. remove the corrupted file and replace it with a good one. You may have to do this several times. Finally there will be a point where you can run fsck
without errors. You will probably have "dangling commit" and "dangling blob" lines in the report, these are a consequence of your rebases and amends in this folder, and are OK. The garbage collector will remove them in due course.
即删除损坏的文件并用一个好的文件替换它。您可能需要多次执行此操作。最后,您可以毫无错误地运行fsck
。您的报告中可能会有“dangling commit”和“dangling blob”行,这些是您在此文件夹中重新设置和修改的结果,并且没问题。垃圾收集器会在适当的时候删除它们。
Thus (at least in my case) a corrupted tree does not mean unpushed commits are lost.
因此(至少在我的情况下)损坏的树并不意味着未推送的提交丢失。
回答by Rebecca Dessonville
I was getting a corrupt loose object error as well.
我也收到了损坏的松散对象错误。
./objects/x/x
I successfully fixed it by going into the directory of the corrupt object. I saw that the users assigned to that object was notmy git user's. I don't know how it happened, but I ran a chown git:git
on that file and then it worked again.
我通过进入损坏对象的目录成功修复了它。我看到分配给该对象的用户不是我的 git 用户。我不知道它是怎么发生的,但是我chown git:git
在那个文件上运行了一个,然后它又工作了。
This may be a potential fix for some peoples' issues but not necessary all of them.
这可能是针对某些人的问题的潜在解决方案,但并非所有问题都必须如此。