Перейти к содержимому

git merge

Определение

Команда git merge объединяет независимые линии разработки в одну ветку. Она работает в связке с git checkout для выбора текущей ветки и git branch с флагом -d для удаления устаревших веток. Подробнее об этих командах читайте в наших предыдущих главах.

Как это работает

Основное назначение git merge — объединение двух веток. Она также используется для интеграции нескольких коммитов из одной ветки в другую. На следующей иллюстрации git merge берет концы двух веток и находит общий коммит-предок между ними. Общий базовый коммит используется для создания нового коммита слияния, который объединяет изменения из обеих веток. Здесь у нас две ветки: master и stage. Нам нужно объединить ветку stage в ветку master.

gitmerge

Коммиты слияния уникальны тем, что имеют два родительских коммита. Git автоматически объединяет отдельные истории при создании нового коммита слияния. Однако, если обе ветки изменяют одни и те же строки, Git не может сделать это автоматически, что приводит к конфликту слияния.

gitmerge1

Процесс слияния

Перед началом процесса слияния выполните следующие шаги:

  • Убедитесь, что вы находитесь в правильной ветке, которая будет принимать изменения. Выполните git checkout <receiving branch>, чтобы переключиться на неё.
  • Обновите целевую ветку последними изменениями с удаленного репозитория. Выполните git pull, чтобы получить и интегрировать последние удаленные коммиты.
  • Последний шаг — выполнение git merge <branch name>, которое указывает ветку, которую нужно объединить с принимающей веткой.

Быстрое слияние (Fast-forward merge)

Быстрое слияние (fast-forward merge) происходит, когда путь от текущей ветки к целевой ветке является линейным. При быстром слиянии истории объединяются, поскольку все коммиты, доступные из целевой ветки, становятся доступны через текущую ветку. Вот пример быстрого слияния:

gitmerge2

Когда две истории расходятся, Git использует 3-way merge в качестве альтернативы. 3-way merge использует отдельный коммит для объединения двух историй.

gitmerge3

Быстрые слияния обычно используются для небольших функций или исправлений ошибок, тогда как 3-way merge применяется для интеграции функций, разрабатываемых длительное время. В следующих примерах используется быстрое слияние:

git merge

bash
# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Merge in the stage branch
git checkout master
git merge stage
git branch -d stage

Мы запускаем git branch -d для удаления ветки stage, так как stage теперь доступна из ветки master.

Команда git merge с опцией --no-ff запускается, если вам нужен коммит слияния во время быстрого слияния для объединения указанной ветки с текущей, всегда создавая коммит слияния (даже в случае быстрого слияния):

git merge --no-ff

bash
git merge --no-ff <branch>

3-way merge

Этот сценарий требует 3-way merge, когда ветка master развивается, в то время как ветка stage все еще находится в разработке. Это используется, когда члены команды одновременно работают над крупной функцией:

команда git merge

bash
# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Develop the master branch
git checkout master
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to master"
# Merge in the stage branch
git merge stage
git branch -d stage

В приведенном выше примере stage представляет собой более крупную функцию, на разработку которой уходит много времени, поэтому мы используем 3-way merge. Если ваша функция небольшая, лучше использовать быстрое слияние, чтобы избежать загромождения истории проекта ненужными коммитами.

Разрешение конфликтов

При объединении двух веток, если одна и та же часть одного и того же файла изменена, возникают конфликты слияния, поскольку Git не может определить, какую версию использовать. В этом случае Git останавливается перед созданием коммита слияния, чтобы дать вам возможность разрешить конфликт. Процесс слияния Git использует рабочий процесс edit/stage/commit для разрешения конфликтов слияния. При возникновении конфликта выполнение git status отобразит файлы, которые необходимо разрешить. Ниже показан результат, когда были изменены одни и те же части файла example.txt:

git status

bash
On branch master
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: example.txt

Если вы решите не продолжать слияние, вы можете отменить его в любое время, выполнив git merge --abort.

Как отображаются конфликты

В случае конфликтов Git редактирует содержимое затронутых файлов, добавляя визуальные метки по обе стороны от конфликтного содержимого. Конфликты слияния возникают только при 3-way merge.

Основными маркерами являются <<<<<<<, ======= и >>>>>>>. Они помогают найти конфликтные участки в ваших файлах.

git conflicts

bash
here is some content not affected by the conflict
<<<<<<< master
this is conflicted text from master
=======
this is conflicted text from stage branch
>>>>>>> stage

После разрешения конфликтов выполните git add <file> для конфликтного файла, чтобы пометить его как разрешенный. Затем выполните git commit, чтобы создать коммит слияния.

Практика

Какие ключевые особенности и процессы связаны с командой 'git merge'?

Считаете ли это полезным?

Предпросмотр dual-run — сравните с маршрутами Symfony на продакшене.