从存储库中删除git corrupt blob

Cyr*_* Ka 7 git corrupt

我有一个存储库中的损坏对象的情况.

$ git push
...
fatal: loose object 95b6a826cadae849f4932a71d6735ab6ceb47cab (stored in .git/objects/95/b6a826cadae849f4932a71d6735ab6ceb47cab) is corrupt
...
Run Code Online (Sandbox Code Playgroud)

而且我知道这个对象是一个与旧提交相关联的blob:

$ git fsck --full
Checking object directories: 100% (256/256), done.
broken link from  tree 27e8e7d5b94c1dad5410a8204089828a167a0eaf
            to    blob 95b6a826cadae849f4932a71d6735ab6ceb47cab 
Run Code Online (Sandbox Code Playgroud)

我已经完成了从常见问题解答中恢复blob经典步骤,但似乎没有其他任何我可以找到的副本(我独自工作并且没有推到遥控器一段时间所以它不在那里)所以我无法恢复它.

这个blob实际上是一个文件的第一个版本,从那时起经过多次修改.我很好地丢失了有关该版本文件的信息.所以我想将它从指向它的提交中删除.我怎样才能做到这一点?

Cyr*_* Ka 4

好吧,我最终自己弄清楚了。

简短版本:我修改了指向损坏的 blob 的提交,以将其从历史记录中删除。

长版本:我认为既然我知道文件是什么,并且只是想让它从提交中消失,那么我可以修改旧的提交。我真的没想到它会起作用,但最终它确实起作用了。

我必须指出,我在尝试之前的操作时删除了 .git/objects 中的 blob,这对于它的工作原理可能很重要。

首先,我必须知道它是什么。为此我使用了命令

git log --raw --all --full-history -- subdir/my-file
Run Code Online (Sandbox Code Playgroud)

我发现该提交被命名为 966a46....

然后我按照步骤进行了修改。由于这是一个旧的提交,我使用了

git rebase -- interactive 966a46^
Run Code Online (Sandbox Code Playgroud)

我的编辑器为每个提交添加一行,并且我将要修改的提交前面的“pick”更改为“edit”。

该命令git status显示我要删除的文件已被修改:

# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   subdir/my-file
Run Code Online (Sandbox Code Playgroud)

我想将其从提交中删除,所以我这样做了rm subdir/my-filegit status然后向我展示:

#       deleted:    subdir/my-file
Run Code Online (Sandbox Code Playgroud)

这看起来很有希望。所以我只是提交了修改后的提交并继续变基:

git commit --all --amend
git rebase --continue
Run Code Online (Sandbox Code Playgroud)

但在重新调整一些提交后,它失败并出现以下错误:

error: could not apply 45c2315... did some fancy things
fatal: unable to read 95b6a826cadae849f4932a71d6735ab6ceb47cab
Run Code Online (Sandbox Code Playgroud)

45c2315 是我的文件在创建后被修改的第一次提交。由于它没有找到该文件的先前版本,因此失败了。

git status除其他外,还向我展示了:

# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       deleted by us:      subdir/my-file
Run Code Online (Sandbox Code Playgroud)

我实际上不确定这意味着什么,但这次提交应该是修复后文件出现的第一个提交。所以我不想让它被删除,而是相反,添加到提交中!所以我做了

git add subdir/my-file
Run Code Online (Sandbox Code Playgroud)

并且肯定git status将其显示为“新文件”。

然后我就这么做了git rebase --continue,一切都很顺利,rebase 成功了。

git push然后进展顺利,而不是因为破碎的斑点而失败。

但仍然有一个问题,因为git fsck仍然失败:

$ git fsck --full
Checking object directories: 100% (256/256), done.
broken link from    tree 27e8e7d5b94c1dad5410a8204089828a167a0eaf
              to    blob 95b6a826cadae849f4932a71d6735ab6ceb47cab
Run Code Online (Sandbox Code Playgroud)

git gc当我要求他修剪所有东西时,他也失败了。所以我发现最好的行动方案是,因为我之前已经成功推送过,所以将所有内容克隆回新的存储库中并从那里开始工作。