Просмотр потерянных коммитов в Git

102

Мой репозиторий git как-то пошатнулся - я загрузил msysgit сегодня утром, и вместо имени ветки, отображаемого после текущего каталога, он говорит: «((ref: re ...))», «git status» сообщает обо всем как о новый файл, «git log» и «git reflog» сообщают мне «фатальная: плохая ревизия по умолчанию« HEAD »» и так далее.

Выполнение «git reflog --all» или «gitk --all» показывает мне, что остальная часть репозитория не повреждена, но похоже, что ветка, над которой я работал, только что исчезла, что объясняет, почему HEAD, похоже, не существует / указать на что угодно.

Я знаю, что git хранит все виды информации, и я предполагаю, что мои коммиты каким-то образом просто осиротели, поэтому есть ли какая-то команда, которая покажет мне эти коммиты, чтобы я мог сбросить для них HEAD?

РЕДАКТИРОВАТЬ: О, дорогой. Я обнаружил «git fsck», и «git fsck --full» сообщает «фатальный: объект 03ca4 ... поврежден». Что, черт возьми, я могу с этим поделать?

РЕДАКТИРОВАТЬ: О, дорогой, дорогой. Я проверил другую ветку, а затем попытался воссоздать исходную ветку с тем же именем, используя 'git checkout -b lostbranchname', и git сообщает: «Ошибка: невозможно разрешить ссылки refs / Heads / lostbranchname: нет ошибки, фатальный: сбой» заблокировать ссылку для обновления: нет ошибки ». «Нет ошибки» должно быть особенно неприятной ошибкой. Так что похоже, что он все еще висит, но не может быть использован и не может быть убит.

РЕДАКТИРОВАТЬ: Супер пупер, о боже. Я сделал кучу распаковки, переупаковки и замены вещей, как предлагается здесь: Как восстановить объекты Git, поврежденные в результате сбоя жесткого диска? , но теперь я получаю еще один хэш, который считается поврежденным, из-за чего-то столь же безобидного, как 'git status'. Я думаю, что все это залито из шланга. Git прекрасный и все такое, но я не должен иметь дело с такими вещами.

Бен Хаймерс
источник
Что касается git checkout -b lostbranchname- если вас интересует только имя ветки (а не ее содержимое), вы можете вручную удалить (или переименовать) .git/refs/heads/lostbranchname- это, надеюсь, поможет.
Энтони Хэтчкинс,
1
А у вас нет апстрима, куда вы вставляете эту папку git?
Lakshman Prasad
1
К сожалению, нет, на самом деле это своего рода суррогатный репозиторий для неполноценной системы управления версиями, я просто использую его локально, чтобы получить все функции и тонкости git без хлопот, связанных с другой системой. Но, по крайней мере, другая система не повреждается случайным образом. Тем не менее, это означает, что все, что я потерял, - это мои изменения с момента последней регистрации в другой системе, которые я уже восстановил. Пришло время создать новый репозиторий!
Бен Хаймерс,
7
Я не решаюсь сказать, что git заставил вас «иметь дело с такими вещами» или что он сам себя испортил. Ничто, кроме резервного копирования, не может быть полностью устойчивым к потере данных.
Cascabel
1
Я знаю, правда, я (естественно) немного обижен, что потерял свою красивую историю. Это не вина git, любая другая система будет вести себя так же при ошибках файловой системы.
Бен Хаймерс,

Ответы:

135

Вместо того, чтобы оставлять это открытым, я думаю, что дам ответ на свой вопрос. Использование git reflog --all- хороший способ просматривать потерянные коммиты, а с помощью хэшей SHA1 вы можете восстановить историю.

Однако в моем случае репозиторий был поврежден, поэтому это не помогло; git fsckможет помочь вам найти и иногда исправить ошибки в самом репозитории.

Бен Хаймерс
источник
3
Спасибо. Это единственное место, где я нашел эту информацию, когда пытался вытащить потерянный запрос на перенос на github. Решил мою проблему.
SystemParadox
6
на случай, если кто-то захочет получить все в gitk: [alias] orphank = !gitk --all --date-order ``git reflog | cut -c1-7``&(edit: представьте эти двойные обратные кавычки, где одиночные - экранирование здесь, похоже, не работает)
mbx
1
Отличный совет @mbx! Очень полезно иметь возможность графически видеть связи между потерянными коммитами!
Бен Хаймерс,
@BenHymers Было бы круто, если бы мы могли получить пунктирные линии и для отношений фиксации типа "rebase / squash". Я еще не нашел способа сделать это.
mbx
Я не знал о рефлоге, когда писал ответ выше. Это такой полезный инструмент!
Jamey Hicks
17

С git 2.9.x / 2.10 (Q3 2016) вам больше не придется использовать git reflog --all, git reflogбудет достаточно.

См. Commit 71abeb7 (3 июня 2016 г.) Седера Габора ( szeder) .
(Объединено Junio ​​C Hamano - gitster- в коммите 7949837 , 06 июля 2016 г.)

reflog: продолжить просмотр reflogпрошлых корневых коммитов

Если репозиторий содержит более одного корневого коммита, то его журнал HEAD reflog может содержать несколько «событий создания», то есть записей, значение «from» которых равно нулю sha1.
Вывод такого журнала ссылок в настоящее время преждевременно прекращается при первой такой записи, даже если журнал ссылок все еще содержит более старые записи.
Это может напугать пользователей, заставив их думать, что их рефлог был усечен после ' git checkout --orphan'.

Продолжайте обходить журнал ссылок мимо таких событий создания на основе «нового» значения предыдущей записи журнала.

VonC
источник
4

Одна хорошая особенность git - обнаружение повреждений. Однако он не включает исправление ошибок для защиты от повреждения.

Я надеюсь, что вы переместили содержимое этого репозитория на другую машину или у вас есть резервные копии для восстановления поврежденных частей.

У меня нет опыта работы с git в Windows, но я никогда не видел такого поведения с git в Linux или OS X.

Джейми Хикс
источник
3

Обычно git reflogрезультат меня сбивает с толку. Мне намного легче понять график коммитов из git log --graph --reflog. Переопределение формата для отображения только сводок фиксации также может упростить отслеживание графика:

$ git alias graph "log --graph --all --format='%h %s%n        (%an, %ar)%d' --abbrev-commit
$ git graph --reflog

* f06abeb Add feature
|         (Sue Dakota, 4 days ago) (HEAD -> master)
* f126291 Fix the build
|         (Oski M. Wizard, 5 days ago) (origin/master, master)
* 3c4fb9c Break the build
|         (Alyssa P. Hacker, 5 days ago)
| * e3124bf fixup! More work for feature
| |         (Sue Dakota, 4 days ago)
| | * 6a7a52e Lost commit
| |/          (Sue Dakota, 4 days ago)
| * 69d9438 More work for feature
| |         (Sue Dakota, 2 weeks ago)
| * 8f69aba Initial work for feature
|/          (Sue Dakota, 3 weeks ago)
* d824fa9 Fix warnings from the linter
|         (Theo Ristudent, 4 weeks ago)
* 9f782b8 Fix tests flakes
|         (Tess Driven, 5 weeks ago)

Из этого ясно, что e3124bfи 6a7a52eявляются сиротами без ссылок, и есть контекст от их предков.

Jamesdlin
источник
Сэкономил мне часы потерянной работы только сейчас! случайно удалил локальную ветку, в которой были неопубликованные коммиты, git reflog --allне показывает их, так как git log --graph --reflogони были очень заметны ...
Adam.Er8