git“松散的对象......是腐败的” - 我丢失了哪些数据?

时间:2014-01-15 08:43:40

标签: git

我已经向一个本地分支做了一些提交,然后我尝试了git fetch。它因以下错误而失败:

fatal: loose object 7b36029a951eacd979d24e993e020c4d018ca265 (stored in .git/objects/7b/36029a951eacd979d24e993e020c4d018ca265) is corrupt
fatal: unpack-objects failed

正在运行git fsck只显示与第一行相同的内容。任何实际提交或推送我的更改的命令似乎都失败了。

该文件似乎只包含一堆零。我见过how to fix GIT error: object file is empty?,其中有人通过删除损坏的文件报告成功解决此问题。

我的问题是:如果我删除它说的每个文件都已损坏,我会丢失什么?我真的会丢失任何提交吗?

注意我不知道我是如何进入这种状态的,虽然这是在我的电脑蓝屏后发生的,所以可能是因为它造成的。

5 个答案:

答案 0 :(得分:11)

我在我的git存储库中解决了这个问题,我相信它是由一个狡猾的文件系统(在Windows上托管的Linux虚拟机上)引起硬复位的。

我和你在同一个地方开始:

jack@machine:~/git/cs$ git status
error: object file .git/objects/2e/f529faaaed03b2384b9f4d49a2ea95d7833894 is empty
error: object file .git/objects/2e/f529faaaed03b2384b9f4d49a2ea95d7833894 is empty
fatal: loose object 2ef529faaaed03b2384b9f4d49a2ea95d7833894 (stored in .git/objects/2e/f529faaaed03b2384b9f4d49a2ea95d7833894) is corrupt

在做任何事情之前,我通过将其递归复制到另一个文件夹来备份整个树。 这样做。

然后我强行删除了腐败的对象:

jack@machine:~/git/cs$ rm .git/objects/2e/f529faaaed03b2384b9f4d49a2ea95d7833894 
rm: remove write-protected regular empty file ‘.git/objects/2e/f529faaaed03b2384b9f4d49a2ea95d7833894’? y

然后我遇到了一个不同的问题,导致我无法运行任何git命令:

jack@machine:~/git/cs$ git status
fatal: bad object HEAD

有些人建议让checkout恢复到良好状态,而不是按HEADresetcheckout更改树的状态和您所在的分支。 reset(没有--hard)更改您所在的分支,但不会更改任何文件。我想保留我当前状态下的所有文件,尤其是因为它们是我最近提交的唯一记录(因为我所在的分支,有一些问题,并且无法记录)

当我最后一次使用git时,我在一个功能分支上,称之为feature_foo。我无法重置为feature_foo,因为它指向已删除的提交2ef529fa..我重置为master。我相信你重置的位置并不重要,任何其他分支都应该这样做。

jack@machine:~/git/cs$ git reset master
Unstaged changes after reset:
M   a/bunch/of_changes
M   more/changes
error: Trying to write ref ORIG_HEAD with nonexistent object 2ef529faaaed03b2384b9f4d49a2ea95d7833894
error: Cannot update the ref 'ORIG_HEAD'.

现在我在master,但使用的文件树与之前相同。由于feature_foomaster完全不同,因此我看到了大量未经暂停的,未提交的更改。这个是正常的。我认为关于ORIG_HEAD的消息只是意味着git会将我以前的位置记录到某处,而现在它并不高兴,因为我之前的位置是已删除的提交。

现在我有一个合适的HEAD,我可以git reflog

jack@machine:~/git/cs$ git reflog
61ac654 HEAD@{0}: commit: Commit message from a commit I did earlier
f9a1ce9 HEAD@{1}: commit: Another commit message
b26a6e9 HEAD@{2}: commit: Yet another commit message

在这里,我看到我在丢失工作之前在功能分支上执行的所有提交仍然存在。我认为只有最近的一个2ef529fa..当然丢失了。我想重置为HEAD@{1}以回到这些提交的分支上。

jack@machine:~/git/cs$ git reset HEAD@{1}
fatal: Log .git/logs/HEAD is corrupt.

所以我打开这个文件进行编辑:

jack@machine:~/git/cs$ vim .git/logs/HEAD

此文件看起来像一堆SHA1和提交消息,直到最后几行:

b26a6e99762e703914dc3749fe136d99e100ac74 f9a1ce9c9eaa54b51aa29efdeafec023202de470 Jack <jack@example.com> 1434447540 +0100  commit: Another commit message
f9a1ce9c9eaa54b51aa29efdeafec023202de470 420ded21ffed88a2865cc0adaf3f54b0b44864e2 Jack <jack@example.com> 1434449503 +0100  commit: Commit message from a commit I did earlier
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@2ef529faaaed03b2384b9f4d49a2ea95d7833894 53b404d482a426046f2de6484b8855d1154b7fca Jack <jack@example.com> 1434465895 +0100  reset: moving to master

换句话说,我在reflog中看到了相同的有效提交,然后是一堆垃圾,然后是一个提交,它显示我从无效提交重置为master(向右滚动以查看它)。

我删除了所有垃圾及其后的所有内容,然后保存文件。现在我可以再次查看reflog:

jack@machine:~/git/cs$ git reflog
61ac654 HEAD@{0}: commit: Commit message from a commit I did earlier
f9a1ce9 HEAD@{1}: commit: Another commit message
b26a6e9 HEAD@{2}: commit: Yet another commit message

现在,第一行61ac654的缩写SHA1似乎指向master。当我在master上时,我进一步查看reflog并看到相同的SHA1出现在其他地方,这证实了这一点。此外,做git reset HEAD@{0}根本不做任何事情。但如果我这样做:

jack@machine:~/git/cs$ git reset HEAD@{1}
Unstaged changes after reset:
M   just/a/few_changes

少量未分级的更改显示我的文件树现在非常接近我在Git中提交的内容。正在做git log确认我现在已经在历史记录中的reflog中看到了所有提交,除了第一个提交。所以我只需要重新提交这个提交,而顽皮的那个2ef529f就可以回到我开始的地方了!

这需要一些搞清楚,但这意味着自从我上一次推动以来我没有失去十几个承诺。

答案 1 :(得分:0)

In our case the remote git had a corrupted file blob ~28mb. This file should have been ~32mb but somehow became corrupted.

Solution was to copy the blob file from the computer that made the commit, and overwrite the corrupted file on the remote git repository.

答案 2 :(得分:0)

我遇到了类似的问题并且遵循了@jwg解决方案,但无法在git reflog步骤进行。

git reflog仅生成 以下内容: -

1fd3a1d HEAD@{0}: reset: moving to develop

然而,结果是我的git不再腐败,我的代码在所有修改后仍未触及。只是更改未提交,我所做的所有提交都丢失了。

此时,我可以执行git-commit -a并丢失所有提交但仍保留最新代码。

然后,我注意到创建了一个分支temp。其中包含我的代码的稍后版本,但不是最新。举例说明: -

当前分支 - 功能/功能1(现在包含我的最新代码,但缺少大多数提交)

另一个分支 - temp(不包含最新代码,但提交的提交数量超过当前分支

所以我继续git commit -a我当前的分支然后git rebase temp,修复了一些冲突并完成了!最后,我仍然丢失了一些提交,但至少代码是最新的。

修改

结果我没有最新的工作代码,所以我设法保存的是一些提交。我用备份恢复了文件。

答案 3 :(得分:0)

当存储库中.git文件夹中的某些文件已损坏时,会发生这种情况。很可能你可能没有丢失任何数据。由于意外电源故障可能导致文件损坏。如果是这种情况,则有可能丢失数据。

在我的情况下,原因是电源故障。我只是克隆了远程仓库到另一个位置,将整个.git文件夹复制到我现有的本地仓库。它解决了这个问题,我的数据都没有丢失。

答案 4 :(得分:-1)

一个简单的解决方法是将旧存储库移动到其他位置并重新放入它:

$ cd ..
$ mv <repo-name> <repo-name>-original
$ git clone <url> <repo-name>

如果有丢失的东西,有办法从旧的存储库中检索它们,但首先尝试重新连接它。