git“松散对象...已损坏"; -我丢失了哪些数据? [英] git "loose object ... is corrupt" - what data have I lost?
问题描述
我已经对本地分支进行了几次提交,然后尝试执行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_foo
与master
完全不同,因此我看到了未分段,未提交的更改的负载.这是正常的.我认为有关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屋!