Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое git revert?
git revert — это команда для отмены изменений из коммита путём создания нового коммита с противоположными изменениями. Это безопасный способ избавиться от ошибок в истории Git без переписывания истории.
Основное назначение
Когда вы сделали коммит и понимаете, что это была ошибка, у вас есть два пути:
- git reset — удалить коммит из истории (опасно в совместной разработке)
- git revert — создать новый коммит, который отменяет старый (безопасно и прозрачно)
Отличие от reset
git reset: История редактируется
❌ На shared branches опасно
✅ Локально безопасно
┌─────────────────────┐
Commit A (200 строк)
Commit B (ошибка)
Commit C
└─────────────────────┘
git reset --hard HEAD~1
┌─────────────────────┐
Commit A (200 строк)
Commit C (снова на A)
└─────────────────────┘
git revert: История расширяется
✅ На shared branches безопасно
✅ История полная и прозрачная
┌─────────────────────┐
Commit A (200 строк)
Commit B (ошибка)
Commit C
Commit D (отмена B) ← Новый коммит
└─────────────────────┘
Синтаксис
# Отменить последний коммит
git revert HEAD
# Отменить конкретный коммит
git revert abc1234
# Отменить несколько коммитов
git revert HEAD~2..HEAD # Отменяет 2 последних
# Отменить без автоматического commit сообщения
git revert --no-commit abc1234
Пример: отмена ошибочного коммита
$ git log --oneline
abc1234 Delete user.txt (ОШИБКА!)
def5678 Add user.txt
$ git revert abc1234
# Откроется редактор для сообщения коммита:
# Revert "Delete user.txt"
#
# This reverts commit abc1234.
$ git log --oneline
xyz9999 Revert "Delete user.txt"
abc1234 Delete user.txt
def5678 Add user.txt
Java проект: пример ошибки в коммите
Представьте, вы случайно сделали:
$ git commit -m "Optimize database query"
# Commit: 2f8a4c9
# Изменения:
# - UserRepository.findAll() переделан на другой алгоритм
# - Но забыли, что это ломает фильтрацию по датам
# Через день тесты падают в CI/CD
$ npm run test
# FAIL: User filtering by date returns wrong results
$ git revert 2f8a4c9 # Отменяем оптимизацию
Git revert в CI/CD
# На GitHub/GitLab этот процесс автоматизирован через UI
# Кнопка "Revert" на pull request создаёт PR с revert коммитом
# Или в командной строке:
$ git log --oneline
foo1111 Merge PR #123: Bug fix ← Хотим отменить
bar2222 Previous commit
$ git revert foo1111
# Создаст новый коммит с отменой
$ git push origin main
# Отправляем отмену на сервер
Конфликты при revert
Если кодовая база сильно изменилась, git revert может создать конфликты слияния:
$ git revert abc1234
# error: could not revert abc1234... Delete configuration
# hint: after resolving the conflicts, mark the resolved paths
# hint: with 'git add <paths>' and commit the changes.
# Смотрим конфликты
$ git status
# both deleted: config.yml
# Решаем вручную
$ git add config.yml
$ git revert --continue
Абортивание revert
# Если что-то пошло не так
$ git revert --abort
# Всё вернётся в исходное состояние
Сравнение reset vs revert vs checkout
| Команда | Что делает | История | Shared branch |
|---|---|---|---|
| reset | Удаляет коммиты | Переписывает | ❌ Опасно |
| revert | Создаёт отмену | Расширяет | ✅ Безопасно |
| checkout | Переключается на коммит | Не меняет | ✅ Безопасно |
Практический сценарий
Сценарий 1: Локальный коммит (не отправлен)
# Если никто не знает о коммите, можешь использовать reset
$ git reset --hard HEAD~1 # Удаляет последний коммит
Сценарий 2: Коммит на shared branch (отправлен)
# НИКОГДА не используй reset на shared branch!
# Это сломает историю для всех
$ git revert abc1234 # Безопасная отмена
$ git push origin main
Сценарий 3: Уже заммержен в main
# Если PR уже в main и это ошибка
$ git revert commit-id
# Создаёт новый коммит-отмену
$ git push origin main
# Все видят, что было отменено, и почему
Phabricator/Gerrit примеры
# В корпоративных системах с code review:
$ git revert -m 1 abc1234
# -m 1 — берёт в качестве родителя первый parent (в merge commits)
# Например, отмена merge коммита
$ git log --oneline
foo1111 Merge branch 'feature' into main
bar2222 Some commit
$ git revert -m 1 foo1111
# Отменяет только изменения из branch 'feature'
Git revert с параметрами
# Отменить несколько коммитов в одном
$ git revert -n abc1234 def5678
$ git commit -m "Revert two commits"
# Отменить коммит с custom сообщением
$ git revert -m "Custom message" abc1234
# Отменить без редактирования сообщения
$ git revert --no-edit abc1234
Примеры из реальных проектов
Linux kernel:
Revert "USB: gadget: fix undefined reference to usb_ep_autoconfig"
This reverts commit 9f7b87d...
The fix introduced new regressions, rolling back.
Kubernetes:
Revert "Fix memory leak in scheduler"
This revert is needed because the fix causes deadlocks
in high-load scenarios.
Лучшие практики
# ✅ Правило 1: Никогда reset на shared branch
# ✅ Правило 2: Используй revert для public истории
# ✅ Правило 3: Реvert сообщение должна быть ясной
# ✅ Хорошее revert сообщение
$ git revert abc1234 -m "Revert 'Add user validation'
This commit breaks login for SSO users.
Will be reimplemented in PR #456."
# ❌ Плохое
$ git revert abc1234 # No message - confusing
Когда использовать что?
# Используй reset, когда:
# - Коммит ещё локальный
# - Никто не вытащил ваш branch
# - Хочешь переписать историю
# Используй revert, когда:
# - Коммит уже отправлен (push)
# - Branch совместный (shared)
# - Нужно отменить, сохраняя историю
# - Нужна полная прозрачность об ошибке
Интеграция с IDE
IntelliJ IDEA:
В Git log → правый клик на коммит → Revert Commit
VS Code:
Source Control → Commits → правый клик → Revert this Commit
Итог: git revert — это безопасный способ отмены коммитов в shared branches. Он создаёт новый коммит, который отменяет старый, сохраняя полную историю. Это делает историю прозрачной и предотвращает проблемы при совместной разработке. На локальных branches можно использовать git reset, но на shared branches (main, master, develop) всегда используй git revert.