Что такое конфликты слияния?

Завершено

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

Поток GitHub

Помимо создания платформы для совместной разработки программного обеспечения, GitHub также предлагает предписанный рабочий процесс, предназначенный для оптимизации использования различных функций. Хотя этот модуль посвящен конкретно запросам на вытягивание, рекомендуется сначала ознакомиться с модулем, посвященным общим сведениям о потоке GitHub.

Слияние ветвей

Рассмотрим ситуацию, когда разработчик создает ветвь с именем feature-branch на основе main, а затем создает две фиксации. По мере выполнения этой работы другой пользователь объединяет несвязанный запрос на вытягивание с main. Что происходит, когда наш разработчик пытается выполнить обратное слияние feature-branch и main?

Ответ: зависит от ситуации.

Хотя feature-branch он был создан из main, он не был основан на самой ветви. Вместо этого она была основана на фиксации HEADmain в тот момент. С тех пор не известно обо всех фиксациях, к которым были применены main . Фиксации, которые он отслеживает в настоящее время, не обязательно собираются сворачивать в текущее состояние ветви без перезаписи последних изменений.

Если оказывается, что feature-branch фиксации не перекрываются параллельными фиксациями, сделанными main с момента создания ветви, то нет проблем. Можно будет добавить новые файлы. Нетронутые файлы можно будет удалить. Строки кода, которые были изменены в main, можно изменить в feature-branch, если над ними не выполнялась параллельная работа с момента создания feature-branch.

A pull request with no merge conflicts.

Но что делать, если оба набора фиксаций содержат изменения в одних и тех же строках кода? Попытка слияния завершится сбоем из-за конфликта слияния.

A merge conflict.

Что такое конфликты слияния?

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

A pull request with merge conflicts.

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

Чтобы помочь в разрешении конфликт слияния, GitHub создает временный гибридный файл, содержащий различия между каждой ветвью. Обычно текст из ветви сравнения отображается над базовой ветвью, а разделяются они строкой знаков равенства (=======).

Resolving a merge conflict.

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

Примечание.

В этом уроке обсуждается разрешение конфликтов слияния в контексте браузера. Существует также множество платформ разработки, таких как Visual Studio, которые предлагают интегрированные возможности разрешения конфликтов слияния.

После разрешения всех конфликт слияния в ветви можно повторить слияние.

Избежание конфликтов слияния

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

Вытягивайте как можно раньше и чаще

Команда git pull извлекает все базовая ветвь фиксации, которые еще не применены к текущей ветви. Она концептуально напоминает команду Получить последнюю, которая используется многими системами управления версиями для обновления локального кода до последней версии. При извлечении обновлений для ветви вы можете объединить все изменения, произошедшие с момента создания ветви (или после последнего извлечения).

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

Помимо снижения последствий конфликтов слияния, вытягивание обновлений также позволяет интегрировать зафиксированные изменения в вашу ветвь по ходу работы. Это позволяет решать потенциальные проблемы ранее. Например, в других файлах может быть изменено определение класса, что приведет к тому, что код больше не компилируется. Это изменение не приведет к конфликт слияния при объединении позже, но это приведет к прерыванию сборки, если вы не протестировали его сначала. Рекомендуется вытягивать обновления часто, чтобы ваша ветвь оставалась близкой к своей базе.

Очистка журнала с помощью перемещения Git

Команда git rebase (или git pull --rebase) перезаписывает журнал ветви, чтобы использовать фиксацию HEAD базовой ветви в качестве его основы. Другими словами, ваша ветвь обновляется так, как будто она была ветвлена только из текущего состояния базовая ветвь. Эта перебаза означает, что все изменения сравниваются с последним состоянием базовая ветвь, а не исходной фиксацией, от которую вы изначально ветвились. Повторное масштабирование может упростить отслеживание журнала после окончательного слияния, так как ваши фиксации будут следовать предыдущим параллельным фиксациям в линейной форме. Рекомендуется переместить изменения в вашу ветвь, немедленно перед слиянием с вышестоящей.

Дополнительные сведения о перемещении изменения из одной ветви в другую в Git и разрешении конфликтов слияния после перемещения между ветвями в Git.