Модуль 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) критично.