Как восстановить коммиты после выполнения команды rebase?

У меня есть локальный проект с несколькими коммитами, и я использовал rebase для его изучения и практики. После нескольких итераций я заметил, что у меня пропало 16 коммитов. При этом стоит отметить, что некоторые из них не были удалены из-за пустоты, и изменения, которые они содержали, по-прежнему доступны. Могло ли это произойти из-за бага в git? И возможно ли восстановить эти коммиты?
  • 9 апреля 2025 г. 10:05
Ответы на вопрос 3
В Git после выполнения операции `rebase` действительно возможна потеря коммитов в случае, если какие-то из них были удалены в процессе слияния (например, если они стали пустыми). Однако в большинстве случаев потерянные коммиты можно восстановить. Вот несколько способов, как это сделать:

1. **Проверка reflog**: Git ведет журнал всех операций, которые вы выполняли, включая `rebase`. Используйте команду `git reflog`, чтобы увидеть историю ваших действий. Вы можете найти SHA-1 хэш потерянных коммитов или состояния ветки до ребейза. Для этого выполните:

   ```bash
   git reflog
   ```

   Найдите строку, в которой присутствует commit вашего состояния до ребейза, и скопируйте его хэш.

   Затем вы можете восстановить состояние ветки, сделав:

   ```bash
   git checkout <commit-hash>
   ```

   Или даже создать новую ветку от этого состояния:

   ```bash
   git checkout -b восстановленная-ветка <commit-hash>
   ```

2. **Сравнение с удаленными репозиториями**: Если вы когда-либо запушили свои коммиты в удаленный репозиторий, вы можете попробовать сбросить (reset) ветку к состоянию, уже запушенному. Используйте:

   ```bash
   git fetch
   git reset --hard origin/ваша-ветка
   ```

   Учтите, что данный способ приведет к потере всех локальных изменений.

3. **Поиск коммитов в ветках**: Если вы работали с несколькими ветками, возможно, ваши коммиты все еще находятся в каких-то других ветках. Просмотрите список всех веток:

   ```bash
   git branch -a
   ```

   И проверьте, не находятся ли нужные коммиты в других ветках.

4. **Использование инструмента для визуализации истории**: Иногда удобно использовать интерфейс, такой как Gitk или GUI-клиенты (например, SourceTree или Tower), чтобы визуально отследить, что произошло с вашими коммитами.

Если вы сможете найти потерянные коммиты, не забудьте делать резервные копии и подумать о том, чтобы учесть дополнительные шаги при использовании `rebase` в будущем, чтобы избежать потери данных.
Просмотреть все коммиты можно используя git reflog
Почему «пропали» коммиты? 

Главная ошибка — использование --amend во время rebase .
Команда git commit --amend не создает новый коммит, а перезаписывает предыдущий.

Когда вы время интерактивного rebase на каждом шаге делаете --amend , вы по сути всё время заменяете один и тот же коммит. Остальные коммиты, которые Git должен был «применить» в процессе ребейза, просто исчезают, потому что их заменили.

Как делать правильно?

Во время rebase -i вместо amend нужно:

git add <файлы> #  главное проиндексировать правки файлов
git rebase --continue # тут гит уже сам сделает git commit --no-edit
Вручную делать git commit перед continue имеет смысл только если вы хотите поменять ещё и сообщение коммита.

Как восстановить утерянные коммиты

Git не удаляет коммиты сразу. Они остаются в репозитории и доступны в reflog — журнале ссылок.

Их можно найти так: git reflog

Затем восстановить ветку: git reset --hard <хеш_из_reflog>

Вывод

Это не баг Git, а ожидаемое поведение. Просто rebase + amend — взрывоопасная смесь, особенно если не до конца понимать, что происходит.
Похожие вопросы