Модуль 8: Решение сложных ситуаций и «спасение»
Разберём, как безопасно откатывать изменения и восстанавливать «потерянные» коммиты. В Git почти всё поправимо.
Принцип: в Git «по-настоящему» удаляется только то, что не было закоммичено или давно не достижимо и было сборщиком мусора удалено.
Важно не паниковать и двигаться по алгоритму: оценить текущее состояние, посмотреть историю и reflog
, зафиксировать «здоровую» точку, а затем аккуратно вернуться к рабочему процессу. Спокойствие и методичность здесь решают всё.
8.1 Откат незакоммиченных изменений: restore/checkout
# Откатить изменения в конкретном файле
git restore path/to/file
# Старый синтаксис (устар.):
# git checkout -- path/to/file
8.2 Восстановление файла из прошлого коммита
# Взять версию файла из конкретного коммита, не меняя всю ветку
git restore --source=<commit> -- path/to/file
8.3 Отмена коммитов: reset vs revert
- reset — переписывает указатели (историю) текущей ветки
- revert — создаёт новый коммит‑откат (без переписывания истории)
# reset: уровни
# --soft — откатить указатель, изменения останутся в индексе
# --mixed — (по умолчанию) откатить указатель, изменения попадут в рабочую директорию
# --hard — откатить всё (ОСТОРОЖНО!)
git reset --soft HEAD~1
git reset --mixed HEAD~1
git reset --hard HEAD~1
# revert: безопасно для публичных веток
git revert <commit-hash>
Выбор между reset
и revert
зависит от аудитории истории. Для общих веток почти всегда предпочтителен revert
, поскольку он прозрачно отражает отмену на «полосе времени» проекта.
8.4 Поиск «потерянного»: git reflog
reflog
хранит локальную историю перемещений HEAD
/веток. Помогает найти коммит после неудачного reset/rebase.
git reflog
# восстановить ветку на найденный коммит
git reset --hard <hash-from-reflog>
# или создать новую ветку с нужной точки
git branch rescue/<date> <hash>
8.5 Алгоритм действий «если всё сломали»
- Не паниковать. Ничего не удаляйте жёстко.
- Посмотрите
git status
иgit log --oneline --graph --decorate --all
. - Откройте
git reflog
и найдите «здоровую» точку. - Создайте спасательную ветку от найденного хеша:
git branch rescue/<date> <hash>
. - Аккуратно вернитесь к работе:
git switch rescue/<date>
илиgit reset --hard <hash>
(понимая последствия).
8.6 Сроки хранения reflog
reflog
хранится локально и очищается сборщиком мусора. Сроки регулируются параметрами конфигурации (например, время истечения записей), что важно при восстановлении старых состояний.
8.7 Garbage collection и packfiles
Git упаковывает объекты в packfiles для экономии места и скорости. git gc
удаляет недостижимые объекты и оптимизирует хранилище, соблюдая «период безопасности», чтобы не потерять недавние объекты.
8.8 Проверка целостности: git fsck
git fsck
анализирует целостность графа объектов и ссылок, помогает найти «висячие» объекты и повреждения.
8.9 Revert merge‑коммита
Откат merge‑коммита требует указать -m <parent-number>
— какой родитель считать «основной». Это важно, чтобы корректно инвертировать изменения.
8.10 Глубже про reset: soft/mixed/hard
reset
перемещает указатели и управляет состоянием индекса/рабочей директории. soft — только HEAD
; mixed — HEAD
и индекс; hard — всё, включая рабочее дерево. Понимание трёх деревьев (HEAD/index/worktree) критично.