Почему возникает конфликт при последовательном rebase двух веток на одну родительскую?

«Почему возникает конфликт при последовательном rebase двух веток на одну родительскую?» — вопрос из категории DevOps, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Конфликт возникает из-за того, что rebase перезаписывает историю коммитов. После перебазирования первой ветки на родительскую, её коммиты создаются заново. Когда вторая ветка пытается перебазироваться на ту же родительскую, её исходные коммиты основаны на старой истории, которая больше не существует, что приводит к конфликтам слияния.

Почему это происходит:

  1. Изменение родительских коммитов: rebase переносит коммиты, меняя их базовый коммит (parent).
  2. Расхождение истории: После первого rebase история родительской ветки и первой ветки изменилась, поэтому коммиты второй ветки не могут быть применены чисто.

Пример сценария:

# Исходное состояние:
# main:      A
# feature1:  A---B
# feature2:  A---C

git checkout feature1
git rebase main  # feature1 теперь: A---B' (B' — новый коммит)

git checkout feature2
git rebase main  # Конфликт! Коммит C пытается применить изменения,
                 # которые могли быть уже изменены в B'.

Решение: Вместо последовательного rebase лучше использовать merge для второй ветки или перебазировать вторую ветку на уже обновлённую первую (git rebase feature1).