Совсем не редки ситуации (а их даже большинство), когда над кодом какой-то программы работает не один человек, а несколько. Для того, чтобы работа нескольких разработчиков над одной и той же программой стала возможной, используются системы контроля версий (например, GIT). Код программы хранится в master-ветке, откуда каждый разработчик может создать себе копию этого кода и работать над ним не боясь помешать своим коллегам. После того как код будет отлажен, разработчик может добавить свои изменения в ветку master, то есть изменить основной код программы. И уже этот изменённый код в дальнейшем будут копировать себе все разработчики перед реализацией очередной задачи.
При таком варианте разработки всегда есть шанс, что два разработчика работая над разными задачами изменят код в одних и тех же файлах. Вполне вероятно, что они изменят одни и те же строки. Рассмотрим пример:
У нас есть команда разработчиков, работающих над одним продуктом. В работе они используют Bitbucket и SourceTree. Мы сейчас будем играть роль одного из разработчиков команды. SourceTree у нас скачан и подключен наш проект. Также у нас создана отдельная ветка, в которой у нас уже есть изменения в файле «Original.txt». Другой разработчик также редактировал этот файл и уже влил изменения в ветку master.
Мы добавили свой код и теперь пытаемся выполнить слияние нашей ветки с веткой master. При попытке создании pull request в Bitbucket у нас возникает ошибка. Возник конфликт, который нам требуется разрешить.
Без разрешения конфликта слияние не выполнить. Также конфликт невозможно решить средствами Bitbucket. Придётся решать конфликт вручную.
Добавление сторонней программы для разрешения конфликтов в SourceTree
Стандартные средства SourceTree, возможно, и предоставляют возможность разрешения конфликтов при слиянии, но мне не удалось разобраться как это делать. Поэтому я подключила внешнюю программу TortoiseMerge для удобного разрешения конфликтов. Как это сделать:
1. Установить TortoiseMerge на компьютер.
2. Открыть SourceTree.
3. В SourceTree в меню Инструменты выбрать пункт Настройки.
4. В разделе Общие установить чек-бокс Разрешить SourceTree изменять глобальные настройки Git и Mercurial. Без включения этой настройки мы не сможем подключить внешнюю программу для сравнения и слияния кода.
5. Открыть раздел Сравнение
6. В блоке Внешняя утилита сравнения / слияния в выпадающих списках Внешняя утилита сравнения и Инструмент слияния выбрать значение TortoiseMerge:
В полях Команда сравнения и Команда слияния нужно указать путь к исполняемому файлу TortoiseGitMerge.exe. Поля Параметры будут заполнены автоматически.
7. Нажать на кнопку Ок для сохранения изменений. Всё, внешняя программа для разрешения конфликтов подключена. Также при необходимости можно подключить любую другую программу из списка и даже не из списка, воспользовавшись пунктом Пользовательский.
Разрешение конфликтов с помощью внешней утилиты сравнения
Мы остановились на том, что Bitbucket сообщил нам о конфликте. Нам нужно его решить. Теперь, когда у нас есть программа для сравнения мы можем это сделать:
1. В SourceTree нажимаем на кнопку Слияние:
2. В открывшемся окне выбрать кликом ветку, с которой требуется провести слияние и нажать на кнопку ОК.
3. У нас появится сообщение о том, что существуют конфликты слияния:
4. Нажимаем на кнопку Закрыть и открываем в разделе Workspace пункт Состояния файлов:
Если слева от названия файла отображается восклицательный знак в оранжевом треугольнике, это значит, что по этому файлу есть конфликты.
5. В этом разделе у нас отображаются все текущие состояния файлов. С помощью выпадающего списка вверху формы при необходимости можно отфильтровать файлы по состояниям:
7. Выделяем файл с конфликтом (у него слева восклицательный знак) кликнув по нему один раз. В правой части окна нажимаем на выпадающий список с иконкой шестерёнки и выбираем пункт Внешняя утилита сравнения:
8. У нас открывается программа TortoiseGitMerge и в ней открывается наш файл, в котором требуется разрешить конфликт. Слева отображается наша версия файла, справа отображается версия файла из master-ветки. Жёлтым подсвечивается код, который был добавлен другим разработчиком. Также отображаются служебные теги, которые нужно будет удалить, если вы не хотите поломать свой код. Тег Head (1) указывает на изменения выполненные нами. На конец блока наших изменений указывает тег состоящий из символов = (2). Соответственно, master (3) указывает на изменения, которые находятся в ветке master:
9. Для того, чтобы иметь возможность редактировать файл (удалять, изменять текст вручную) убедитесь, что в меню активирована настройка Enable Edit
10. Теперь нам предстоит самое сложное: разрешить конфликты между двумя файлами. Здесь нужно быть предельно внимательными. Если вы что-то не то удалите или наоборот, оставите лишнее, ваша программа может отказаться работать. В правой части окна отображается версия файла, которая будет в итоге сохранена. Она должна содержать все необходимые изменения.
Если нам не нужно ничего менять в блоке, ничего не меняем.
Если нужно заменить какие-то блоки и использовать «нашу» версию (из файла слева), то кликаем по соответстующему блоку (в правом файле) правой кнопкой мыши и выбираем пункт Use other text block (использовать другой текстовый блок из левого файла) или в левом файле кликаем правой кнопкой мыши и выбираем пункт Use this text block (использовать этот текстовый блок).
Также обратите внимание и на другие варианты: можно использовать оба блока и указать какой должен идти первым, а какой вторым.
11. Переключаться между конфликтующими блоками в файле можно с помощью навигационных стрелок в меню Previous difference и Next difference:
12. После того как вы разобрались со всеми изменениями не забудьте удалить служебные теги head, master, символы равно и треугольные скобки. Они вам явно не пригодятся. Сохраните изменения нажав на кнопку Save. Всё. TortoiseGitMerge можно закрывать.
13. Если у вас не один конфликтующий файл, а несколько, то выполните шаги 6-12 для оставшихся файлов. Если все конфликты разрешены — переходите к шагу 14.
14. Очень важный шаг. Убедитесь, что всё работает. Запустите свою программу и проверьте её работоспособность. Если программа или проект не запускается или падает с ошибками, а до разрешения конфликтов всё работало, значит вы неправильно разрешили конфликты.
Отменить изменения связанные с разрешениями конфликтов можно следующим образом:
a. Нажмите на кнопку Отменить в SourceTree
b. В появившемся окне выберите вкладку Сбросить всё и нажмите на кнопку Сбросить всё.
Это отменит все локальные изменения и отменит неудавшуюся попытку слияния.
Если выбрать вкладку Отменить изменения файла, то вы не сможете выполнить повторное слияние, так как сохраняются метаданные слияния и будет возникать ошибка слияния. Как её побороть я пока не знаю. Если кто-то знает — пишите, будем дополнять статью.
c. Подтвердите действие нажав на кнопку Ок в появившемся окне подтверждения:
d. Теперь можете повторно выполнить слияние и разрешить конфликты (шаги 1-13).
15. Мы разрешили все конфликты и теперь можем сделать коммит изменений в нашу ветку. В SourceTree программа автоматически оставила комментарий, что новый коммит — это слияние нашей ветки и ветки master. Добавляем все изменения в индекс (1) и после этого нажимаем на кнопку Закоммитить (2). Отправьте изменения в ветку, если не установили галочку Сразу отправить изменения в [имя ветки]:
16. Итак, все изменения отправлены в нашу ветку. Теперь мы можем делать Merge. Идём в Bitbucket, находим наш pull request и убеждаемся, что никаких конфликтов теперь нет (если страница была уже открыта, то обновите её) нажимаем на кнопку Merge:
17. Никаких ошибок нет, подтверждаем наше действие нажатием на кнопку Merge и радуемся жизни. Конфликты решены успешно.
Откат к предыдущему коммиту
Может случиться так, что в работе вам понадобится откатиться к какому-то определённому коммиту (например, вы сделали коммит, который сломал вашу ветку, и теперь вы хотите вернуться к предыдущей версии кода, до этого коммита). SourceTree позволяет это сделать. Для этого нужно выполнить следующие действия:
1. В SourceTree в разделе Hystory выбрать коммит, к которому нужно откатиться. Для этого нужно кликнуть по нему левой кнопкой мыши:
2. Кликнуть правой кнопкой мыши по выбранному коммиту и в контекстном меню выбрать пункт Сбросить состояние текущей ветки к этому коммиту:
3. В появившемся модальном окне выберите режим сброса:
Подробности о типах читайте в интернете.
4. Проверьте есть ли у вас файлы не в индексе (раздел «Состояния файлов»). Если есть, то выполните коммит изменений:
5. Если SourrceTree предлагает получить и отправить изменения, сначала получите все изменения, а затем отправьте. В обратном порядке выполнить эти действия не получится, программа будет ругаться.
Отличная статья. Спасибо!
Спасибо, ты мне сильно помогла.