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

str*_*ger 3 git

我已经向当地分公司做了一些提交,然后我试着去做git fetch.它因以下错误而失败:

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

运行git fsck只显示与第一行相同.任何实际提交或推送我的更改的命令似乎都会因同样的原因而失败.

该文件似乎只包含一堆零.我已经看到如何修复GIT错误:对象文件是空的?其中有人通过删除已损坏的文件报告成功解决此问题.

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

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

jwg*_*jwg 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
Run Code Online (Sandbox Code Playgroud)

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

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

jack@machine:~/git/cs$ rm .git/objects/2e/f529faaaed03b2384b9f4d49a2ea95d7833894 
rm: remove write-protected regular empty file ‘.git/objects/2e/f529faaaed03b2384b9f4d49a2ea95d7833894’? y
Run Code Online (Sandbox Code Playgroud)

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

jack@machine:~/git/cs$ git status
fatal: bad object HEAD
Run Code Online (Sandbox Code Playgroud)

我做了checkout,而不是做一些人建议HEAD回到一个好状态reset.checkout更改树的状态和您所在的分支.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'.
Run Code Online (Sandbox Code Playgroud)

现在我正在使用master,但使用的是与之前相同的文件树.由于feature_foo完全不同master,我看到大量未经暂停的,未提交的更改.这个是正常的.我认为关于ORIG_HEADjust 的消息意味着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
Run Code Online (Sandbox Code Playgroud)

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

jack@machine:~/git/cs$ git reset HEAD@{1}
fatal: Log .git/logs/HEAD is corrupt.
Run Code Online (Sandbox Code Playgroud)

所以我打开这个文件来编辑它:

jack@machine:~/git/cs$ vim .git/logs/HEAD
Run Code Online (Sandbox Code Playgroud)

这个文件看起来像一堆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
Run Code Online (Sandbox Code Playgroud)

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

我删除了所有垃圾及其后的所有内容,然后保存文件.现在我可以再次查看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
Run Code Online (Sandbox Code Playgroud)

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

jack@machine:~/git/cs$ git reset HEAD@{1}
Unstaged changes after reset:
M   just/a/few_changes
Run Code Online (Sandbox Code Playgroud)

少量未分级的更改向我显示我的文件树现在非常接近我在Git中提交的内容.这样做git log,我有所有我在引用日志看到提交在我的历史,现在,除了第一个确认.所以我只需要重新提交这个提交,而顽皮的提交2ef529f将完全回到我开始的地方!

这需要一些解决,但意味着自从我上一次推动以来我没有丢失十几个提交.


Moh*_*f C 5

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

就我而言,原因是电源故障。我刚刚将远程存储库克隆到另一个位置,并将整个.git文件夹从新克隆复制到我现有的存储库。它解决了问题,并且我未提交/未推送的更改都没有丢失。

注意:该.git目录是本地存储库根目录中的隐藏目录。您可能必须启用显示隐藏的文件和文件夹选项,具体取决于您的操作系统


Agi*_*gis -1

一个简单的解决方法是将旧存储库移至其他位置并重新克隆它:

$ cd ..
$ mv <repo-name> <repo-name>-original
$ git clone <url> <repo-name>
Run Code Online (Sandbox Code Playgroud)

如果有东西丢失,有多种方法可以从旧存储库中检索它们,但首先尝试重新克隆它。