Отмена объединения коммитов в Git: руководство с примерами

Мы можем компрометировать приложение,合并有问题的代码, будь то случайная интеграция незавершенной работы в основную ветку или疏忽自动测试漏过的关键错误.

В этой статье я проведу вас через процесс использования 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 обратно в то место, где он был. Для этого мы:

  1. Идентифицируем предыдущий HEAD с помощью git reflog
  2. Сбросьте 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

Решение конфликтов при откатах коммитов

Иногда при откатах коммитов могут возникнуть конфликты, особенно если откатываемый коммит конфликтует с более поздними изменениями в коде. В таких случаях:

  1. Git приостановит откат: Нам нужно вручную разрешить конфликты. Git пометит конфликтующие файлы и потребует вмешательства.
  2. Разрешите конфликты: Мы открываем каждый конфликтующий файл, разрешаем конфликты, помеченные Git, и сохраняем изменения.
  3. Установите разрешенные файлы в индекс: git add <path-to-file>
  4. Продолжите откат: git revert --continue

Заключение

Использование git revert для отката слияний коммитов обеспечивает документирование каждого изменения и исправления в истории коммитов.

Кроме того, понимание подходящих сценариев для применения git reset по сравнению с git revert позволяет нам принимать более обоснованные решения, особенно при рассмотрении совместных рабочих процессов или локальных изменений.

Вы можете узнать больше об этой теме в разделе FAQ ниже. Если вы хотите узнать больше о Git, я рекомендую следующие ресурсы:

Source:
https://www.datacamp.com/tutorial/git-revert-merge