git revert
Безопасная отмена коммита путём создания нового коммита, который отменяет изменения — история не переписывается.
Зачем нужно
Когда нужно отменить изменения, которые уже опубликованы на remote и видны другим разработчикам, git reset опасен: он перезаписывает историю. git revert создаёт новый commit, который применяет инвертированный diff указанного коммита. История остаётся неизменной, все видят что именно было отменено и когда. Это стандартный способ отката в командных проектах.
Где используется
- Откат опубликованной фичи или бага с сохранением истории
- Отмена конкретного коммита посередине истории (не только последнего)
- Откат merge-коммита (слияния ветки)
- Hotfix: быстрая отмена сломанного релиза
Основной контент
Базовые команды
# Откатить последний коммит (откроет редактор для сообщения)
git revert HEAD
# Откатить конкретный коммит по хэшу
git revert abc1234
# Откатить без открытия редактора
git revert HEAD --no-edit
# Откатить диапазон коммитов (от старого к новому)
git revert abc1234..def5678
# Откатить, но не создавать коммит (добавить в staging)
git revert HEAD --no-commit
git revert HEAD -n
Откат merge-коммита
# Найти хэш merge-коммита
git log --oneline
# Откатить merge-коммит
# -m 1 означает: сохранить первую родительскую ветку (main)
# -m 2 сохранила бы feature-ветку
git revert -m 1 abc1234merge
Пример: откат сломанной фичи
# 1. Найти коммит, который нужно откатить
git log --oneline
# a1b2c3d feat: добавить экспорт в PDF ← сломал прод
# e4f5g6h feat: добавить фильтры
# i7j8k9l fix: исправить пагинацию
# 2. Откатить сломанный коммит
git revert a1b2c3d --no-edit
# Git создаст коммит:
# Revert "feat: добавить экспорт в PDF"
# This reverts commit a1b2c3d.
# 3. Опубликовать
git push
Разница revert vs reset
История до: A---B---C (HEAD)
git revert C: A---B---C---C' (C' отменяет изменения C)
git reset --hard B: A---B (C потерян)
revert |
reset |
|
|---|---|---|
| История | Сохраняется | Перезаписывается |
| Безопасность | Безопасен для published | Опасен для published |
| Аудит | Виден в log | Теряется |
Частые ошибки
- Откатить merge без
-m— Git не знает, какую родительскую ветку считать основной; нужен флаг-m 1 - Использовать
resetвместоrevertна публичной ветке — перезаписывает историю, коллеги получат конфликты при pull - Откатить коммит, от которого зависят другие — возникнут конфликты; revert применяет изменения в обратном порядке
- Не проверить результат revert — после
git revertзапусти тесты; иногда откат создаёт неожиданные состояния