git“松散对象...已损坏"; -我丢失了哪些数据? [英] git "loose object ... is corrupt" - what data have I lost?

查看:109
本文介绍了git“松散对象...已损坏"; -我丢失了哪些数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经对本地分支进行了几次提交,然后尝试执行git fetch.它失败,并出现以下错误:

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

运行git fsck只是显示与第一行相同的内容.出于相同的原因,实际上可以提交或推送我的更改的任何命令似乎都将失败.

该文件似乎只包含零负载.我看过如何修复GIT错误:目标文件为空?,其中有人报告通过删除已损坏的文件成功解决了该问题.

我的问题是:如果我删除每个显示损坏的文件,将会丢失什么?我实际上会丢失任何提交吗?

请注意,我不确定如何进入这种状态,尽管它是在我的电脑蓝屏之后发生的,所以也许是造成这种情况的原因.

解决方案

我在git储存库中解决了此问题,我认为这是由运行在Windows上的不可靠文件系统(在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

我没有像某些人建议的那样使HEAD恢复到良好状态,而是做了reset. checkout更改树的状态和所在的分支. reset(无--hard)更改您所在的分支,但不更改任何文件.我想将我拥有的所有文件都保持在当前状态,所以更是如此,因为它们是我最近提交的唯一记录(因为我所在的分支有问题,并且无法记录). /p>

当我上一次可以使用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即可完全回到我的起点!

这花了点时间,但是这意味着自从我上次推送以来,我并没有丢失十几个提交.

I have made a few commits to a local branch, then I tried to do git fetch. It failed with the following errors:

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

Running git fsck just shows the same as the first line. Any command that would actually commit or push my changes seems to fail for the same reason.

The file appears to just contain a load of zeros. I've seen how to fix GIT error: object file is empty? in which someone reports success resolving this by deleting the file that is corrupt.

My question is: if I go through deleting every file that it says is corrupt, what will I lose? Will I actually lose any commits?

Note I'm not sure how I got into this state, though it happened after my pc blue-screened, so maybe that caused it.

解决方案

I fixed this problem on my git repository, where I believe it was caused by a dodgy filesystem (on a Linux virtual machines hosted on Windows) acting up on a hard reset.

I started out in the same place as you, with:

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

Before doing anything, I backed up the whole tree by making a recursive copy of it into another folder. Do this.

Then I forcibly removed the object which was corrupt:

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

I then got a different problem which prevented me from running any git commands:

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

Instead of doing a checkout as some people recommend to get HEAD back to a good state, I did reset. checkout changes both the state of your tree and the branch that you are on. reset (without --hard) changes the branch that you are on, but doesn't change any of the files. I wanted to keep all the files I had in their current state, all the more so since they are the only record of my recent commits (since the branch that I am on, has some problem, and can't be logged).

When I last could use git, I was on a feature branch, call it feature_foo. I couldn't reset to feature_foo since it pointed to the deleted commit 2ef529fa.. I reset to master. I believe it doesn't matter where you reset to, any other branch should do.

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'.

Now I am on master, but with the same file tree that I had before. Since feature_foo was quite different from master, I see loads of unstaged, uncommitted changes. This is normal. I think the message about ORIG_HEAD just means that git records my previous location somewhere, and right now it's not happy because my previous location is the deleted commit.

Now that I have a proper HEAD, I can do 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

Here I see that all the commits I did on the feature branch before losing my work are still there. I think that only the most recent one, 2ef529fa.. was lost of course. I would like to reset to HEAD@{1} to be back on a branch with these commits.

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

So I open this file to edit it:

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

This file looks like a bunch of SHA1s and commit messages, until the last few lines:

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

In other words, I see the same valid commits in the reflog, then a bunch of garbage, then a commit which shows me resetting to master FROM the invalid commit (scroll right to see it).

I delete all the garbage and everything past it, then save the file. Now I can look at the reflog again:

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

Now, the abbreviated SHA1 from the first line, 61ac654, seems to point to master. This is confirmed by me looking further down the reflog and seeing the same SHA1 appear in other places, when I was on master. Furthermore, doing git reset HEAD@{0} doesn't do anything at all. But if I do:

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

The small number of unstaged changes shows me that my file tree is now very close to what I have committed in Git. Doing git log confirms that I have all the commits I saw in the reflog in my history now, except for the first one. So I just have to re-commit this commit, and the naughty one 2ef529f to get exactly back to where I started!

This took some figuring out, but meant I didn't lose the dozen or so commits since my last push.

这篇关于git“松散对象...已损坏"; -我丢失了哪些数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆