Я только что испытал это - моя машина сломалась во время записи в репозиторий Git, и она стала поврежденной. Я исправил это следующим образом.
Я начал с просмотра количества коммитов, которые я не перенес в удаленное репо, таким образом:
gitk &
Если вы не используете этот инструмент, он очень удобен - доступен, насколько мне известно, во всех операционных системах. Это указывало на то, что на моем пульте не было двух коммитов. Поэтому я нажал на метку, указывающую последний удаленный коммит (обычно это будет /remotes/origin/master
), чтобы получить хеш (хеш длиной 40 символов, но для краткости я здесь использую 10 - это обычно работает в любом случае).
Вот оно:
14c0fcc9b3
Затем я нажимаю на следующий коммит (т. Е. Первый, которого нет у пульта) и получаю хэш:
04d44c3298
Затем я использую оба из них, чтобы сделать патч для этого коммита:
git diff 14c0fcc9b3 04d44c3298 > 1.patch
Затем я сделал то же самое с другим отсутствующим коммитом, т. Е. Раньше использовал хэш коммита и сам хэш коммита:
git diff 04d44c3298 fc1d4b0df7 > 2.patch
Затем я переместился в новый каталог, клонировал репозиторий с пульта:
git clone git@github.com:username/repo.git
Затем я переместил файлы исправлений в новую папку, применил их и зафиксировал их с точными сообщениями о фиксации (их можно вставить из git log
или из окна gitk
):
patch -p1 < 1.patch
git commit
patch -p1 < 2.patch
git commit
Это восстановило вещи для меня (и заметьте, что, вероятно, есть более быстрый способ сделать это для большого количества коммитов). Однако мне было интересно посмотреть, можно ли отремонтировать дерево в поврежденном репо, и ответ - можно. С восстановленным репо, доступным, как указано выше, выполните эту команду в сломанной папке:
git fsck
Вы получите что-то вроде этого:
error: object file .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d is empty
error: unable to find ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
error: sha1 mismatch ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
Чтобы сделать ремонт, я бы сделал это в сломанной папке:
rm .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
cp ../good-repo/.git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
т.е. удалите поврежденный файл и замените его хорошим. Возможно, вам придется сделать это несколько раз. Наконец, наступит момент, когда вы сможете запустить fsck
без ошибок. Вероятно, в отчете будут строки «висячий коммит» и «висячий блоб», они являются следствием ваших перебазировок и исправлений в этой папке, и все в порядке. Сборщик мусора удалит их со временем.
Таким образом (по крайней мере, в моем случае) поврежденное дерево не означает, что невыдвинутые коммиты будут потеряны.