Мы можем компрометировать приложение,合并有问题的代码, будь то случайная интеграция незавершенной работы в основную ветку или疏忽自动测试漏过的关键错误.
В этой статье я проведу вас через процесс использования git revert
, чтобы безопасно откатить слияние, обеспечивая сохранность истории коммитов и целостности проекта.
Как работает git revert
Мы можем рассматривать git revert
как команду undo в Git. Однако команда git revert
не удаляет коммиты или не переходит в предыдущее состояние ветки. Вместо этого она создает новый коммит, который отменяет изменения из определенного коммита.
Синтаксис для отката коммита с хэшем <commit_hash>
:
git revert <commit_hash>
Мы можем перечислить коммиты вместе с их хэш-идентификаторами, используя команду git log
. Вывод git log
перечисляет коммиты от самого свежего до самого старого, вот так:
Например, чтобы откатить коммит, который внедряет функцию вычитания, мы бы использовали команду:
git revert 7ba24a3e62d4d37182428ccfaa070baa222b1151
Используя git revert
, мы можем отменить изменения определенного коммита, не затрагивая историю коммитов.
Обратите внимание, что git revert
не является магическим средством, и в зависимости от истории коммитов, это может привести к конфликту, который необходимо разрешить вручную.
Преимущества git revert
перед 手动ными изменениями
Почему git revert
полезен, если нам может потребоваться разрешить конфликт вручную? Разве не проще было бы просто вручную取消 изменения? Давайте рассмотрим его преимущества:
- Сохраняет историю:
git revert
создает новый коммит, который отменяет изменения определенного коммита, сохраняя при этом всю историю коммитов. Это помогает поддерживать прозрачную историю изменений и откатов. - Атомарное откатывание: Оно обеспечивает атомарность и一致性 отмены. Когда мы вручную удаляем и коммитим изменения, существует риск ошибок человека.
- Осведомленность о конфликтах: Оно ensures, что мы информируемся о конфликтах, если есть какие-либо интеграции или изменения, зависящие от исходного коммита. Это может показаться неудобным, но это protects от нежелательных побочных эффектов.
- Метаданные: Новый коммит, созданный
git revert
, включает метаданные и.message коммита, контекстуально описывающий, что было отменено, что помогает в будущем понимании. Безgit revert
этот контекст может быть утрачен.
Откатывание слияния в различных сценариях
В этом разделе мы узнаем, как отменить слияние. Для примера предположим, что мы слияние ветки feature
в ветку main
, выполняем команду из ветки main
:
git merge feature
Что мы здесь узнаем, можно применить к любым двум веткам, заменив имена соответствующим образом.
Отката слияния, не связанного с коммитом
Команда git merge
не всегда создает новый коммит. Коммит создается только если ветка main
отклонилась от ветки feature
. Потому что команда git revert
требует коммит для своей работы, мы не можем использовать её в этом случае.
Ветки main
и feature
отклоняются, когда на main
создаются новые коммиты, которые не являются предками ветки feature
. Другими словами, новые коммиты были созданы на main
после создания feature
.
Если ветки не отклонились, при выполнении команды git merge feature
на ветке main
, Git использует быстрое продвижение для слияния. Это означает, что он передвигает HEAD
ветки main
к HEAD
ветки feature
.
Мы можем观察到 это, посмотрев на результат git merge
:
Чтобы отменить такое слияние, нам нужно всего лишь переместить HEAD
ветки main
обратно в то место, где он был. Для этого мы:
- Идентифицируем предыдущий
HEAD
с помощьюgit reflog
- Сбросьте
HEAD
на предыдущий, используяgit reset --hard <предыдущий_hea>
, заменив<предыдущий_hea>
на предыдущийHEAD
.
Вывод команды git reflog
будет выглядеть примерно так:
Мы можем определить предыдущий HEAD
, посмотрев на строку, которая гласит “checkout: moving from feature to main” (она пишет feature
и main
, потому что это имена наших веток).
В этом случае, предыдущий заголовок это fe59838
. Чтобы переместить HEAD
основной ветки обратно к нему и отменить слияние, мы используем команду:
git reset --hard fe59838
Отмена слияния с связанным коммитом
Если ветки main
и feature
разошлись, то при слиянии двух веток создается новый коммит, называемый коммитом слияния.
Коммит слияния применяет изменения одной ветки к другой. В этом случае, изменения в feature
применяются к main
ветке.
Чтобы отменить изменения на main
ветке, мы используем git revert
на коммите слияния. Это создаст новый коммит, который отменит изменения, внесенные в main
ветку при слиянии, эффективно Restoreив состояние основной ветки до того, что было до слияния.
Во-первых, нам нужно определить хэш слияния коммита. Мы можем сделать это, используя команду git log
:
Потому что у слияния коммита есть два родителя, синтаксис git revert
немного отличается. Нам нужно использовать опцию -m 1
, чтобы указать, что мы хотим откатить изменения relative к ветке main
:
git revert -m 1 b8dab2c8611e324ed0d273133987415350e6d10d
Решение конфликтов при откатах коммитов
Иногда при откатах коммитов могут возникнуть конфликты, особенно если откатываемый коммит конфликтует с более поздними изменениями в коде. В таких случаях:
- Git приостановит откат: Нам нужно вручную разрешить конфликты. Git пометит конфликтующие файлы и потребует вмешательства.
- Разрешите конфликты: Мы открываем каждый конфликтующий файл, разрешаем конфликты, помеченные Git, и сохраняем изменения.
- Установите разрешенные файлы в индекс:
git add <path-to-file>
- Продолжите откат:
git revert --continue
Заключение
Использование git revert
для отката слияний коммитов обеспечивает документирование каждого изменения и исправления в истории коммитов.
Кроме того, понимание подходящих сценариев для применения git reset
по сравнению с git revert
позволяет нам принимать более обоснованные решения, особенно при рассмотрении совместных рабочих процессов или локальных изменений.
Вы можете узнать больше об этой теме в разделе FAQ ниже. Если вы хотите узнать больше о Git, я рекомендую следующие ресурсы: