Разрешение конфликтов слияния в Visual Studio
Twitter LinkedIn Facebook Адрес электронной почты
- Статья
- Чтение занимает 2 мин
Область применения:Visual StudioVisual Studio для Mac Visual Studio Code
При слиянии одной ветви с другой изменения файлов из фиксаций в одной ветви могут конфликтовать с изменениями в другой. Git пытается устранить эти изменения, используя журнал в репозитории, чтобы определить, как должны выглядеть объединенные файлы. Если не ясно, как объединить изменения, Git останавливает слияние и сообщает, какие файлы конфликтуют.
Общие сведения о конфликтах слияния
На следующем рисунке показан простой пример конфликта изменений в Git. В этом примере главная ветвь и ветвь исправления ошибок обновляются в одни и те же строки исходного кода.
При попытке объединить ветвь исправления ошибок в main Git не сможет определить, какие изменения следует использовать в объединенной версии. Может потребоваться сохранить изменения в главной ветви, ветвь исправления ошибок или в некотором сочетании этих двух. Устраните этот конфликт с помощью фиксации слияния в главной ветви, которая согласовывает конфликтующие изменения между двумя ветвями.
Наиболее распространенный сценарий конфликта слияния возникает при извлечении обновлений из удаленной ветви в локальную ветвь (например, из источника или исправления ошибок в локальную ветвь исправления ошибок). Эти конфликты можно разрешить тем же способом: создайте фиксацию в локальной ветви для согласования изменений, а затем завершите слияние.
Предотвращение конфликтов слияния
Git хорошо подходит для автоматического объединения изменений файлов в большинстве случаев, если содержимое файла не изменяется резко между фиксациями. Если ваша ветвь значительно отстает от вашей главной ветви, рассмотрите возможность повторного масштабирования ветвей, прежде чем открывать запрос на вытягивание. Перебазированные ветви будут объединяться в главную ветвь без конфликтов.
Разрешение конфликтов слияния
При совместной работе с другими пользователями в той же ветви при отправке изменений могут возникнуть конфликты слияния.
Visual Studio определяет, находится ли локальная ветвь, с которым вы работали, за ее удаленной ветвью отслеживания, а затем предоставляет варианты выбора.
Примечание
Если удаленный репозиторий поддерживает принудительная отправка, ее можно включить с помощьюпараметров
Git>.В этом примере выберите Вытягивание и Отправка , чтобы включить изменения, внесенные в удаленный репозиторий. Если при извлечении изменений или попытке объединения двух ветвей возникают конфликты слияния, Visual Studio сообщает об этом в окне Изменения Git , в окне репозитория Git и во всех файлах, которые имеют конфликты.
В окне Изменения Git отображается список файлов с конфликтами в разделе Не объединены изменения. Чтобы начать разрешение конфликтов, дважды щелкните файл. Если в редакторе открыт файл с конфликтами, можно выбрать Открыть редактор слияния.
В редакторе слияния начните разрешение конфликта с помощью любого из следующих методов (как показано на нумерованном снимке экрана):
- Последовательно перебирайте конфликты и выбирайте правую или левую сторону, установив флажки.
- Сохраняйте или игнорируйте все конфликтующие изменения.
- Вручную измените код в окне Результат .
Совет
Если вам не нравится макет по умолчанию в редакторе слияния, вы можете изменить его с помощью раскрывающегося меню шестеренки.
Например, на следующем снимку экрана показано, как выглядит вертикальное представление:
Завершив разрешение конфликтов слияния, выберите Принять слияние. Повторите эту процедуру для всех конфликтующих файлов.
Используйте окно Изменения Git , чтобы создать фиксацию слияния и устранить конфликт.
Примечание
Если вам нужно сохранить все изменения в файле, щелкните его правой кнопкой мыши в разделе Unmerged Changes (Необъединенные изменения ) и выберите Сохранить текущий (локальный) без необходимости открывать редактор слияния.
Дальнейшие действия
Чтобы продолжить работу и узнать больше об устранении конфликтов, перейдите на веб-страницу Git для команды слияния.
См. также раздел
- Интерфейс GIT в Visual Studio
- Visual Studio и GitHub: лучше вместе
Безболезненное разрешение Merge конфликтов в Git / Хабр
Предлагаю читателям «Хабрахабра» перевод публикации «Painless Merge Conflict Resolution in Git»
из блога blog.wuwon.id.au.
В моей повседневной работе, часто приходится иметь дело со множеством git ветвей (branch). Это могут быть ветви промежуточных релизов, ветви с устаревшим API находящиеся на поддержке для некоторых клиентов, или ветви с экспериментальными свойствами. Лёгкость создания ветвей в модели Git так и соблазняет разработчиков создавать все больше и больше ветвей, и как правило бремя от большого количества ветвей становится очень ощутимым, когда приходится все эти ветви поддерживать и периодически делать слияния (merge) с другими ветвями.
Слияния очень важны для поддержания кода в актуальном состоянии, и как правило ошибка сделанная при слиянии может привести к большей головной боли, нежели ошибка сделанная при простом коммите. К сожалению ошибки слияния далеко не редкость, потому что во-первых слияния имеют несколько родительских ветвей. Даже при анализе истории слияния ветвей, бывает очень трудно понять, какие же изменения были сделаны для разрешения конфликта. Во-вторых, отмена неудачного слияния может превратиться в большую головную боль. В-третьих, большая часть конфликтов слияния происходит при работе с чужим кодом, потому что само понятие ветвей подразумевает множество пользователей, т.е. далеко не всегда слияние производит тот же человек который работал с той или иной веткой. В сухом остатке, сделать ошибку при слиянии очень легко, её трудно исправить и трудно найти. Таким образом время потраченное на изучение и понимание процесса слияния ветвей, окупится с лихвой.
Удивительно, но я обнаружил, что многие доступные инструменты и интерфейсы предназначенные для выполнения слияний, не достаточно хорошо оснащены для эффективного выполнения этого процесса. Часто программист просто надеется что команда git merge сделает за него всю работу. Но когда все-таки происходит конфликт, то обычно стратегия слияния заключается в беглом просмотре кода вокруг строки конфликта, и интуитивном угадывании что именно данный кусок кода предпочтительней другого.
В данной статье я надеюсь продемонстрировать что процесс разрешения конфликтов может быть пошагово точным, при котором отпадает необходимость что-либо там угадывать.
Голубые Розы (Roses are Blue)
Давайте предположим что вашей команде поручили писать поэмы в отведённом для этих целей репозитории. (Какой кошмар!) А вам доверили самое главное — делать слияния последних фиксов из ветки master в ветку beta. Итак, вы переключаетесь в ветку beta и выполняете следующую команду:
$ git merge master Auto-merging roses.txt CONFLICT (content): Merge conflict in roses.txt Automatic merge failed; fix conflicts and then commit the result.
Ого, это конфликт. Вы решаете просмотреть файл на который ссылается git:
$ cat roses.txt <<<<<<< HEAD roses are #ff0000 violets are #0000ff all my base are belong to you ======= Roses are red, Violets are blue, All of my base Are belong to you.>>>>>>> master (Listing 1)
Замечательно! Весь файл, как показывает Listing 1, находится в конфликтном состоянии. Какой же вариант файла является более корректным? Оба варианта выглядят корректно. Верхний вариант написан в хакер-стиле с элементами цветовой кодировки в стиле HTML и с использованием только строчных букв. Нижний вариант выглядит более натурально, с использованием пунктуации и заглавных букв.
Если бы это был ваш проект, вы бы могли просто выбрать один вариант и покончить с этим слиянием. Но проблема в том, что это не ваша поэма, вы никогда не читали эту поэму раньше, не были ответственны за написание или редактирование, и вы отлично понимаете что в случае не верного решения чья-то тяжёлая работа может кануть в небытие. Однако вас всё же назначили ответственным по слиянию этих веток. Что же вам делать?
Назад к Базе (Back to Base)
Хитрость заключается в том, что Listing 1 не даёт вам полную информацию, необходимую для совершения корректного слияния. На самом деле, в процессе слияния участвуют четыре важных части информации (состояния), три из которых просто необходимы для успешного разрешения конфликта. В случае Listing 1, Git предоставил вам только два состояния.
Следующая диаграмма иллюстрирует эти четыре состояния:
Состояния (B) и © относятся к текущим положениям (head) веток master и beta соответственно, эти два состояния как раз таки и отражены в Listing 1. Состояние (D) это результат слияния, то что вы хотите получить/сгенерировать в конечном итоге (в большинстве случаев Git автоматически генерирует состояние (D)). Состояние (А) на самом верху, представляет собой базу (основу) слияния веток master и beta. База слияния (A) это последний общий предок веток master и beta, и пока предположим что это база слияния уникальна. Как мы увидим позже состояние (A) играет ключевую роль в разрешении конфликтов. На диаграмме я также отразил дельты 1 и 2, которые представляют изменения между состояниями (A)-(B), и (A)-© соответственно. Зная состояния (A), (B) и © дельты 1 и 2 могут быть легко получены (вычислены). Обратите внимание, что дельты 1 и 2 могут состоять из более чем одного коммита. Но для наших целей будем считать что все дельты монолитны.
Чтобы понять, как получить состояние (D), вы должны понимать что же операция слияния пытается сделать. Состояние (D) должно представлять собой сочетание изменений, внесённых в ветку master и beta соответственно. Т.е. другими словами сочетание дельт 1 и 2. Идея проста на поверхности и большую часть времени не требует вмешательства со стороны человека, за исключением особых случаев когда дельты затрагивают наслаиваемые (пересекающиеся) части файла. В такой ситуации вам требуется помочь машине сгенерировать результат (D), путём сравнения дельт 1 и 2.
Определение Отличий (Identifying the Differences)
Для того чтобы найти изменения внесённые в каждую ветку, необходимо знать как выглядит база слияния, состояние (A). Самый простой механизм получения информации о базе слияния, это установка опции merge. conflictstyle в значение diff3
$ git config merge.conflictstyle diff3
После включения этой опции, попробуйте заново сделать слияние (git reset —hard; git merge master) и проинспектируйте конфликтующий файл ещё раз:
$ cat roses.txt <<<<<<< HEAD roses are #ff0000 violets are #0000ff all my base are belong to you ||||||| roses are red violets are blue all my base are belong to you ======= Roses are red, Violets are blue, All of my base Are belong to you. >>>>>>> master (Listing 2)
Теперь мы видим третий фрагмент посередине, который и является базой слияния или состояние (A). Изменения видны как на ладони: в ветке beta (HEAD) человеческие названия цветов были заменены на HTML коды, а в ветку master добавили капитализацию и пунктуацию. Основываясь на этих знаниях, мы теперь знаем что результат должен включать в себя капитализацию, пунктуацию и HTML коды цветов.
В принципе на этом можно было бы и закончить, потому что результат достигнут. Но есть решение и получше.
Графическое Слияние (GUI Merging)
Хотя и простое текстовое представление конфликта слияния делает свою работу в простых случаях, на практике конфликты могут быть более радикальными и сложными. В таких случаях могут помочь графические инструменты. Мой выбор пал на простой инструмент написанный на Python под названием meld, но может подойти любой другой графический инструмент, способный представить слияние в трёх-колоночном виде.
Для использования графического инструмента (он должен быть установлен), после того как git пожаловался что есть конфликт, введите следующую команду:
$ git mergetool
Последует вопрос какой программой для слияния вы хотели бы воспользоваться, просто введите meld и нажмите Enter. Вот как окно программы может выглядеть (подразумевается опция merge.conflictstyle не была включена):
Несмотря на то что информация представлена бок о бок, она не отображает нужные фрагменты которые были в Listing 2. Мы не видим здесь фрагмента базы слияния (состояния (A)), что мы видим это файл roses.txt.LOCAL.2760.txt в левой колонке и файл roses.txt.REMOTE.2760.txt в правой колонке и файл посередине это неудачное слияние. Т.е. по сути нам представили состояния (B), © и несостоявшееся состояние (D), но состояние (A) отсутствует…
Правда отсутствует? Давайте проверим, в старом добром терминале:
$ ls -1 roses.txt roses.txt.BACKUP.2760.txt roses.txt.BASE.2760.txt roses.txt.LOCAL.2760.txt roses.txt.REMOTE.2760.txt
Видим интересующий нас файл: roses.txt.BASE.2760.txt. Это и есть файл базы слияния. Теперь нам осталось всего лишь найти изменения внесённые в ветки master и beta, по отношению к базе. Мы можем сделать это двумя отдельными вызовами meld:
$ meld roses.txt.LOCAL.2760.txt roses.txt.BASE.2760 & $ meld roses.txt.BASE.2760 roses.txt.REMOTE.2760.txt &
(Кто-то может подметить что было бы более разумно, поменять порядок аргументов в первом вызове, для того чтобы файл базы находился в левой колонке в обоих случаях, но именно такой порядок сохраняет подобие трёх-колоночного вида, при котором база остаётся по середине.
) Результат выполнения — два окна как показано ниже:При чтении первого окна справа налево и второго окна слева направо, становится ясно как день, какие изменения произошли в каждой ветке. Так как meld любезно подсветил все изменения, теперь практически не возможно пропустить даже мелко заметные правки (Кто-нибудь заметил добавление предлога «of» при просмотре текстового представления разрешения конфликта Listing 1 или даже Listing 2?)
Вооружившись этими знаниями, мы теперь можем вернуться к трёх-колоночному представлению и сделать изменения. Моя стратегия ручного слияния это взять весь текст из ветки с более весомыми изменениями (в данном случае master/REMOTE т.е. beta), и поверх него производить пошаговые правки, т.е. вносить изменения сделанные в другой ветке (master). Вот что получилось:
А теперь всё вместе (All Together Now)
Надеюсь, вы найдёте этот трёх-окошечный метод разрешения конфликтов, таким же полезным каким нахожу его я. Но согласитесь что запускать новые вызовы meld вручную каждый раз при разрешении конфликтов, не очень то и удобно.
#!/bin/sh meld $2 $1 & sleep 0.5 meld $1 $3 & sleep 0.5 meld $2 $4 $3
И добавьте следующее в ваш ~/.gitconfig файл:
[merge] tool = mymeld [mergetool "mymeld"] cmd = $HOME/bin/gitmerge $BASE $LOCAL $REMOTE $MERGED
Теперь, когда вы в следующий раз будете запускать команду git mergetool для разрешения конфликта, откроются все три окна:
Окно дифа между BASE и LOCAL Окно дифа между BASE и REMOTE Окно трёх-колоночного вида
После того как вы привыкните к такому разрешению конфликтов с использованием трёх вышеупомянутых окон, вы скорее всего обнаружите, что процесс стал более методичным и механическим. В большинстве случаев, вам даже не придётся читать и понимать куски кода из каждой ветки, для того чтобы понять какой же вариант применить для слияния. Вам больше не понадобится догадываться, потому что вы будете гораздо более уверенным в корректности вашего комита. Из-за этой уверенности, появится чувство что разрешение конфликтов превратилось в увлекательное занятие.
Бонус от переводчика
Для тех кто пользуется tmux и n?vim, предлагаю следующий скрипт gitmerge:
#!/bin/sh sn=gitmerge tmux new-session -d -s "$sn" -n "diff3" "nvim -d $2 $4 $3" tmux split-window -t "$sn:1" -v "nvim -d $2 $1" tmux split-window -t "$sn:1" -h "nvim -d $1 $3"
Примечание: если вы не используете эту опцию в своем ~/.tmux.conf, то вам надо поменять в двух последних строках "$sn:1"
на "$sn:0"
Соответственно добавьте следующее в ваш ~/.gitconfig
[mergetool "gitmerge"] cmd = $HOME/bin/gitmerge \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\" [merge] tool = gitmerge
Воркфлоу разрешения конфликта будет выглядеть так:
Пока игнорируем вопрос (Was the merge successful [y/n]?) и переключаемся в сессию под названием gitmerge (сочетание TMUXPREFIX + s):
Видим наше трёх-оконное представление на одном экране. Цифрами обозначены сплиты (panes) tmux’a, буквами соответствующие состояния. Делаем правки для разрешения конфликта, т.е. редактируем состояние (D) и сохраняем. После этого возвращаемся обратно в исходную сессию tmux’a и подтверждаем что слияние произошло успешно.
git rebase master
Лично я предпочитаю и считаю более правильным делать сначала rebase master в ветке beta, и только после этого переключаться в master и делать git merge beta. В принципе воркфлоу не сильно отличается, за исключением трёх-оконного вида.
Переключаемся в сессию gitmerge
Обратите внимание, что состояния (B) и © поменялись местами:
Рекомендую всем поиграться с примером репозитария хотя бы один раз, сделать разрешение конфликта по вышеописанной схеме. Лично я больше не гадаю а что же выбрать «Accept theirs» или «Accept yours».
Как разрешить конфликты слияния в Git?
Git — одна из самых популярных систем управления исходным кодом, которая позволяет профессионалам в области разработки программного обеспечения во всех отраслях, позволяя нескольким членам команды одновременно работать над проектами. Однако, поскольку многие пользователи одновременно работают из разных мест над одним и тем же файлом, вы можете столкнуться с конфликтом слияния. В этой статье объясняются основы конфликтов слияния Git и одна из продвинутых операций Git: разрешение конфликтов слияния Git.
Сначала мы рассмотрим основы Git.
Что такое Git?
Git — это распределенная система управления версиями (VCS) с открытым исходным кодом, которая имеет удаленный репозиторий на стороне сервера и локальный репозиторий на стороне клиента. Это означает, что файла или кода нет на центральном сервере, но есть копия файла, хранящаяся на компьютере клиента.
Распределенная система контроля версий позволяет нескольким разработчикам работать параллельно друг с другом без каких-либо конфликтов кода. Git позволяет разработчикам при необходимости возвращаться к более старой версии кода.
Git помогает как разработчикам, так и нетехническим специалистам, отслеживая файлы их проектов. Это облегчает совместную работу нескольких человек и играет чрезвычайно важную роль в крупных проектах, в которых участвуют большие команды.
Основные команды Git
- git конфиг
- гит инициализация
- git добавить
- git разница
- git совершить
- git сброс
- статус git
- git слияние
- гит пуш
- git тянуть
Что такое конфликт слияния Git?
Конфликт слияния — это событие, которое происходит, когда Git не может автоматически разрешить различия в коде между двумя фиксациями. Git может автоматически объединять изменения, только если коммиты находятся в разных строках или ветвях.
Ниже приведен пример того, как работает конфликт слияния Git:
Предположим, что есть два разработчика: разработчик А и разработчик Б. Оба они извлекают один и тот же файл кода из удаленного репозитория и пытаются внести в этот файл различные изменения. После внесения изменений разработчик А отправляет файл обратно в удаленный репозиторий из своего локального репозитория. Теперь, когда разработчик B пытается отправить этот файл после внесения изменений со своей стороны, он не может этого сделать, так как файл уже был изменен в удаленном репозитории.
Для предотвращения подобных конфликтов разработчики работают в отдельных изолированных ветках. Команда Git merge объединяет отдельные ветки и разрешает любые конфликтующие изменения.
Теперь, когда мы рассмотрели основы конфликтов слияния Git, давайте рассмотрим различные типы конфликтов.
Типы конфликтов слияния Git
Есть два момента, когда слияние может войти в конфликтное состояние:
1. Запуск процесса объединения
Если есть изменения в рабочей области рабочего каталога для текущего проекта, слияние не начнется.
В этом случае конфликты возникают из-за ожидающих изменений, которые необходимо стабилизировать с помощью различных команд Git.
2. Во время процесса слияния
Сбой в процессе слияния указывает на конфликт между локальной ветвью и объединяемой ветвью.
В этом случае Git разрешает, насколько это возможно, но есть вещи, которые необходимо разрешать вручную в конфликтующих файлах.
Теперь мы рассмотрим разрешение конфликтов слияния в Git.
Как разрешить конфликты слияния в Git?
Существует несколько шагов, которые могут сократить количество шагов, необходимых для разрешения конфликтов слияния в Git.
- Самый простой способ разрешить конфликтный файл — открыть его и внести необходимые изменения
- После редактирования файла мы можем использовать команду git add для подготовки нового объединенного содержимого
- Последний шаг — создать новую фиксацию с помощью команды git commit
- Git создаст новую фиксацию слияния для завершения слияния
Давайте теперь рассмотрим команды Git, которые могут играть важную роль в разрешении конфликтов.
Команды Git для разрешения конфликтов
1. git log —merge
Команда git log —merge помогает создать список коммитов, вызывающих конфликт
2. git разница
Команда git diff помогает определить различия между репозиториями состояний или файлами
3. git checkout
Команда git checkout используется для отмены изменений, внесенных в файл, или для смены веток
4.
git reset —mixedКоманда git reset —mixed используется для отмены изменений в рабочем каталоге и промежуточной области
5. git слить —abort
Команда git merge —abort помогает выйти из процесса слияния и вернуться в состояние до начала слияния
6. git сброс
Команда git reset используется во время конфликта слияния для сброса конфликтующих файлов в исходное состояние
Демонстрация: разрешение конфликтов слияния Git
Сначала инициализируйте два репозитория:
git инициализация A git инициализация B |
Добавьте удаленный адрес в репозиторий A:
git удаленное добавление источника *адрес* |
Следующим шагом будет перенос всех изменений из центрального репозитория в локальный репозиторий.
мастер происхождения git pull |
Выполните тот же процесс, чтобы добавить источник в репозиторий B.
git удаленное добавление источника *адрес* |
Команда pull выполняется снова, чтобы извлечь все содержимое из удаленного репозитория и переместить его в локальный репозиторий.
мастер происхождения git pull |
Оба этих репозитория представляют собой два разных репозитория двух разных разработчиков.
Вернемся к репозиторию А.
кд ../А |
В репозитории A открывается файл readme для внесения различных изменений.
vi README.md |
Внесите необходимые изменения в файл и сохраните его.
Затем выполняется команда git status, чтобы увидеть отраженные изменения.
статус git |
Следующий шаг — добавить эти изменения в промежуточную область и зафиксировать их.
гит доп. git commit -m *сообщение фиксации* |
После завершения фиксации измененный файл помещается в удаленный репозиторий.
мастер происхождения git push |
Теперь вернитесь в репозиторий B.
Откройте файл readme
vi README.md |
Внесите изменения в файл, сохраните его и закройте. После этого добавьте измененный файл и зафиксируйте его.
гит доп. git commit -m *сообщение фиксации* |
Следующим шагом будет отправка файла в удаленный репозиторий.
git push |
Отображается ошибка, означающая, что обновления отклонены.
Далее нам нужно выполнить:
git — перебазировать мастер происхождения |
В настоящее время имеются видимые конфликты, которые необходимо разрешить вручную.
Если вы хотите пропустить эту фиксацию, вы можете ввести git rebase —skip, или если вы хотите прервать эту перезагрузку, вы можете ввести git rebase —abort.
После управления этим конфликтом вручную мы откроем инструмент слияния.
git слияние |
После ввода этой команды все файлы будут обработаны.
Это все процессы и изменения, сделанные в файле.
Там можно увидеть три разных файла, и можно увидеть все, что было добавлено или удалено.
После прокрутки можно проверить, где именно произошел конфликт.
Затем вы можете решить, хотите ли вы продолжить работу с этим конкретным файлом или нет. Я продолжу удаление этой строки.
Модификации вручную позволили нам разрешить конфликты файлов. Сохраните файл и закройте окончательный файл.
Далее мы запустим:
git rebase —продолжить |
Теперь, когда конфликт разрешен, мы должны иметь возможность отправить файл в удаленный репозиторий.
Теперь вы можете проверить коммиты в удаленном репозитории.
Изучите возможности работы с новейшими инструментами DevOps, такими как Docker, Git, Jenkins и другими, выбрав наш курс сертификации инженеров DevOps. Спешите занять свое место, связавшись с нашим консультантом по приему СЕГОДНЯ!
Заключение
Мы надеемся, что это всеобъемлющее руководство поможет вам справиться с конфликтами слияния Git. Мы рассмотрели основы конфликтов слияния, включая типы конфликтов слияния и возможные объяснения их возникновения. Мы также предоставили подробный пример в виде пошаговой демонстрации. В демо мы видели, как мы можем вручную разрешать конфликты слияния.
Хотите узнать больше?
Как мы уже упоминали, Git — мощный инструмент, используемый компаниями по всему миру. Это означает, что квалифицированные специалисты пользуются большим спросом. Если вы хотите начать свою карьеру, ознакомьтесь с сертификационным курсом Simplilearn DevOps уже сегодня. В нем вы получите глубокие знания о Git и других популярных системах контроля версий, а также многое другое.
конфликтов слияния Git | Atlassian Git Tutorial
Системы управления версиями предназначены для управления вкладом между несколькими распределенными авторами (обычно разработчиками). Иногда несколько разработчиков могут пытаться редактировать один и тот же контент. Если разработчик А попытается отредактировать код, который редактирует разработчик Б, может возникнуть конфликт. Для предотвращения возникновения конфликтов разработчики будут работать в отдельных изолированных ветках. Основная задача команды git merge
— объединить отдельные ветки и разрешить любые конфликтующие изменения.
Понимание конфликтов слияния
Слияние и конфликты — обычная часть работы с Git. Конфликты в других инструментах контроля версий, таких как SVN, могут быть дорогостоящими и трудоемкими. Git упрощает слияние. Большую часть времени Git выяснит, как автоматически интегрировать новые изменения.
Конфликты обычно возникают, когда два человека изменили одни и те же строки в файле или если один разработчик удалил файл, пока другой разработчик его модифицировал. В этих случаях Git не может автоматически определить, что правильно. Конфликты затрагивают только разработчика, проводящего слияние, остальная часть команды не знает о конфликте. Git пометит файл как конфликтующий и остановит процесс слияния. В этом случае разработчики несут ответственность за разрешение конфликта.
Типы конфликтов слияния
Слияние может войти в состояние конфликта в двух разных точках. При запуске и во время процесса слияния. Ниже приводится обсуждение того, как решать каждый из этих конфликтных сценариев.
Git не удается начать слияние
Слияние не запустится, если Git обнаружит изменения либо в рабочем каталоге, либо в промежуточной области текущего проекта. Git не может начать слияние, потому что эти ожидающие изменения могут быть перезаписаны коммитами, которые объединяются. Когда это происходит, это происходит не из-за конфликтов с другими разработчиками, а из-за конфликтов с ожидающими локальными изменениями. Локальное состояние нужно будет стабилизировать с помощью git stash
, git checkout
, git commit
или git reset
. Ошибка слияния при запуске приведет к следующему сообщению об ошибке:
error: Entry '' not update. Невозможно объединить. (Изменения в рабочем каталоге)
Ошибка Git во время слияния
Сбой ВО ВРЕМЯ слияния указывает на конфликт между текущей локальной ветвью и объединяемой ветвью. Это указывает на конфликт с кодом другого разработчика. Git сделает все возможное, чтобы объединить файлы, но оставит конфликтующие файлы на ваше усмотрение. При сбое в середине слияния выводится следующее сообщение об ошибке:
ошибка: запись '' будет перезаписана при слиянии. Невозможно объединить. (Изменения в промежуточной области)
Создание конфликта слияния
Чтобы по-настоящему познакомиться с конфликтами слияния, в следующем разделе будет смоделирован конфликт для последующего изучения и разрешения. В примере будет использоваться Unix-подобный интерфейс командной строки Git для выполнения примера моделирования.
$ mkdir git-merge-test
$ cd git-merge-test
$ git init.
$ echo "это контент, с которым нужно повозиться" > merge.txt
$ git add merge.txt
$ git commit -am "мы коммитим исходное содержимое"
[main (root-commit) d48e74c] мы коммитим исходное содержимое
1 файл изменен, 1 вставка (+)
режим создания 100644 merge.txt
В этом примере кода выполняется последовательность команд, которые выполняют следующие действия.
- Создайте новый каталог с именем
git-merge-test,
перейдите в этот каталог и инициализируйте его как новый репозиторий Git. - Создать новый текстовый файл
merge.txt
с некоторым содержимым. - Добавьте
merge.txt
в репозиторий и зафиксируйте его.
Теперь у нас есть новое репо с одной веткой main
и файлом merge. txt
с содержимым. Далее мы создадим новую ветку для использования в качестве конфликтующего слияния.
$ git checkout -b new_branch_to_merge_later
$ echo "совершенно другой контент для объединения позже" > merge.txt
$ git Commit -am"изменил содержимое файла merge.txt, чтобы вызвать конфликт"
[new_branch_to_merge_later 6282319] изменил содержимое файла merge.txt, чтобы вызвать конфликт новая ветка с именемnew_branch_to_merge_later
merge.txt
С этой новой веткой: new_branch_to_merge_later, которая переопределяет содержимое 9 созданного нами коммита
0401 merge.txt
git checkout main
Переключено на ветку 'main'
echo "содержимое для добавления" >> merge.txt
git commit -am "добавленное содержимое для слияния.txt"
[main 24fbe3c] для добавленного содержимого merge.tx
1 файл изменен, 1 вставка (+)
Эта цепочка команд проверяет основную ветвь
, добавляет содержимое в merge. txt
и фиксирует его. Теперь это переводит наш пример репозитория в состояние, когда у нас есть 2 новых коммита. Один в основной
и один в ветке new_branch_to_merge_later
. А пока давайте git объединим new_branch_to_merge_later
и посмотрим, что получится!
$ git merge new_branch_to_merge_later
Автоматическое слияние merge.txt
КОНФЛИКТ (содержимое): конфликт слияния в merge.txt
Автоматическое слияние не удалось; исправить конфликты, а затем зафиксировать результат.
СТРЕЛА 💥. Появляется конфликт. Спасибо, Git, что сообщили нам об этом!
Как определить конфликты слияния
Как видно из предыдущего примера, Git выдаст описательный вывод, информирующий нас о возникновении КОНФЛИКТА. Мы можем получить дополнительную информацию, выполнив команду git status
$ git status
В основной ветке
У вас есть неслитные пути.
(исправить конфликты и запустить "git commit")
(использовать "git merge --abort", чтобы прервать слияние)Необъединенные пути:
(использовать "git add. ..", чтобы отметить разрешение) оба изменено: merge.txt
Выходные данные git status
указывают на наличие неслитных путей из-за конфликта. Файл merge.text
теперь отображается в измененном состоянии. Давайте изучим файл и посмотрим, что изменилось.
$ cat merge.txt
<<<<<<< HEAD
это некоторый контент, который нужно смешать с контентом
, чтобы добавить
=======
совершенно другой контент, который нужно объединить позже
>>>>>> > new_branch_to_merge_later
Здесь мы использовали 9Команда 0401 cat для вывода содержимого файла merge.txt
. Мы видим некоторые странные новые добавления
-
-
=======
-
>>>>>>> new_branch_to_merge_later
=======
является "центром" конфликта. Весь контент между центром и строкой — это контент, существующий в текущей ветке main , на которой HEAD
ref указывает на. В качестве альтернативы все содержимое между центром и >>>>>>> new_branch_to_merge_later
— это содержимое, присутствующее в нашей объединяющейся ветке.
Как разрешить конфликты слияния с помощью командной строки
Самый простой способ разрешить конфликт слияния — отредактировать конфликтующий файл. Откройте файл merge.txt в вашем любимом редакторе. Для нашего примера давайте просто удалим все конфликтные разделители. Модифицированный merge.txt
содержимое должно выглядеть следующим образом:
это содержимое, которое нужно смешать с содержимым
, чтобы добавить
совершенно другое содержимое, чтобы объединить его позже
После редактирования файла используйте git add merge.txt
для подготовки новый объединенный контент. Чтобы завершить слияние, создайте новую фиксацию, выполнив:
git commit -m "объединил и разрешил конфликт в файле merge.txt"
Git увидит, что конфликт был разрешен, и создаст новую фиксацию слияния для завершения слияния.
Команды Git, которые могут помочь разрешить конфликты слияния
Общие инструменты
git status
Команда status часто используется при работе с Git и во время слияния помогает выявить конфликтующие файлы.
git log --merge
При передаче аргумента --merge
команде git log
будет создан журнал со списком коммитов, конфликтующих между объединяющимися ветвями.
git разница
разница
помогает найти различия между состояниями репозитория/файлов. Это полезно для прогнозирования и предотвращения конфликтов слияния.
Инструменты для случаев, когда git не может начать слияние
git checkout
checkout
можно использовать для отмены изменений в файлах или для изменения веток
git reset —mixed
reset
можно использовать для отмены изменений в рабочем каталоге и промежуточной подготовки.
Инструменты для устранения конфликтов git во время слияния
git merge --abort
Выполнение git merge
с параметром --abort
приведет к выходу из процесса слияния и возврату ветки в состояние до начала слияния.