Что такое merge (слияние) в Git?

«Что такое merge (слияние) в Git?» — вопрос из категории DevOps, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

git merge — это команда Git для интеграции изменений из одной ветки в другую. Она объединяет истории разработки, создавая новый коммит слияния (merge commit), который имеет двух родителей.

Основные типы слияния:

  1. Fast-forward merge (Быстрая перемотка):

    • Когда происходит: Если целевая ветка (например, main) не имеет новых коммитов с момента создания ветки-источника (например, feature).
    • Что делает: Git просто перемещает указатель целевой ветки вперед, к последнему коммиту ветки-источника. Коммит слияния не создается.
      # Визуализация: main -> A - B - C (feature)
      git checkout main
      git merge feature  # Указатель main теперь указывает на коммит C
  2. Recursive merge (3-way merge, Рекурсивное слияние):

    • Когда происходит: Если в целевой ветке появились новые коммиты, и истории разошлись.
    • Что делает: Git находит общего предка (common ancestor) двух веток и создает новый коммит слияния, который объединяет изменения из обеих веток.
      # Визуализация: main -> A - B - D
      #               feature -> A - B - C
      git checkout main
      git merge feature  # Создается новый коммит слияния E, родители: D и C

Разрешение конфликтов слияния: Если одни и те же строки в одном файле были изменены в обеих ветках, Git не может автоматически решить, какое изменение оставить. Он помечает файл как конфликтующий.

# После команды merge, если есть конфликт:
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.

Вам нужно вручную отредактировать файл, выбрать нужные изменения (или оставить оба), а затем завершить слияние:

git add file.txt  # Помечаем конфликт как разрешенный
git commit         # Завершаем создание коммита слияния

Сравнение с git rebase:

  • merge сохраняет полную историю с ветвлениями, что может быть нагляднее, но "загромождает" историю коммитами слияния.
  • rebase "перемещает" ваши коммиты на вершину целевой ветки, создавая линейную историю, но переписывает историю, что может быть опасно для уже опубликованных веток.