OK、私は最終的にそれを自分で理解しました。
短いバージョン:破損したblobを指すコミットを修正して、履歴から削除しました。
長いバージョン:ファイルが何であるかを知っていて、それをコミットから消えさせたいだけだったので、古いコミットを修正するだけでよいと思いました。私はそれが実際に機能することを期待していませんでしたが、最終的には機能しました。
以前のことを試したときに.git/objectsのblobを削除したことを指摘する必要があります。これは、なぜそれが機能したのかという点でおそらく重要です。
最初に、私はそれが何のコミットであるかを知らなければなりませんでした。そのために私はコマンドを使用しました
git log --raw --all --full-history -- subdir/my-file
コミットの名前は966a46でした。
それから私はそれを修正するための手順を実行しました。古いコミットだったので使ってみました
git rebase -- interactive 966a46^
私のエディターはコミットごとに1行を入力し、変更したいコミットの前で「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
、そしてすべてがうまくいった、そしてリベースは成功した。
git push
壊れたブロブについて失敗するのではなく、スムーズに進みました。
git fsck
しかし、まだ失敗していたので、まだ問題がありました:
$ git fsck --full
Checking object directories: 100% (256/256), done.
broken link from tree 27e8e7d5b94c1dad5410a8204089828a167a0eaf
to blob 95b6a826cadae849f4932a71d6735ab6ceb47cab
そしてgit gc
、私が彼にすべてを剪定するように頼んだときも失敗しました。それで、私は、以前に成功裏にプッシュしたので、すべてを新しいリポジトリにクローンして戻し、そこから作業することが最善の行動方針であると考えました。