Совсем не редки ситуации (а их даже большинство), когда над кодом какой-то программы работает не один человек, а несколько. Для того, чтобы работа нескольких разработчиков над одной и той же программой стала возможной, используются системы контроля версий (например, GIT). Код программы хранится в master-ветке, откуда каждый разработчик может создать себе копию этого кода и работать над ним не боясь помешать своим коллегам. После того как код будет отлажен, разработчик может добавить свои изменения в ветку master, то есть изменить основной код программы. И уже этот изменённый код в дальнейшем будут копировать себе все разработчики перед реализацией очередной задачи.

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

У нас есть команда разработчиков, работающих над одним продуктом. В работе они используют Bitbucket и SourceTree. Мы сейчас будем играть роль одного из разработчиков команды. SourceTree у нас скачан и подключен наш проект. Также у нас создана отдельная ветка, в которой у нас уже есть изменения в файле «Original.txt». Другой разработчик также редактировал этот файл и уже влил изменения в ветку master.

Мы добавили свой код и теперь пытаемся выполнить слияние нашей ветки с веткой master. При попытке создании pull request в Bitbucket у нас возникает ошибка. Возник конфликт, который нам требуется разрешить.

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

Без разрешения конфликта слияние не выполнить. Также конфликт невозможно решить средствами Bitbucket. Придётся решать конфликт вручную.

Добавление сторонней программы для разрешения конфликтов в SourceTree

Стандартные средства SourceTree, возможно, и предоставляют возможность разрешения конфликтов при слиянии, но мне не удалось разобраться как это делать. Поэтому я подключила внешнюю программу TortoiseMerge для удобного разрешения конфликтов. Как это сделать:
1. Установить TortoiseMerge на компьютер.
2. Открыть SourceTree.
3. В SourceTree в меню Инструменты выбрать пункт Настройки.

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

4. В разделе Общие установить чек-бокс Разрешить SourceTree изменять глобальные настройки Git и Mercurial. Без включения этой настройки мы не сможем подключить внешнюю программу для сравнения и слияния кода.

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

5. Открыть раздел Сравнение
6. В блоке Внешняя утилита сравнения / слияния в выпадающих списках Внешняя утилита сравнения и Инструмент слияния выбрать значение TortoiseMerge:

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

В полях Команда сравнения и Команда слияния нужно указать путь к исполняемому файлу TortoiseGitMerge.exe. Поля Параметры будут заполнены автоматически.

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

7. Нажать на кнопку Ок для сохранения изменений. Всё, внешняя программа для разрешения конфликтов подключена. Также при необходимости можно подключить любую другую программу из списка и даже не из списка, воспользовавшись пунктом Пользовательский.

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

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

Мы остановились на том, что Bitbucket сообщил нам о конфликте. Нам нужно его решить. Теперь, когда у нас есть программа для сравнения мы можем это сделать:

1. В SourceTree нажимаем на кнопку Слияние:

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

2. В открывшемся окне выбрать кликом ветку, с которой требуется провести слияние и нажать на кнопку ОК.

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

3. У нас появится сообщение о том, что существуют конфликты слияния:

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

4. Нажимаем на кнопку Закрыть и открываем в разделе Workspace пункт Состояния файлов:

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

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

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

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

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

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

8. У нас открывается программа TortoiseGitMerge и в ней открывается наш файл, в котором требуется разрешить конфликт. Слева отображается наша версия файла, справа отображается версия файла из master-ветки. Жёлтым подсвечивается код, который был добавлен другим разработчиком. Также отображаются служебные теги, которые нужно будет удалить, если вы не хотите поломать свой код. Тег Head (1) указывает на изменения выполненные нами. На конец блока наших изменений указывает тег состоящий из символов = (2). Соответственно, master (3) указывает на изменения, которые находятся в ветке master:

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

9. Для того, чтобы иметь возможность редактировать файл (удалять, изменять текст вручную) убедитесь, что в меню активирована настройка Enable Edit

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

10. Теперь нам предстоит самое сложное: разрешить конфликты между двумя файлами. Здесь нужно быть предельно внимательными. Если вы что-то не то удалите или наоборот, оставите лишнее, ваша программа может отказаться работать. В правой части окна отображается версия файла, которая будет в итоге сохранена. Она должна содержать все необходимые изменения.

Если нам не нужно ничего менять в блоке, ничего не меняем.
Если нужно заменить какие-то блоки и использовать «нашу» версию (из файла слева), то кликаем по соответстующему блоку (в правом файле) правой кнопкой мыши и выбираем пункт Use other text block (использовать другой текстовый блок из левого файла) или в левом файле кликаем правой кнопкой мыши и выбираем пункт Use this text block (использовать этот текстовый блок).

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

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

11. Переключаться между конфликтующими блоками в файле можно с помощью навигационных стрелок в меню Previous difference и Next difference:

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

12. После того как вы разобрались со всеми изменениями не забудьте удалить служебные теги head, master, символы равно и треугольные скобки. Они вам явно не пригодятся. Сохраните изменения нажав на кнопку Save. Всё. TortoiseGitMerge можно закрывать.

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

13. Если у вас не один конфликтующий файл, а несколько, то выполните шаги 6-12 для оставшихся файлов. Если все конфликты разрешены — переходите к шагу 14.

14. Очень важный шаг. Убедитесь, что всё работает. Запустите свою программу и проверьте её работоспособность. Если программа или проект не запускается или падает с ошибками, а до разрешения конфликтов всё работало, значит вы неправильно разрешили конфликты.

Отменить изменения связанные с разрешениями конфликтов можно следующим образом:

a. Нажмите на кнопку Отменить в SourceTree

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

b. В появившемся окне выберите вкладку Сбросить всё и нажмите на кнопку Сбросить всё.

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

Это отменит все локальные изменения и отменит неудавшуюся попытку слияния.

Если выбрать вкладку Отменить изменения файла, то вы не сможете выполнить повторное слияние, так как сохраняются метаданные слияния и будет возникать ошибка слияния. Как её побороть я пока не знаю. Если кто-то знает — пишите, будем дополнять статью.

c. Подтвердите действие нажав на кнопку Ок в появившемся окне подтверждения:

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

d. Теперь можете повторно выполнить слияние и разрешить конфликты (шаги 1-13).

15. Мы разрешили все конфликты и теперь можем сделать коммит изменений в нашу ветку. В SourceTree программа автоматически оставила комментарий, что новый коммит — это слияние нашей ветки и ветки master. Добавляем все изменения в индекс (1) и после этого нажимаем на кнопку Закоммитить (2). Отправьте изменения в ветку, если не установили галочку Сразу отправить изменения в [имя ветки]:

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

16. Итак, все изменения отправлены в нашу ветку. Теперь мы можем делать Merge. Идём в Bitbucket, находим наш pull request и убеждаемся, что никаких конфликтов теперь нет (если страница была уже открыта, то обновите её) нажимаем на кнопку Merge:

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

17. Никаких ошибок нет, подтверждаем наше действие нажатием на кнопку Merge и радуемся жизни. Конфликты решены успешно.

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

Откат к предыдущему коммиту

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

1. В SourceTree в разделе Hystory выбрать коммит, к которому нужно откатиться. Для этого нужно кликнуть по нему левой кнопкой мыши:

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

2. Кликнуть правой кнопкой мыши по выбранному коммиту и в контекстном меню выбрать пункт Сбросить состояние текущей ветки к этому коммиту:

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

3. В появившемся модальном окне выберите режим сброса:

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

Подробности о типах читайте в интернете.

4. Проверьте есть ли у вас файлы не в индексе (раздел «Состояния файлов»). Если есть, то выполните коммит изменений:

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

5. Если SourrceTree предлагает получить и отправить изменения, сначала получите все изменения, а затем отправьте. В обратном порядке выполнить эти действия не получится, программа будет ругаться.

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