Предыдущий ролик Следующий ролик  

Видео урок: Конфликты при слиянии

Git: обучение основам

Теперь мы знаем, как влить один бранч в другой, и Git действительно хорошо реализует слияние. Например, допустим, у нас есть файл index.html, и в мастер-бранче мы сделали изменение вверху файла index.html, где-то вверху html файла мы ввели изменение. И у нас есть другой бранч, с которым мы хотим сделать слияние, и мы сделали изменение внизу файла index.html. Это не проблема для Git. Git видит эти изменения, он распознает номера строк и понимает, что они не расположены рядом, он берет эти два набора изменений и включает их в один составной документ.

Наличие двух версий одного документа - это не проблема в большинстве случаев. Однако конфликт возникает тогда, когда есть два изменения в одной строке или наборе строк в двух разных коммитах потому что тогда Git не может решить, какое из них использовать или как объединить их, и тогда появляется конфликт при слиянии. Разрешение конфликтов при слиянии является важной задачей при работе с бранчами. Давайте сначала поговорим, что это за конфликты, а затем изучим, как их решать. Вот простой пример, допустим, у нас есть основной бранч, и у нас есть строка где-то в одном из наших HTML файлов, это строка окружена тегами <span>.

Из основного бранча мы создаем новый бранч, назовем его new_styles. Сюда мы внесем некоторые изменения. Здесь у нас есть все коммиты, и в это же время мы переключимся на основной бранч, и здесь также сделаем некоторые изменения. Одно из изменений, которое мы коммитим в мастер-бранч, заключается в том, что мы меняем теги <span> на теги <strong>, а затем мы сделаем еще больше коммитов, переключаемся на new_styles, и сделаем еще и тут несколько коммитов. В какой-то момент мы редактируем бранч new_styles, меняя теги <span> на теги <em>. Итак, у нас есть две разные версии этой строки. В основном бранче здесь стоят теги <strong>, а в бранче new_styles стоят теги <em>.

Если мы хотим объединить new_styles с основным бранчем, Git не знает, какой из них мы предпочитаем. Git говорит, что он не может выбрать между ними. Он не знает, чего мы хотим, так что нам нужно ему об этом четко сказать. Так что Git пометит конфликт и будет ждать, пока вы не решите проблему. Давайте попробуем это сделать в нашем проекте explore_california. Для генерации конфликта я использую страницу mission.html, давайте ее быстренько откроем и посмотрим. А теперь я хочу создать конфликт при слиянии вот в этом тексте. Чтобы сделать это, нам нужно создать условия, которые позволят этому случиться.

Во-первых, давайте создадим новый бранч, итак, git checkout -b text_edits. Помните, checkout -b - это чекаут в качестве нового бранча, или создание бранча и переключение на него. Теперь в новом бранче открываем mission.html, и это бранч text_edit, идея здесь заключается в том, что в бранче будут сделаны изменения в тексте. Я прокручиваю вниз до данного блока текста, и давайте внесем сюда некоторые изменения. "We are passionate about Californian preserving the abundant resources that make it so unique. Our goal at Export California is transform your vacation into adventure that will educate, inspire, and energize you unlike any other".

Давайте уберем unlike any other, оставим просто energize you. Все нормально, это изменение находится на строке 65. Теперь давайте посмотрим на строку 66. "Our tours are crafted around our central mission, and are deigned to engage you in a unique and fulfilling way. All our tours are sensitive to the environment, and will provide you with the opportunity to explore California in your own way." Теперь давайте вырежем это и напишем вместо этого "they're environmentally sensitive". Итак, "environmentally sensitive", мы внесли изменение в строку 66, а теперь давайте спустимся на строку 67, и давайте внесем это изменение.

Все действительно довольно просто, мы это оставляем, видите - we ask ourselves one question - мы меняем на we ask ourselves a question. Я думаю, так лучше. Итак, мы внесли изменение в строку 67. Итак, в строках 65, 66 и 67 есть изменения. Давайте еще отредактируем строку 68 - we have worked for a tour company. Итак, в каждой из этих строк есть изменения. Вы можете редактировать и дальше строки, если хотите. Теперь давайте сохраним документ и закроем его. Мы находимся в бранче text_edits, мы знаем, что внесли изменения, мы можем их увидеть при помощи git status.

Теперь мы можем сделать коммит, то есть, прописываем git commit, и я использую опцию -am, а сообщение будет такое - "Text edits on mission page". Итак, коммит сделан в бранче text_edits. А теперь давайте вернемся и переключимся на основной бранч. Все верно, теперь вы в основном бранче, и в нем нет только что внесенных изменений, давайте зайдем в mission.html и прокрутим до нужного блока текста. Вы видите, что всех тех изменений, что мы сделали, здесь нет.

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

Итак, все кавычки стали фигурными. Возможно, я что-то упустил, вот посмотрите, здесь до сих пор одинарные кавычки. Так, хорошо, закрываем документ, делаем коммит, git commit с сообщением "Replaces double quotes with curly quotes," на самом деле, я могу это сделать и с одинарными кавычками, а не только с двойными, напишем "Replace straight quotes". Итак, давайте вспомним, что у нас есть, git log --oneline, изменения находятся в основном бранче.

"Replaces straight quotes with curly quotes" - это слияние, которое идет сразу же после слияния с бранчем shorten_title. Если мы проверим это же самое, вставляем бранч text_edits, вы увидите, что слияние shorten_title есть здесь, и вот наш новый коммит. Но эти два коммиты вызывают конфликт. Давайте снова попробуем делать слияние, просто чтобы вы вспомнили, вот наши бранчи. Пишем git merge, а затем text_edits. Git говорит нам о конфликте при автоматическом слиянии, и он дает нам список всех тех элементов, из-за которых возник конфликт, в mission.html.

Git говорит, что автоматическое слияние не удалось, что нужно разрешить конфликт, а затем закоммитить результат. А теперь обратите внимание, что здесь написано master and MERGING, верно? Я не нахожусь полностью в основном бранче, я нахожусь в процессе слияния, и Git Говорит мне об этом. Давайте посмотрим, если мы напишем git status, видите, Git говорит мне - unmerged paths, он советует мне использовать для них add и remove, чтобы отметить разрешение, он мне говорит, что обе версии mission.html были изменены и ничего не может быть еще закоммичено. Мне надо решить эти проблемы.

Открываем mission.html, и давайте посмотрим, как Git отметил эти проблемы, вот оно. Это то, на что указывает HEAD, помните. мы в основном бранче, сейчас это текущий бранч. Git показывает мне эти строки, здесь много знаков равно, а вот еще один блок, и Git говорит мне, что это то, что находится в бранче text_edits. А теперь, все зависит от меня, мне нужно решить, какие из изменений мне нужны. Но вот здесь есть три строки, они различаются во всех бранчах, и по этому поводу возникает конфликт.

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