#Что означает проблема
После git rebase Git пересоздаёт коммиты поверх другой основы: хеши обычно меняются, а прежние вершины веток могут перестать отображаться в обычном git log. Это не всегда потеря: Git хранит локальный журнал перемещений ссылок (reflog) и, пока нужные объекты не удалены, коммит можно восстановить. Статья посвящена поиску исчезнувшего коммита, а не обычному завершению перебазирования.
#Как отличить причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Коммит пересоздан с новым SHARebase создал эквивалентный коммит с другим родителем. | Новый git log содержит похожее изменение и сообщение, но другой идентификатор. | Сначала проверить содержимое, возможно, восстанавливать нечего. |
| Коммит пропущен или оказался пустымRebase не включил прежний коммит, например из-за уже присутствующих изменений. | Коммита в новой линии нет; в reflog видна прежняя вершина или исходный SHA. | Проверить исходный коммит, закрепить его отдельной веткой. |
| Коммит остался в отброшенной локальной историиВетка теперь указывает на новую вершину, а прежняя не имеет именованной ссылки. | git reflog --all находит старый SHA, git show показывает нужные файлы. | Создать спасательную ссылку до новых операций очистки. |
#Пошаговая диагностика и решение
- Остановите любые операции очистки и проверьте rebaseОткройте VS Code → «Терминал» → «Создать терминал» внутри проекта либо Git Bash в его каталоге. Введите
git status -sb. Если тамYou are currently rebasing, сперва выясните, есть ли незаконченные конфликты:git rebase --abortотменяет текущий НЕЗАВЕРШЁННЫЙ rebase, но не отменяет давно завершённый. Не используйте команду автоматически — если изменения уже исправлялись вручную, сохраните их копию. Перед остальными командами выполнитеgit --version: в ответ должна появиться установленная версия Git. Если терминал сообщает, чтоgitне найден, проверьте установку Git и доступность команды в этом терминале; не продолжайте операции наугад. - Проверьте, нет ли нужного изменения под новым хешемВыполните
git log --all --oneline --decorate -30и найдите сообщение исчезнувшего коммита. Откройте его черезgit show --stat ВАШ_SHAс настоящим идентификатором. Если файлы и поведение уже совпадают, повторное применение может создать дубль. Проверьте тесты вместо немедленного восстановления. - Откройте локальный журнал перемещений ссылокВ том же терминале выполните
git reflog --all --date=iso. Записи часто содержатrebase (start),rebase (pick)илиrebase (finish)и исходные вершины. Из-за большого журнала можно дополнительно посмотретьgit reflog show HEAD -30, но он может не показать старые записи других веток. Запишите хеш нужного коммита из вывода, а не плавающий номерHEAD@{N}. - Проверьте содержимое найденного SHA, не переключаясьВыполните
git show --stat ВАШ_SHAи при необходимостиgit show --format=fuller --no-patch ВАШ_SHA. Сверьте автора, дату, текст сообщения и список файлов. ПодстановкаВАШ_SHAобязательна; не копируйте пример буквально. Если Git пишетbad object, проверьте правильность хеша и того, что это тот же локальный клон: удалённый сервер обычно не хранит ваш reflog. - Закрепите найденную точку отдельной веткойКогда уверены, что SHA правильный, создайте ссылку
git branch rescue-before-rebase ВАШ_SHA. Это НЕ меняет рабочие файлы и не сбрасывает текущую ветку; созданное имя защищает объект от потери из-за отсутствия ссылок. Если веткаrescue-before-rebaseуже существует, выберите новое уникальное имя и не используйте-f. - Сравните восстановленный коммит с текущей историейЗапустите
git log --oneline --left-right --cherry-pick rescue-before-rebase...HEAD. Здесь трёхточечное выражение сравнивает две линии и с--cherry-pickпомогает скрыть эквивалентные изменения. Однако сложные слияния и частично изменённые правки могут требовать ручной сверкиgit show. Сохраните результаты сравнения для команды до применения любых изменений. - Перенесите необходимый одиночный коммит безопасноТолько если коммит действительно отсутствует в текущей ветке, нет незакоммиченных правок и вы обсудили порядок с командой, создайте отдельную ветку
git switch -c restore-lost-change. Затем выполнитеgit cherry-pick ВАШ_SHA, подставив проверенный SHA одиночного коммита. Возможны конфликты: исправьте файлы,git addиgit cherry-pick --continueпосле тестов. При отказе от попытки выполнитеgit cherry-pick --abort, пока операция ещё не завершена. Для merge-коммита этот пример не подходит. - Проверьте результат и согласуйте публикациюУбедитесь, что
git log -3 --onelineсодержит нужное изменение на восстановительной ветке, тесты прошли,git status --shortпуст. Отправляйте изменения через обычный запрос на включение и не выполняйтеgit push --forceв рабочую общую ветку. Если нужного SHA нет ни в reflog, ни в копиях, специалист может изучить оставшиеся объекты, но гарантировать восстановление нельзя.
#Команды для проверки и исправления
--all включает известные ссылки, --date=iso делает даты понятнее.git status -sbgit log --all --oneline --decorate -30git reflog --all --date=isoВАШ_SHA действительным хешем из журнала в ОБЕИХ командах. Показывает файлы, автора и дату; не изменяет данные.git show --stat ВАШ_SHAgit show --format=fuller --no-patch ВАШ_SHAgit branch rescue-before-rebase ВАШ_SHAКоманда может изменить состояние системы или её настройки. Проверьте параметры и последствия перед запуском.
git log --oneline --left-right --cherry-pick rescue-before-rebase...HEADgit switch -c restore-lost-changegit cherry-pick ВАШ_SHAКоманда может изменить состояние системы или её настройки. Проверьте параметры и последствия перед запуском.
#Как проверить результат и что делать, если не помогло
Успех: спасательная ветка содержит исходный SHA, новая ветка содержит ровно необходимые восстановленные изменения, тесты проходят, рабочая папка чистая. Если найден только большой merge-коммит, не используйте пример cherry-pick без разбора родителей. Если журнал отсутствует, соберите резервные копии и сведения о Git для специалиста.