好的,我最终自己弄清楚了。
简短版本:我修改了指向损坏 blob 的提交以将其从历史记录中删除。
长版:我想既然我知道文件是什么,只是想让它从提交中消失,那么我可以修改旧的提交。我真的没想到它会起作用,但最终它确实起作用了。
我必须指出,我在尝试以前的事情时删除了 .git/objects 中的 blob,这对于它为什么起作用可能很重要。
首先,我必须知道它是什么提交。为此,我使用了命令
git log --raw --all --full-history -- subdir/my-file
我发现提交被命名为 966a46....
然后我做了修改它的步骤。由于这是一个旧的提交,我使用
git rebase -- interactive 966a46^
我的编辑器为每个提交输入一行,我在我想要修改的提交前将“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
我想从提交中删除它,所以我做了rm subdir/my-file
. git status
然后给我看:
# deleted: subdir/my-file
这看起来很有希望。所以我只是提交了修改后的提交并继续变基:
git commit --all --amend
git rebase --continue
但是在重新提交了一些提交后,它失败了,出现了这个错误:
error: could not apply 45c2315... did some fancy things
fatal: unable to read 95b6a826cadae849f4932a71d6735ab6ceb47cab
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
我实际上不确定这意味着什么,但这个提交应该是在修复之后文件将出现的第一个。所以我不希望它被删除,而是相反,添加到提交中!所以我做了
git add subdir/my-file
并且肯定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
git gc
当我让他修剪所有东西时,也失败了。所以我发现最好的做法是,因为我之前已经成功推送,所以将所有内容克隆回一个新的存储库并从那里开始工作。