Что произойдет при выполнении git merge без возникновения конфликтов

Конфликты слияния в Git

Системы контроля версий предназначены для управления дополнениями, вносимыми в проект множеством распределенных авторов (обычно разработчиков). Иногда один и тот же контент могут редактировать сразу несколько разработчиков. Если разработчик A попытается изменить код, который редактирует разработчик B, может произойти конфликт. Для предотвращения конфликтов разработчики работают в отдельных изолированных ветках. Основная задача команды git merge заключается в слиянии отдельных веток и разрешении любых конфликтующих правок.

Общие сведения о конфликтах слияния

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

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

Типы конфликтов слияния

Конфликт во время слияния может произойти в двух отдельных точках — при запуске и во время процесса слияния. Далее рассмотрим, как разрешать каждый из этих конфликтных сценариев.

Git прерывает работу в самом начале слияния

Git прерывает работу во время слияния

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

Создание конфликта слияния

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

С помощью приведенной в этом примере последовательности команд выполняются следующие действия.

Представленная выше последовательность команд выполняет следующие действия.

БАХ! 💥 Возник конфликт. Хорошо, что система Git сообщила нам об этом.

Выявление конфликтов слияния

Вывод команды git status говорит о том, что из-за конфликта не удалось слить пути. Теперь файл merge.text отображается как измененный. Давайте изучим этот файл и посмотрим, что изменилось.

Разрешение конфликтов слияния с помощью командной строки

Самый простой способ разрешить конфликт — отредактировать конфликтующий файл. Откройте файл merge.txt в привычном редакторе. В нашем примере просто удалим все разделители конфликта. Измененное содержимое файла merge.txt будет выглядеть следующим образом:

Git обнаружит, что конфликт разрешен, и создаст новый коммит слияния для завершения процедуры слияния.

Команды Git, с помощью которых можно разрешить конфликты слияния

Общие инструменты

Команда status часто используется во время работы с Git и помогает идентифицировать конфликтующие во время слияния файлы.

Команда diff помогает найти различия между состояниями репозитория/файлов. Она полезна для выявления и предупреждения конфликтов слияния.

Инструменты для случаев, когда Git прерывает работу в самом начале слияния

Команда checkout может использоваться для отмены изменений в файлах или для изменения веток.

Команда reset может использоваться для отмены изменений в рабочем каталоге или в разделе проиндексированных файлов.

Инструменты для случаев, когда конфликты Git возникают во время слияния

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

Резюме

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

Готовы попробовать ветвление?

Ознакомьтесь с этим интерактивным обучающим руководством.

Источник

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

Azure Repos | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018-TFS 2015

Visual Studio 2019 | Visual Studio 2017 | Visual Studio 2015

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

Из этого руководства вы узнаете, как выполнить следующие задачи:

Общие сведения о конфликтах слияния

На следующем рисунке показан самый простой пример конфликта изменений в Git. Обе ветви Main и бугфикс обновляют одни и те же строки исходного кода.

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

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

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Наиболее распространенной ситуацией конфликта слияния является случай, когда вы извлекаете обновления из удаленной ветви в локальную ветвь, например из origin/bugfix в локальную bugfix ветвь. Разрешите эти конфликты аналогичным образом — создайте фиксацию слияния в локальной ветви, чтобы согласовать изменения и завершить слияние.

Что делает Git для предотвращения конфликтов слияния?

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

Предотвращение конфликтов слияния

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

Если вы используете Visual Studio 2019 версии 16.8 или выше, опробуйте систему управления версиями Git. Узнайте, чем интерфейс Git отличается от Team Explorer, на странице наглядного сравнения.

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

Появится уведомление о конфликте. Щелкните ссылку » конфликты «, чтобы начать устранение конфликтов файлов.

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Будет приведен список файлов с конфликтами. Выбор файла позволяет принять изменения в исходной ветви, из которой выполняется слияние, с помощью кнопки взять источник или принять изменения в ветви, в которую выполняется слияние, с помощью команды » оставить цель«. Можно выполнить слияние изменений вручную, выбрав объединить, а затем введя изменения непосредственно в средство слияния, указанное в параметрах Git.

Используйте флажки рядом со строками, измененными для выбора между удаленными и локальными изменениями, или измените результаты непосредственно в редакторе результатов в исходном и целевом редакторе в представлении diff.

Откройте представление изменения в Team Explorer и зафиксируйте изменения, чтобы создать фиксацию слияния и разрешить конфликт.

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

сравните конфликтующие фиксации, а также различия между общим журналом с параметрами в средстве слияния Visual Studio.

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

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

Раздел является изменениями из одной фиксации, ======= отделяет изменения и >>>>>>> для другой конфликтующей фиксации.

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

Разрешение конфликтов при удалении файлов с помощью git add (сохранения файла) или git rm (удаление файла).

Источник

Команда Git Merge

В какой-то момент история репозитория ветвится. Например, в проекте требуется пофиксить баг — обычно это выполняют в отдельной ветке, а потом сливают в основную ветку master. Команда git merge как раз и служит для слияния веток.

Пример использования

Допустим, есть основная ветка master. И есть ветка hotfix, в которой мы фиксим баг. Мы его пофиксили и хотим слить изменения в ветку master. Для этого надо перейти на ветку master — ту ветку, в которую сливают изменения:

И залить изменения из ветки hotfix в текущую ветку master:

Это типичный пример использования команды.

Но не всегда слияние происходит гладко. Пока мы делали hotfix, кто-то мог отредактировать тот же файл в том же месте, что и мы. Тогда слияние не удается, возникает конфликт.

Конфликт слияния

Допустим, файл index.html отредактировал кто-то еще в том же месте. Тогда при попытке выполнить команду merge мы получим сообщение:

Что же делать? Если открыть index.html, мы увидим, что Git его пометил примерно так:

Надо удалить разметку в файле и оставить только один вариант спорной строки. После этого нужно добавить конфликтный файл в индекс:

На этом все, конфликт будет разрешен.

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

Продвинутые сценарии git merge

Параметр —no-commit

Бывают ситуации, когда история снимков (ряд команд commit) в ветке была сделана не очень осмысленно, то есть вы делали снимки состояний, которые не стоит сохранять в истории на всеобщем обозрении. Здесь то и пригодится параметр —no-commit. Он используется нечасто — только в том случае, если хочется уничтожить историю снимков ветки, так чтоб никто их никто никогда не увидел и к ним нельзя было вернуться.

Но сначала вернемся к вышеприведенным командам и рассмотрим, как работает merge без параметра:

Первая команда (checkout) переведет нас на ветку master. Это значит, что наша папка на диске физически заполнятся версиями файлов из ветки master

Теперь рассмотрим, как работает команда merge с параметром.

Первый шаг такой же — переходим на ветку master, в которую надо залить изменения:

Но в этот раз допустим, что снимки в ветке hotfix были ненужными и мы хотим, чтоб их не было в истории. В этом случае надо добавить параметр —no-commit:

Эта команда обновит текущие папки — перенесет в них все изменения ветки hotfix, но финального снимка сделано не будет. Мы сможем еще кое-что поменять в файлах и потом выполнить команду commit самостоятельно. При этом в историю попадет только финальный снимок. Будет видно, что ветка hotfix слита с веткой master, и все. А снимки ветки hotfix видны не будут.

Параметр —squash

Эта команда такая же, как предыдущая, разница будет только при просмотре истории. Перейдем на ветку master, в которую мы хотим залить изменения:

После выполнения команды:

изменения появятся в текущих папках ветки master, аналогично тому, как это было после выполнения предыдущей команды с аргументом —no-commit. При этом финального снимка (commit) так же не произойдет.

Но затем после самостоятельного выполнения команды commit мы увидим в истории этот снимок как самый обычный снимок в ветке master. То, что ветка hotfix сливалась в ветку master, отображено в истории не будет.

Параметр —no-ff

Параметр —no-ff запрещает перемотку.

ff означает fast forward, то есть перемотка.

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

На картинке мы ответвились от С и сделали снимки X и Y. После снимка C в ветке master никто ничего не делал, и при слиянии указатель просто переместится на снимок Y:

Еще раз обратите внимание, что в ветке master после ответвления от С снимков не появилось, именно поэтому перемотка и возможна.

С помощью аргумента —no-ff можно запретить перемотку, а именно: сделать при слиянии новый отдельный снимок, хоть в нем и нет технической необходимости. Сделаем это:

На картинке это выглядит так:

Будет создан дополнительный снимок M и указатель переместится на него (хотя мог бы просто переместиться на Y, если б выполняли слияние без параметра —no-ff).

Когда именно стоит использовать параметр —no-ff сказать сложно — отчасти это вопрос вкуса. Некоторые любят делать отдельный снимок при любом важном слиянии.

Источник

Git merge

Порядок действий

Команда git merge объединяет несколько последовательностей коммитов в общую историю. Чаще всего команду git merge используют для объединения двух веток. Этот вариант слияния рассматривается в следующих примерах. В таких случаях команда git merge принимает два указателя на коммиты (обычно последние в ветке) и находит общий для них родительский коммит. Затем Git создает коммит слияния, в котором объединяются изменения из обеих последовательностей, выбранных к слиянию.

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

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

Подготовка к слиянию

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

Проверка выбора принимающей ветки

Получение последних коммитов из удаленного репозитория

Выполнение слияния

Ускоренное слияние

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

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Однако выполнить ускоренное слияние не получится, если ветки после разделения развивались независимо друг от друга. Если до целевой ветки нет прямого пути, Git будет вынужден объединить их методом трехстороннего слияния. Такое слияние выполняется с помощью специального коммита, который служит для объединения двух историй. Метод называется трехсторонним, поскольку Git использует три коммита для создания коммита слияния (последние коммиты двух веток и общий родительский элемент).

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

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

В первом примере демонстрируется ускоренное слияние. С помощью кода создается новая ветка, после чего в нее добавляется два коммита. Затем она включается в основную ветку посредством ускоренного слияния.

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

Эта команда выполнит объединение указанной ветки с текущей с обязательным созданием коммита слияния (даже если слияние будет ускоренным). Это полезно для учета всех слияний в репозитории.

Трехстороннее слияние

Следующий пример похож на предыдущий, но в нем слияние должно быть трехсторонним, поскольку работа над веткой main ведется одновременно с работой над функцией. Так часто происходит в случае объемных функций или когда над одним проектом одновременно работают несколько разработчиков.

Обратите внимание, что Git не может выполнить ускоренное слияние, потому что невозможно перенести указатель main на ветку new-feature без использования предыдущих коммитов.

В большинстве случаев ветка new-feature отводится под более объемные функции с продолжительным временем разработки, за которое в ветке main появляются новые коммиты. Если бы реальный размер вашей функциональной ветки был так же мал, как в приведенном выше примере, было бы проще перебазировать ее на ветку main и выполнить ускоренное слияние. В этом случае не потребовалось бы засорять историю проектов лишними коммитами слияния.

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

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

Представление конфликтов

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

Обычно содержимое перед отметкой ======= относится к принимающей ветке, а все, что указано после нее, — к ветке, для которой выполняется слияние.

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

Резюме

Готовы попробовать ветвление?

Ознакомьтесь с этим интерактивным обучающим руководством.

Источник

Что произойдет при выполнении git merge без возникновения конфликтов

Безболезненное разрешение Merge конфликтов в Git.

В моей повседневной работе, часто приходится иметь дело со множеством git ветвей (branch). Это могут быть ветви промежуточных релизов, ветви с устаревшим API находящиеся на поддержке для некоторых клиентов, или ветви с экспериментальными свойствами. Лёгкость создания ветвей в модели Git так и соблазняет разработчиков создавать все больше и больше ветвей, и как правило бремя от большого количества ветвей становится очень ощутимым, когда приходится все эти ветви поддерживать и периодически делать слияния (merge) с другими ветвями.

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

Удивительно, но я обнаружил, что многие доступные инструменты и интерфейсы предназначенные для выполнения слияний, не достаточно хорошо оснащены для эффективного выполнения этого процесса. Часто программист просто надеется что команда git merge сделает за него всю работу. Но когда все-таки происходит конфликт, то обычно стратегия слияния заключается в беглом просмотре кода вокруг строки конфликта, и интуитивном угадывании что именно данный кусок кода предпочтительней другого.

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

Голубые Розы (Roses are Blue)

Ого, это конфликт. Вы решаете просмотреть файл на который ссылается git:

Замечательно! Весь файл, как показывает Listing 1, находится в конфликтном состоянии. Какой же вариант файла является более корректным? Оба варианта выглядят корректно. Верхний вариант написан в хакер-стиле с элементами цветовой кодировки в стиле HTML и с использованием только строчных букв. Нижний вариант выглядит более натурально, с использованием пунктуации и заглавных букв.

Если бы это был ваш проект, вы бы могли просто выбрать один вариант и покончить с этим слиянием. Но проблема в том, что это не ваша поэма, вы никогда не читали эту поэму раньше, не были ответственны за написание или редактирование, и вы отлично понимаете что в случае не верного решения чья-то тяжёлая работа может кануть в небытие. Однако вас всё же назначили ответственным по слиянию этих веток. Что же вам делать?

Назад к Базе (Back to Base)

Хитрость заключается в том, что Listing 1 не даёт вам полную информацию, необходимую для совершения корректного слияния. На самом деле, в процессе слияния участвуют четыре важных части информации (состояния), три из которых просто необходимы для успешного разрешения конфликта. В случае Listing 1, Git предоставил вам только два состояния.

Следующая диаграмма иллюстрирует эти четыре состояния:

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Состояния (B) и (C) относятся к текущим положениям (head) веток master и beta соответственно, эти два состояния как раз таки и отражены в Listing 1. Состояние (D) это результат слияния, то что вы хотите получить/сгенерировать в конечном итоге (в большинстве случаев Git автоматически генерирует состояние (D)). Состояние (А) на самом верху, представляет собой базу (основу) слияния веток master и beta. База слияния (A) это последний общий предок веток master и beta, и пока предположим что это база слияния уникальна. Как мы увидим позже состояние (A) играет ключевую роль в разрешении конфликтов. На диаграмме я также отразил дельты 1 и 2, которые представляют изменения между состояниями (A)-(B), и (A)-(C) соответственно. Зная состояния (A), (B) и (C) дельты 1 и 2 могут быть легко получены (вычислены). Обратите внимание, что дельты 1 и 2 могут состоять из более чем одного коммита. Но для наших целей будем считать что все дельты монолитны.

Чтобы понять, как получить состояние (D), вы должны понимать что же операция слияния пытается сделать. Состояние (D) должно представлять собой сочетание изменений, внесённых в ветку master и beta соответственно. Т.е. другими словами сочетание дельт 1 и 2. Идея проста на поверхности и большую часть времени не требует вмешательства со стороны человека, за исключением особых случаев когда дельты затрагивают наслаиваемые (пересекающиеся) части файла. В такой ситуации вам требуется помочь машине сгенерировать результат (D), путём сравнения дельт 1 и 2.

Определение Отличий (Identifying the Differences)

Для того чтобы найти изменения внесённые в каждую ветку, необходимо знать как выглядит база слияния, состояние (A). Самый простой механизм получения информации о базе слияния, это установка опции merge.conflictstyle в значение diff3

Теперь мы видим третий фрагмент посередине, который и является базой слияния или состояние (A). Изменения видны как на ладони: в ветке beta (HEAD) человеческие названия цветов были заменены на HTML коды, а в ветку master добавили капитализацию и пунктуацию. Основываясь на этих знаниях, мы теперь знаем что результат должен включать в себя капитализацию, пунктуацию и HTML коды цветов.

В принципе на этом можно было бы и закончить, потому что результат достигнут. Но есть решение и получше.

Графическое Слияние (GUI Merging)

Хотя и простое текстовое представление конфликта слияния делает свою работу в простых случаях, на практике конфликты могут быть более радикальными и сложными. В таких случаях могут помочь графические инструменты. Мой выбор пал на простой инструмент написанный на Python под названием meld, но может подойти любой другой графический инструмент, способный представить слияние в трёх-колоночном виде.

Для использования графического инструмента (он должен быть установлен), после того как git пожаловался что есть конфликт, введите следующую команду:

Последует вопрос какой программой для слияния вы хотели бы воспользоваться, просто введите meld и нажмите Enter. Вот как окно программы может выглядеть (подразумевается опция merge.conflictstyle не была включена):

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Несмотря на то что информация представлена бок о бок, она не отображает нужные фрагменты которые были в Listing 2. Мы не видим здесь фрагмента базы слияния (состояния (A)), что мы видим это файл roses.txt.LOCAL.2760.txt в левой колонке и файл roses.txt.REMOTE.2760.txt в правой колонке и файл посередине это неудачное слияние. Т.е. по сути нам представили состояния (B), (C) и несостоявшееся состояние (D), но состояние (A) отсутствует.

Правда отсутствует? Давайте проверим, в старом добром терминале:

Видим интересующий нас файл: roses.txt.BASE.2760.txt. Это и есть файл базы слияния. Теперь нам осталось всего лишь найти изменения внесённые в ветки master и beta, по отношению к базе. Мы можем сделать это двумя отдельными вызовами meld:

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтовЧто произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

При чтении первого окна справа налево и второго окна слева направо, становится ясно как день, какие изменения произошли в каждой ветке. Так как meld любезно подсветил все изменения, теперь практически не возможно пропустить даже мелко заметные правки (Кто-нибудь заметил добавление предлога «of» при просмотре текстового представления разрешения конфликта Listing 1 или даже Listing 2?)

Вооружившись этими знаниями, мы теперь можем вернуться к трёх-колоночному представлению и сделать изменения. Моя стратегия ручного слияния это взять весь текст из ветки с более весомыми изменениями (в данном случае master/REMOTE т.е. beta), и поверх него производить пошаговые правки, т.е. вносить изменения сделанные в другой ветке (master). Вот что получилось:

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

А теперь всё вместе (All Together Now)

И добавьте следующее в ваш

Теперь, когда вы в следующий раз будете запускать команду git mergetool для разрешения конфликта, откроются все три окна:

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

Бонус от переводчика

Для тех кто пользуется tmux и n?vim, предлагаю следующий скрипт gitmerge:

Соответственно добавьте следующее в ваш

Воркфлоу разрешения конфликта будет выглядеть так:

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Пока игнорируем вопрос (Was the merge successful [y/n]?) и переключаемся в сессию под названием gitmerge (сочетание TMUXPREFIX + s):

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Видим наше трёх-оконное представление на одном экране. Цифрами обозначены сплиты (panes) tmux’a, буквами соответствующие состояния. Делаем правки для разрешения конфликта, т.е. редактируем состояние (D) и сохраняем. После этого возвращаемся обратно в исходную сессию tmux’a и подтверждаем что слияние произошло успешно.

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Лично я предпочитаю и считаю более правильным делать сначала rebase master в ветке beta, и только после этого переключаться в master и делать git merge beta. В принципе воркфлоу не сильно отличается, за исключением трёх-оконного вида.

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Переключаемся в сессию gitmerge

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Обратите внимание, что состояния (B) и (C) поменялись местами:

Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть фото Что произойдет при выполнении git merge без возникновения конфликтов. Смотреть картинку Что произойдет при выполнении git merge без возникновения конфликтов. Картинка про Что произойдет при выполнении git merge без возникновения конфликтов. Фото Что произойдет при выполнении git merge без возникновения конфликтов

Рекомендую всем поиграться с примером репозитария хотя бы один раз, сделать разрешение конфликта по вышеописанной схеме. Лично я больше не гадаю а что же выбрать «Accept theirs» или «Accept yours» 🙂

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *