OK, w końcu sam to wymyśliłem.
Skrócona wersja: Poprawiłem commit wskazując na uszkodzony obiekt blob, aby usunąć go z historii.
Długa wersja: Myślałem, że skoro już wiedziałem, co to za plik, i po prostu chciałem, aby zniknęło z zatwierdzenia, mógłbym tylko zmienić stare zatwierdzenie. Nie spodziewałem się, że to zadziała, ale ostatecznie tak się stało.
Muszę zaznaczyć, że usunąłem blob w pliku .git/objects próbując poprzednich rzeczy, i prawdopodobnie jest ważne, dlaczego zadziałało.
Po pierwsze, musiałem wiedzieć, jakie było to zobowiązanie. Do tego użyłem komendy
git log --raw --all --full-history -- subdir/my-file
znalazłem commit nazwano 966a46 ....
Potem zrobiłem kroki w celu jego zmiany. Ponieważ to był stary popełnić użyłem
git rebase -- interactive 966a46^
Mój redaktor przyszedł z jednej linii dla każdego popełnić, i zmieniłem „pick” na „edytuj” przed commit chciałem zmodyfikować.
Komenda git status
pokazał mi, że plik Chciałam wymazać zmodyfikowano:
# 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
chciałem usunąć go z popełnić, więc zrobiłem rm subdir/my-file
. git status
następnie mi pokazał:
# deleted: subdir/my-file
To wyglądało obiecująco. Więc po prostu popełnił zmieniony popełnić i kontynuował rebase:
git commit --all --amend
git rebase --continue
Ale po rebased kilka zobowiązuje się nie udało z tego błędu:
error: could not apply 45c2315... did some fancy things
fatal: unable to read 95b6a826cadae849f4932a71d6735ab6ceb47cab
45c2315 był pierwszym commit, w którym mój plik został zmodyfikowany po utworzeniu. Ponieważ nie znaleziono poprzedniej wersji pliku, po prostu się nie udało.
git status
pokazał mi, między innymi:
# 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
I rzeczywiście nie jestem pewien, co to znaczy, ale to commit miał być pierwszym, w którym wydaje się plik, po poprawce. Więc nie chciałem, aby został usunięty, ale wręcz przeciwnie, dodano do zatwierdzenia! Więc zrobiłem
git add subdir/my-file
I pewnie git status
pokazał go jako „nowy plik”.
Potem zrobiłem git rebase --continue
i wszystko poszło dobrze, a rebelianci odniosły sukces.
git push
poszło wtedy gładko, zamiast zawodzić o pękniętej kropli.
Ale były jeszcze problemem, ponieważ git fsck
wciąż braku:
$ git fsck --full
Checking object directories: 100% (256/256), done.
broken link from tree 27e8e7d5b94c1dad5410a8204089828a167a0eaf
to blob 95b6a826cadae849f4932a71d6735ab6ceb47cab
I git gc
zawiodły też, gdy zapytałem go przycinać wszystko. Odkryłem więc, że najlepszym sposobem działania było, od kiedy z powodzeniem przeforsowałem wcześniej, sklonowanie wszystkiego z powrotem w nowym repozytorium i pracę z tego miejsca.
Spróbuj spojrzeć na niektóre z rozwiązań tutaj: http://stackoverflow.com/q/4254389/1031900 –
To pytanie dotyczy uszkodzonego drzewa, które jest nieco inne. Żadna z tych odpowiedzi nie może mi pomóc, niestety. Zamierzam wypróbować kilka rzeczy i opublikuję go tutaj, jeśli zadziałają. –