7

リポジトリ内のオブジェクトが破損している状況があります。

$ git push
...
fatal: loose object 95b6a826cadae849f4932a71d6735ab6ceb47cab (stored in .git/objects/95/b6a826cadae849f4932a71d6735ab6ceb47cab) is corrupt
...

そして、このオブジェクトが古いコミットによってリンクされた blob であることはわかっています。

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

FAQ から blob を復元するための従来の手順を実行しましたが、他のコピーが見つからないようです (私は一人で作業していて、しばらくリモートにプッシュしていないため、存在しません)。私はそれを回復することはできません。

このブロブは実際には、それ以来多くの変更が加えられたファイルの最初のバージョンです。そのバージョンのファイルに関する情報が失われても問題ありません。したがって、それを指しているコミットから削除したいと思います。どうやってやるの?

4

1 に答える 1

4

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-filegit 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、私が彼にすべてを剪定するように頼んだときも失敗しました。それで、私は、以前に成功裏にプッシュしたので、すべてを新しいリポジトリにクローンして戻し、そこから作業することが最善の行動方針であると考えました。

于 2013-01-04T04:27:25.843 に答える