34 Вопрос: Как разрешить конфликты слияния в Git

вопрос создан в Wed, May 15, 2019 12:00 AM

Как мне разрешить конфликты слияния в Git?

    
4443
  1. Следующий пост в блоге, кажется, дает очень хороший пример того, как обрабатывать конфликт слияния с Git, который должен заставить вас двигаться в правильном направлении. Обработка и предотвращение конфликтов в Git
    2008-10-02 11: 40: 03Z
  2. Вы можете настроить инструмент слияния (kdiff3 jebaird.com/2013/07/08/… ), а затем используйте git mergetool. Когда вы работаете в больших группах разработчиков, вы всегда будете сталкиваться с конфликтами слияния.
    2015-04-18 05: 37: 12Z
  3. Не забывайте, что вы можете уменьшить большинство конфликтов слияния путем регулярного слияния вниз по течению!
    2015-07-27 09: 50: 33Z
  4. 2015-10-20 11: 19: 55Z
  5. Увлекательный вопрос: в 2008 году вопрос на 100% завершился без всякого намека на то, о чем идет речь (это о GUI, о командах git, о семантике? о толкании /вытягивании или просто общих конфликтах?) - совершенно неопровержимый. 30 ответов, все из них (насколько можно судить по беглому взгляду) более или менее касаются различных инструментов сравнения и слияния, ни один из них не принят. В ответе с наибольшим количеством голосов упоминается команда, которая не работает даже из коробки с установкой по умолчанию git. Мне удалось попасть на стартовую страницу SE сегодня, 2017, с 1,3 млн просмотров и тысячами голосов в обе стороны. Захватывающий.
    2017-07-11 16: 48: 34Z
30 ответов                              30                         

Попробуйте: git mergetool

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

Согласно комментарию @JoshGlover:

Команда не обязательно открывает графический интерфейс, если вы его не установите. Запуск git mergetool для меня привел к использованию vimdiff. Вы можете установить один из следующих инструментов, чтобы использовать его вместо:. meld, opendiff, kdiff3, tkdiff, xxdiff, tortoisemerge, gvimdiff, diffuse, ecmerge, p4merge, araxis, vimdiff, emerge

Ниже приведен пример процедуры для использования vimdiff для разрешения конфликтов слияния. На основе этой ссылки

Шаг 1 . Выполните следующие команды в своем терминале

git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

Это установит vimdiff в качестве инструмента слияния по умолчанию.

Шаг 2 . Выполните следующую команду в терминале

git mergetool

Шаг 3 . Вы увидите дисплей vimdiff в следующем формате

  ╔═══════╦══════╦════════╗
  ║       ║      ║        ║
  ║ LOCAL ║ BASE ║ REMOTE ║
  ║       ║      ║        ║
  ╠═══════╩══════╩════════╣
  ║                       ║
  ║        MERGED         ║
  ║                       ║
  ╚═══════════════════════╝

Эти 4 вида являются

  

LOCAL - это файл из текущей ветви

     

BASE - общий предок, как файл выглядел до обоих изменений

     

REMOTE - файл, который вы объединяете в свою ветку

     

MERGED - результат слияния, это то, что сохраняется в репо

Вы можете перемещаться между этими представлениями, используя ctrl + w . Вы можете напрямую перейти к представлению MERGED, используя ctrl + w , за которым следует j .

Подробнее о навигации по vimdiff здесь и here р>

Шаг 4 . Вы можете редактировать MERGED вид следующим образом

Если вы хотите получить изменения от REMOTE

:diffg RE  

Если вы хотите получать изменения от BASE

:diffg BA  

Если вы хотите получать изменения из LOCAL

:diffg LO 

Шаг 5 . Сохранить, выйти, зафиксировать и очистить

:wqa сохранить и выйти из vi

git commit -m "message" р>

git clean Удалите дополнительные файлы (например, * .orig), созданные инструментом diff.

    
2662
2019-06-23 15: 50: 52Z
  1. К вашему сведению, вы можете использовать git mergetool -y, чтобы сохранить несколько нажатий клавиш, если вы объединяете много файлов одновременно.
    2010-06-17 23: 32: 50Z
  2. Ну, он не обязательно открывает графический интерфейс, если вы его не установите. Запуск git mergetool для меня привел к использованию vimdiff. Вместо этого вы можете установить один из следующих инструментов: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge.
    2011-05-11 14: 00: 49Z
  3. Хороший вопрос, Джош. На Ubuntu мне больше всего повезло с meld, его трехстороннее отображение слияния неплохо. На OSX Git выбрал хороший по умолчанию.
    2011-05-24 05: 08: 08Z
  4. Это открыло KDiff3. Который я понятия не имею, как использовать.
    2011-06-10 18: 46: 25Z
  5. Вы также можете использовать Beyond Compare 3 сейчас (git mergetool -t bc3).
    2012-08-30 14: 59: 24Z

Вот вероятный вариант использования сверху:

Вы собираетесь внести некоторые изменения, но, к сожалению, вы не в курсе:

git fetch origin
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

Итак, вы обновились и попробуйте снова, но у вас возник конфликт:

git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.

Итак, вы решили взглянуть на изменения:

git mergetool

О боже, боже мой, некоторые изменения изменились, но я просто использовал мои изменения ... нет ... их изменения ...

git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"

А потом мы попробуем в последний раз

git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

Та-да!

    
1643
2019-06-10 08: 10: 35Z
  1. Это было очень полезно, потому что у меня было много ошибок слияния с бинарными файлами (художественными активами), и объединение этих файлов, похоже, всегда завершалось неудачей, поэтому мне нужно перезаписать его с помощью новый файл всегда и не "сливать"
    2011-06-08 17: 39: 40Z
  2. Осторожно! Значение --ours и --theirs поменялось местами. --ours == пульт. --theirs == местные. См. git merge --help
    2013-03-04 22: 56: 21Z
  3. В моем случае я подтверждаю, что --theirs = удаленный репозиторий, --ours = мой собственный локальный репозиторий. Это противоположно комментариям @mmell.
    2013-06-22 12: 59: 08Z
  4. @ mmell По-видимому, только на перебазе. См. this question DIV>
    2013-11-10 06: 19: 14Z
  5. Ребята, "наши" и "их" относятся к тому, используете ли вы слияние или отказ от него. Если вы слияние , то «наш» означает отрубиch, с которым вы объединяетесь, и «их» - это ветвь, в которую вы сливаетесь. Когда вы ребазируете , то «наш» означает коммиты, на которые вы опровергаете, а «их» относится к коммитам, которые вы хотите перебазировать.
    2014-05-26 04: 27: 22Z

Я считаю, что инструменты слияния редко помогают мне понять конфликт или решение. Я обычно более успешно смотрю на маркеры конфликта в текстовом редакторе и использую git log в качестве дополнения.

Вот несколько советов:

Совет первый

Лучшее, что я нашел, - это использование стиля конфликта слияния "diff3":

git config merge.conflictstyle diff3 р>

Это приводит к появлению таких маркеров конфликта:

<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a 
feature/topic branch.
>>>>>>>

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

Если конфликт состоит всего из нескольких строк, это обычно делает конфликт очень очевидным. (Знание того, как исправить конфликт, совсем другое; вам нужно знать, над чем работают другие люди. Если вы растерялись, лучше всего просто позвонить этому человеку в вашу комнату, чтобы он мог видеть, что вы ищете в.) р>

Если конфликт будет более продолжительным, я буду вырезать и вставлять каждый из трех разделов в три отдельных файла, таких как «мой», «общий» и «их».

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

diff common mine
diff common theirs

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

Совет второй

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

git log --merge -p <name of file>

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

Совет третий

Проверьте свои изменения с помощью автоматизированных инструментов.

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

Совет четвертый

Планируйте заранее; общаться с коллегами.

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

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

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

Если вы не можете работать последовательно (возможно, из-за нехватки времени), то сообщение об ожидаемых конфликтах слияния, по крайней мере, поможет вам быстрее решить проблемы, пока детали еще свежи. Например, если сотрудник совершает серию разрушительных коммитов в течение однонедельного периода, вы можете выбрать слияние /перебазирование в этом филиале коллег один или два раза в день в течение этой недели. Таким образом, если вы обнаружите конфликты слияния /перебазировки, вы сможете разрешить их быстрее, чем если бы вы подождали несколько недель, чтобы объединить все в один большой кусок.

Совет пятый

Если вы не уверены в слиянии, не форсируйте его.

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

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

    
710
2014-07-23 17: 32: 54Z
  1. Опция diff3 - отличная возможность для слияния. Единственный GUI, с которым я столкнулся, показывает, что это p4merge от Perforce, который можно устанавливать и использовать отдельно от других инструментов Perforce (которые я не использовал, но слышал жалобы).
    2014-05-01 22: 15: 41Z
  2. После попытки перебазировки, которая привела к конфликту слияния: $git log --merge -p build.xml вывод: fatal: --merge без MERGE_HEAD?
    2016-06-17 09: 15: 07Z
  3. что делать, если у меня есть изменения в одном файле из branch1 и удаление этого файла в branch2. Как я могу решить этот конфликт слияния? Есть ли способ использовать git, где я могу объединить их, сохранив изменения одной ветви?
    2017-01-21 14: 48: 16Z
  4. git config merge.conflictstyle diff3 - спасибо, сэр. Это удивительно и освободило меня от попыток найти (и заплатить $$) хороший графический интерфейс с 3 путями слияния. IMO, это лучше, потому что он показывает общего предка, а также local /remote, и показывает последние строки журнала коммитов, которые (AFAIK) никакой GUI не делает. Коммиты определенно помогут вам определить, какой код принадлежит какой ветви.
    2017-04-04 16: 00: 53Z
  5. Я обнаружил, что иногда конфликтный стиль diff3 приводит к огромным блокам различий, которые в значительной степени идентичны, тогда как по умолчанию будут производиться меньшие, более управляемые блоки. К сожалению, у меня нет репродуктора, который я мог бы использовать для сообщения об ошибке. Но если вы столкнулись с этой проблемой, вы можете временно отключить эту опцию.
    2017-07-02 03: 31: 12Z
  1. Определите, какие файлы конфликтуют (Git должен сообщить вам об этом).

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

  3. После разрешения конфликта в файле git add the_file.

  4. Разрешив все конфликты, выполните git rebase --continue или любую другую команду. Git сказал делать, когда ты закончил.

333
2014-08-07 17: 48: 46Z
  1. @ Джастин Думайте о Git как о отслеживании содержимого , а не о отслеживании файлов. Тогда легко заметить, что контент, который вы обновили, отсутствует в репозитории и должен быть добавлен. Этот способ мышления также объясняет, почему Git не отслеживает пустые папки: хотя технически они являются файлами, контент для отслеживания отсутствует.
    2010-10-12 09: 17: 27Z
  2. контент есть, конфликт возникает, потому что есть 2 версии контента. Поэтому «git add» не звучит правильно. И это не работает (git add, git commit), если вы хотите зафиксировать только тот файл, который был разрешен после конфликта («fatal: невозможно выполнить частичную фиксацию во время слияния».)
    2011-09-14 09: 19: 10Z
  3. Да, технически, это отвечает на вопрос, который был задан, но не является пригодным для использования ответом, на мой взгляд, извините. Какой смысл в том, чтобы сделать одну ветку такой же, как другая? Конечно слияние будет иметь конфликты.
    2012-08-09 05: 56: 27Z
  4. Тулфир: кто сказал что-то о том, чтобы сделать одну ветку такой же, как другая? Существуют разные сценарии, в которых вам нужно объединить, не «делая одну ветвь такой же, как другая». Во-первых, когда вы закончите с разработкойопцию ветки и хотим включить ее изменения в основную ветку; после этого ветка разработки может быть удалена. Другой - когда вы хотите перебазировать свою ветку разработки, чтобы облегчить окончательное окончательное слияние с мастером.
    2012-09-21 08: 50: 19Z
  5. @ JustinGrant git add проверяет файлы в индексе; он не добавляет ничего в хранилище. git commit добавляет вещи в хранилище. Такое использование имеет смысл для слияний - слияние автоматически ставит все изменения, которые могут быть слиты автоматически; Вы обязаны объединить остальные изменения и добавить их в индекс, когда закончите.
    2012-10-17 15: 13: 05Z

Ознакомьтесь с ответами на вопрос о переполнении стека Отмена слияния в Git , особенно ответ Чарльза Бейли , в котором показано, как просмотреть разные версии файла с проблемами, например

# Common base version of the file.
git show :1:some_file.cpp

# 'Ours' version of the file.
git show :2:some_file.cpp

# 'Theirs' version of the file.
git show :3:some_file.cpp
    
102
2017-05-23 11: 47: 34Z
  1. Также проверьте параметр "-m" для "git checkout -m" - он позволяет вам извлекать различных мух обратно в ваше рабочее пространство
    2015-02-05 22: 06: 41Z
  2. Это спасло меня. Просмотр каждого файла в отдельности позволил мне вспомнить, к чему я стремился в каждой ветке. Тогда я мог бы принять решение о выборе.
    2016-05-14 21: 59: 15Z

Конфликты слияния возникают, когда в файл одновременно вносятся изменения. Вот как это решить.

git CLI

Вот простые шаги, которые нужно предпринять, когда вы попадаете в конфликтующее состояние:

  1. Обратите внимание на список конфликтующих файлов с: git status (в разделе Unmerged paths).
  2. Решите конфликты отдельно для каждого файла одним из следующих подходов:

    • Используйте графический интерфейс для разрешения конфликтов: git mergetool (самый простой способ).

    • Чтобы принять удаленную /другую версию, используйте: git checkout --theirs path/file. Это отклонит любые локальные изменения, которые вы сделали для этого файла.

    • Чтобы принять локальную /нашу версию, используйте: git checkout --ours path/file

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

      Связано: Каково точное значение «наших» и «их» в git?

    • Отредактируйте конфликтующие файлы вручную и найдите блок кода между <<<<</>>>>>, затем выберите версию сверху или снизу =====. См. Как отображаются конфликты .

    • Конфликты пути и имени файла могут быть решены с помощью git add/git rm.

  3. Наконец, просмотрите файлы, готовые для фиксации, используя: git status.

    Если у вас все еще есть файлы с именем Unmerged paths, и вы действительно решили конфликт вручную, то сообщите Git, что вы решили его с помощью: git add path/file.

  4. Если все конфликты были успешно разрешены, зафиксируйте изменения по номеру: git commit -a и как обычно отправьте на удаленное устройство.

См. также: Разрешение конфликта слияния из командной строки на GitHub

DiffMerge

Я успешно использовал DiffMerge , который может визуально сравнивать и объединять файлы в Windows, macOS и Linux /Unix . р>

Он может графически отображать изменения между 3 файлами и позволяет автоматически объединять (когда это безопасно) и полностью контролировать редактирование.результирующий файл.

 DiffMerge

Источник изображения: DiffMerge (скриншот для Linux)

Просто загрузите его и запустите в репозитории как:

git mergetool -t diffmerge .

MacOS

В macOS вы можете установить через:

brew install caskroom/cask/brew-cask
brew cask install diffmerge

И, вероятно, (если не предоставлено) вам понадобится следующая дополнительная простая обертка, помещенная в вашу переменную PATH (например, /usr/bin):

#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "$@"

Затем вы можете использовать следующие сочетания клавиш:

  • - Alt - Вверх / Вниз для перехода к предыдущим /следующим изменениям.
  • - Alt - влево / вправо , чтобы принять изменения слева или справа

Либо вы можете использовать opendiff (часть Xcode Tools), которая позволяет объединить два файла или каталога вместе, чтобы создать третий файл или каталог.

    
90
2017-05-23 10: 31: 39Z

Если вы часто делаете небольшие коммиты, начните с просмотра комментариев коммитов с git log --merge. Тогда git diff покажет вам конфликты.

Для конфликтов, которые включают в себя несколько строк, легче увидеть, что происходит во внешнем инструменте с графическим интерфейсом. Мне нравится opendiff - Git также поддерживает vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, появляются из коробки, и вы можете установить другие: git config merge.tool "your.tool" установит выбранный вами инструмент, а затем git mergetool после неудачного слияния покажет вам различия в контекст.

Каждый раз, когда вы редактируете файл для разрешения конфликта, git add filename будет обновлять индекс, и ваш diff больше не будет его показывать. Когда все конфликты будут обработаны и их файлы будут git add-ed, git commit завершит ваше слияние.

    
76
2014-07-23 17: 43: 21Z
  1. Использование "git add" - вот настоящий трюк. Вы можете даже не хотеть коммитить (может быть, вы хотите спрятать), но вы должны сделать «git add», чтобы завершить слияние. Я думаю, что Mergetool сделает добавление для вас (хотя оно не находится на странице руководства), но если вы делаете слияние вручную, вам нужно использовать «git add», чтобы завершить его (даже если вы не хотите фиксировать).
    2010-10-25 09: 37: 00Z

См. как представляются конфликты или в Git. документацию git merge, чтобы понять, что такое маркеры конфликта слияния.

Также в разделе Как разрешать конфликты объясняется как разрешить конфликты:

  

Увидев конфликт, вы можете сделать две вещи:

     
  • Решите не объединять. Единственная очистка, в которой вы нуждаетесь, - это сброс файла индекса до коммита HEAD для отмены 2. и очистка изменений рабочего дерева, сделанных 2. и 3 .; Для этого можно использовать git merge --abort.

  •   
  • Разрешите конфликты. Git отметит конфликты в рабочем дереве. Отредактируйте файлы в форму и git add их в индекс. Используйте git commit для заключения сделки.

  •   

Вы можете преодолеть конфликт с помощью ряда инструментов:

     
  • Используйте mergetool. git mergetool для запуска графического инструмента слияния, который проведет вас через слияние.

  •   
  • Посмотрите на различия. git diff будет показывать трехстороннюю разность, выделяя изменения как в версиях HEAD, так и в версиях MERGE_HEAD.

  •   
  • Посмотрите на различия из каждой ветви. git log --merge -p <path> покажет различия сначала для версии HEAD, а затем для версии MERGE_HEAD.

  •   
  • Посмотрите на оригиналы. git show :1:filename показывает сотрудничествоПредок mmon, git show :2:filename показывает версию HEAD, а git show :3:filename показывает версию MERGE_HEAD.

  •   

Вы также можете прочитать о маркерах конфликтов слияния и о том, как их разрешать, в разделе книги Pro Git Основные конфликты при слиянии .

    
44
2014-07-23 17: 22: 15Z

Для Emacs пользователей, которые хотят разрешать конфликты слиянием полу-вручную:

git diff --name-status --diff-filter=U

показывает все файлы, которые требуют разрешения конфликтов.

Откройте каждый из этих файлов по одному или все сразу:

emacs $(git diff --name-only --diff-filter=U)

При посещении буфера, требующего редактирования в Emacs, введите

ALT+x vc-resolve-conflicts

Это откроет три буфера (мой, их и выходной буфер). Перемещайтесь, нажимая «n» (следующий регион), «p» (регион предвидения). Нажмите «a» и «b», чтобы скопировать мой или их регион в выходной буфер, соответственно. И /или отредактируйте выходной буфер напрямую.

Когда закончите: нажмите «q». Emacs спросит вас, хотите ли вы сохранить этот буфер: да. После завершения буфера пометьте его как разрешенный, запустив его из терминалиста:

git add FILENAME

Когда закончите со всеми типами буферов

git commit

чтобы завершить слияние.

    
38
2014-07-23 17: 24: 52Z

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

Полностью принимайте мою или их версию .

Примите мою версию (локальную, нашу):

git checkout --ours -- <filename>
git add <filename>              # Marks conflict as resolved
git commit -m "merged bla bla"  # An "empty" commit

Примите их версию (удаленную, свою):

git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"

Если вы хотите выполнить для всех файлов конфликтов , выполните:

git merge --strategy-option ours

или р>

git merge --strategy-option theirs

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

  1. git mergetool
  2. Просмотрите изменения и примите любую версию для каждого из них.
  3. git add <filename>
  4. git commit -m "merged bla bla"

По умолчанию mergetool работает в командной строке . Как использовать командную строку mergetool должно быть отдельным вопросом.

Для этого вы также можете установить визуальный инструмент , например, meld и запустите

git mergetool -t meld

Откроется локальная версия (наша), «базовая» или «объединенная» версия (текущий результат слияния) и удаленная версия (их). Сохраните объединенную версию, когда закончите, снова запустите git mergetool -t meld, пока не появится сообщение «Нет необходимости объединять файлы», затем перейдите к Шагу 3. и 4.

    
35
2018-06-19 03: 29: 48Z
  1. Эта команда: git checkout --theirs - < filename > изменил ВСЕ файлы на свои, а не только на < filename >
    2018-06-26 01: 00: 29Z
  2. На самом деле я был не прав. Это только обновляет указанный файл.
    2018-06-26 01: 23: 15Z

Пожалуйста, выполните следующие шаги, чтобы исправить конфликты слияния в Git:

  1. Проверьте статус Git: git status

  2. Получите набор патчей: git fetch (извлеките правильный патч из вашего коммита Git)

  3. Оформите локальную ветку (в моем примере это temp1): git checkout -b temp1

  4. Извлеките последнее содержимое из master: мастер происхождения git pull --rebase

  5. Запустите mergetool, проверьте конфликты и исправьте их ... и проверьте изменения в удаленной ветви с вашей текущей веткой: git mergetool

  6. Проверьте статус еще раз: git status

  7. Удалите ненужные файлы, локально созданные с помощью mergetool, обычно mergetool создает дополнительный файл с расширением * .orig. Пожалуйста, удалите этот файл, так как это просто дубликат, исправьте изменения локально и добавьте правильную версию своих файлов. git add #your_changed_correct_files

  8. Проверьте статус еще раз: git status

  9. Передайте изменения в один и тот же идентификатор фиксации (это позволяет избежать нового отдельного набора исправлений): git commit --amend

  10. Нажмите на главную ветку: git push (в ваш репозиторий Git)

28
2018-06-19 03: 25: 07Z

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

git checkout . --ours

для разрешения изменений в пользу вашего хранилища или

git checkout . --theirs

для разрешения изменений в пользу другого или основного репозитория .

Или же вам придется использовать инструмент слияния с графическим интерфейсом для просмотра файлов один за другим, например, использовать инструмент слияния p4merge или написать имя, которое вы уже установили

git mergetool -t p4merge

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

    
28
2018-06-19 03: 26: 09Z
  1. git checkout. --Their решил мою проблему, спасибо
    2016-03-10 06: 53: 00Z
  2. если вы предпочитаете разрешать конфликты вручную, попробуйте открыть папку в коде Visual Studio, она помечает файлы с конфликтами и конфликтует цветами внутри каждой из них
    2016-07-03 08: 31: 42Z

Бонус:

Говоря о pull /fetch /merge в приведенных выше ответах, я хотел бы поделиться интересным и продуктивным приемом,

git pull --rebase

Эта команда является самой полезной в моей жизни в git, которая сэкономила много времени.

Прежде чем отправлять только что подтвержденные изменения на удаленный сервер, попробуйте git pull --rebase, а не git pull и руководство merge, и он автоматически синхронизирует последние изменения удаленного сервера (с выборкой + слиянием) и поместит ваш локальный последний коммит в верхнюю часть журнала git. Не нужно беспокоиться о ручном вытягивании /слиянии.

В случае конфликта просто используйте

git mergetool
git add conflict_file
git rebase --continue

Подробности можно найти по адресу: http://gitolite.com/git-pull--rebase р>     

27
2015-12-31 03: 30: 19Z

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

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

Я лично привык иметь в виду две вещи, которые помогут избежать этого.

Вместо:

git add .
git commit -m"some msg"

Который имеет два недостатка -

a) Все новые /измененные файлы добавляются, что может включать некоторые нежелательные изменения.
б) Вы не можете сначала просмотреть список файлов.

Так что вместо этого я делаю:

git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.

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

[Обновление - со временем я переключился на:

git status # Make sure I know whats going on
git add .
git commit # Then use the editor

] р>

Также (и в большей степени в вашей ситуации) я стараюсь избегать:

git pull

или р>

git pull origin master.

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

Вместо этого я пытаюсь сделать

git checkout master
git fetch   
git rebase --hard origin/master # or whatever branch I want.

Вы также можете найти это полезным:

git ветвление, разветвление, выборка, слияние, перебазирование и клонирование, в чем различия?

    
25
2017-05-23 12: 18: 27Z
  1. Эй, я вроде понял ваш ответ. Но так как я новичок в конфликтах github слияния, я думаю, что-то не хватает. Что происходит с вашими локальными изменениями, когда вы делаете git checkout master и git fetch и git rebase --hard origin/master
    2017-08-08 17: 43: 36Z
  2. Я полагаю, вам следует добавить дополнительные сведения о том, что делать. Другой пример, который меня смущает, вы упомянули в своем ответе: мы делаем git add ., сохранит ли он наши локальные модификации, чтобы мы могли продолжить с git checkout master? или это два разных сценария?
    2017-08-08 17: 47: 14Z

Есть 3 шага:

  1. Определите, какие файлы вызывают конфликты по команде

    git status
    
  2. Проверьте файлы, в которых вы найдете конфликты, помеченные как

    <<<<<<<<head
    blablabla
    
  3. Измените его так, как вам нужно, затем подтвердите его командами

    git add solved_conflicts_files
    git commit -m 'merge msg'
    
25
2018-07-05 21: 03: 45Z
  1. Работал для меня! Спасибо!
    2017-09-18 04: 00: 54Z
  2. Вы должны обратить внимание, если делаете это во время перебазирования. Вы должны использовать git rebase --continue вместо git commit
    2018-10-29 13: 37: 48Z

Ответ CoolAJ86 подводит итог почти всем. Если у вас есть изменения в обеих ветвях в одном и том же фрагменте кода, вам придется выполнить слияние вручную. Откройте файл в конфликте в любом текстовом редакторе, и вы должны увидеть следующую структуру.

(Code not in Conflict)
>>>>>>>>>>>
(first alternative for conflict starts here)
Multiple code lines here
===========
(second alternative for conflict starts here)
Multiple code lines here too    
<<<<<<<<<<<
(Code not in conflict here)

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

git commit -a -m "commit message"
git push origin master
    
22
2014-07-23 17: 17: 38Z
git log --merge -p [[--] path]

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

Чтобы обойти эту проблему, я открываю две командные строки и за один раз

git log ..$MERGED_IN_BRANCH --pretty=full -p [path]

а в другом

git log $MERGED_IN_BRANCH.. --pretty=full -p [path]

Замена $MERGED_IN_BRANCH ветвью, в которую я слился, и [path] файлом, который конфликтует. Эта команда будет регистрировать все коммиты в форме патча между (..) двумя коммитами. Если вы оставите одну сторону пустой, как в приведенных выше командах, git будет автоматически использовать HEAD (в данном случае ветвь, с которой вы объединяетесь).

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

    
15
2016-01-05 03: 45: 43Z

С 12 декабря 2016 года вы можете объединять филиалы и разрешать конфликты на github.com

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

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

 введите описание изображения здесь

    
15
2017-01-09 19: 57: 14Z
  1. это не вопрос о github, поэтому я проголосовал за то, что я считаю очень плохим ответом.
    2017-01-25 05: 06: 51Z
  2. спасибо, что держите меня в курсе, чувак.
    2017-01-26 23: 07: 24Z
  3. @ mschuett прав: вопрос в том, «как разрешать конфликты в git», а не «как разрешать конфликты в github». Есть разница, и уже слишком много людей думают, что git и github - это одно и то же, поэтому все, что распространяет это чувство, является неправильным.
    2018-04-05 16: 21: 56Z

Использование patience

Я удивлен, что никто больше не говорил об урегулировании конфликта с использованием patience с рекурсивной стратегией слияния. Для большого конфликта слияния использование patience дало хорошие результаты для меня. Идея состоит в том, что он будет пытаться сопоставить блоки, а не отдельные строки.

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

git merge -s recursive -X patience other-branch

Из документации:

With this option, merge-recursive spends a little extra time to avoid 
mismerges that sometimes occur due to unimportant matching lines 
(e.g., braces from distinct functions). Use this when the branches to 
be merged have diverged wildly.

Сравнение с общим предком

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

git diff $(git merge-base <our-branch> <their-branch>) <their-branch>

Обычно вы хотите видеть изменения только для определенного файла:

git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
    
15
2018-06-19 03: 31: 39Z
  1. В моем случае это не помогло разрешить конфликты слияния, так как по какой-то причине в проектах C # сохранились повторяющиеся строки конфигурации. Хотя это было более дружелюбно, чем ВЕСЬ ФАЙЛ РАЗЛИЧНЫЙ, который я имел раньше
    2017-09-08 07: 55: 23Z

Я всегда выполняю следующие шаги, чтобы избежать конфликтов.

  • мастер git checkout (зайдите в ветку master)
  • git pull (обновите мастер, чтобы получить последний код)
  • git checkout -b mybranch (извлеките новую ветку и начните работать над этой веткой, чтобы ваш мастер всегда оставался верхом ствола.)
  • git add. И git commit И git push (в вашей локальной ветке после ваших изменений)
  • мастер git checkout (вернись к своему хозяину.)

Теперь вы можете делать то же самое и поддерживать столько локальных веток, сколько вам нужно, и работать одновременно, я просто делаю git checkout для вашей ветки, когда это необходимо.

    
12
2015-02-12 04: 25: 58Z

Если вы хотите объединить ветвь (тест) с мастером, вы можете выполнить следующие действия:

Шаг 1. Перейти в ветку

git checkout test

Шаг 2: git pull --rebase origin master

Шаг 3. Если есть конфликты, перейдите к этим файлам, чтобы изменить его.

Шаг 4. Добавьте эти изменения

git add #your_changes_files

Шаг 5: git rebase --continue

Шаг 6: если конфликт все еще существует, вернитесь к шагу 3 еще раз. Если нет конфликта, сделайте следующее: git push origin +test

Шаг 7: И тогда между тестом и мастером нет конфликта. Вы можете использовать слияние напрямую.

    
11
2018-06-19 03: 23: 34Z

Конфликты слияния могут возникать в разных ситуациях:

  • При запуске "git fetch", а затем "git merge"
  • При запуске "git fetch", а затем "git rebase"
  • При запуске "git pull" (который фактически равен одному из вышеупомянутых условий)
  • При запуске "git stash pop"
  • Когда вы применяете git-патчи (коммиты, которые экспортируются в файлы для передачи, например, по электронной почте)

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

https://sourceforge.net/projects/kdiff3/files/ р>

Кстати, если вы устанавливаете Git Extensions, в его мастере настройки есть опция для установки Kdiff3.

Затем настройте git config для использования Kdiff в качестве mergetool:

$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false

$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false

(Не забудьте заменить путь на фактический путь к исполняемому файлу Kdiff.)

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

$git mergetool

Затем он открывает Kdiff3 и сначала пытается автоматически разрешить конфликты слияния. Большинство конфликтов будут разрешены спонтанно, а остальные нужно исправить вручную.

Вот как выглядит Kdiff3:

 Введите описание изображения здесь

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

Чтобы проверить, все ли успешно объединено, просто запустите команду mergetool еще раз, вы должны получить такой результат:

$git mergetool
No files need merging
    
11
2018-06-19 03: 28: 18Z

Этот ответ заключается в том, чтобы добавить альтернативу для тех пользователей VIM, как я, которые предпочитают делать все в редакторе.

TL; DR

 введите описание изображения здесь

Tpope разработала этот замечательный плагин для VIM, который называется fugitive . После установки вы можете запустить :Gstatus, чтобы проверить конфликтующие файлы, и :Gdiff, чтобы открыть Git тремя способами слияния.

После трехстороннего слияния fugitive позволит вам получить изменения в любой из веток, которые вы объединяете, следующим образом:

  • :diffget //2, получите изменения из исходной ( HEAD ) ветки:
  • :diffget //3, получите изменения из ветви слияния:

После завершения слияния файла введите :Gwrite в объединенном буфере. Vimcasts выпустил отличное видео , подробно объясняющее это шаги.

    
7
2018-05-10 11: 45: 24Z
  

git fetch
  git checkout ваша ветка
  мастер git rebase

На этом этапе вы попытаетесь исправить конфликт, используя предпочитаемую среду IDE.

Вы можете перейти по этой ссылке, чтобы проверить, как исправить конфликт в файле
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/

  

git add
  git rebase - продолжение
  git commit --amend
  git push origin HEAD: ссылки /черновики /master (push как черновики)

Теперь все в порядке, и вы найдете свой коммит в геррите

Я надеюсь, что это поможет всем по этому вопросу.

    
4
2017-07-05 13: 25: 30Z

Gitlense For VS Code

Вы можете попробовать Gitlense для кода VS, основными функциями которого являются:

3. Легко разрешать конфликты.

Мне уже нравится эта функция:

 введите описание изображения здесь

2. Виновность текущей линии.

 введите описание изображения здесь

3. Виноват желоб

 введите описание изображения здесь

4. Обвинение в статусной строке

 введите описание изображения здесь

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

    
4
2019-01-05 18: 33: 46Z

Попробуйте код Visual Studio для редактирования, если вы этого еще не сделали. После попытки слияния (и попадания в конфликты слияния) .VS код автоматически обнаруживает конфликты слияния.

Это может помочь вам очень хорошо, показав, какие изменения были внесены в исходное, и должны ли вы принять incoming или

current change (имеется в виду оригинал до слияния) '?.

Это помогло мне, и это может сработать и для вас!

PS: он будет работать, только если вы настроили git с помощью своего кода и кода Visual Studio.

    
2
2018-03-16 06: 26: 08Z

Более безопасный способ разрешения конфликтов - использовать git-mediate (предложены общие решения тут довольно много ошибок имхо).

См. этот пост для краткого введения в его использование.

    
1
2016-12-29 16: 46: 35Z

Для тех, кто использует Visual Studio (2015 в моем случае)

  1. Закройте свой проект в VS. Особенно в больших проектах VS имеет тенденцию сходить с ума при слиянии с использованием пользовательского интерфейса.

  2. Выполните слияние в командной строке.

    git checkout target_branch

    git merge source_branch

  3. Затем откройте проект в VS и перейдите в Team Explorer - > Ветка. Теперь есть сообщение о том, что слияние ожидает рассмотрения, и прямо под сообщением перечислены конфликтующие файлы.

  4. Щелкните по конфликтующему файлу, и у вас будет возможность объединить, сравнить, взять источник, взять цель. Инструмент слияния в VS очень прост для насе.

1
2017-07-10 20: 29: 53Z
  1. Я использую VS Code 2017 для очень большого проекта, и у меня нет необходимости закрывать проект. Он справляется с этим довольно хорошо:)
    2017-08-10 16: 22: 46Z

Если вы используете intelliJ в качестве IDE Попробуйте объединить родителя с вашей веткой с помощью

git checkout <localbranch>
git merge origin/<remotebranch>

Это покажет все конфликты, подобные этому

  

A_MBPro: проверить происхождение anu $git merge /Auto-merging   src /test /java /com /.../TestClass.java CONFLICT   (содержание): конфликт слияния в   SRC /тест /Java /COM /.../TestClass.java

Теперь обратите внимание, что файл TestClass.java показан красным цветом в intelliJ Также будет отображаться статус git

Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified:   src/test/java/com/.../TestClass.java

Откройте файл в intelliJ, в нем будут разделы с

  <<<<<<< HEAD
    public void testMethod() {
    }
    =======
    public void testMethod() { ...
    }
    >>>>>>> origin/<remotebranch>

где HEAD - это изменения в вашей локальной ветке, а origin /- это изменения из удаленной ветви. Сохраните то, что вам нужно, и удалите то, что вам не нужно. После этого следует выполнить обычные шаги. Это

   git add TestClass.java
   git commit -m "commit message"
   git push
    
1
2017-08-07 15: 09: 13Z

Я следую приведенному ниже процессу.

Процесс устранения конфликта слияния:

  1. Сначала извлеките последнюю версию из ветви назначения, в которую вы хотите объединить git pull origin develop

  2. Получив последние сведения из пункта назначения, теперь разрешите конфликт вручную в IDE, удалив эти дополнительные символы.

  3. Сделайте git add, чтобы добавить эти отредактированные файлы в очередь git, чтобы они могли быть commit и push для той же ветви, над которой вы работаете.

  4. Как только git add готово, выполните git commit, чтобы зафиксировать изменения.

  5. Теперь внесите изменения в вашу рабочую ветку до git push origin HEAD

Это все, и вы увидите, что оно разрешено в вашем запросе на получение доступа, если вы используете Bitbucket или GitHub.

    
1
2017-11-23 09: 06: 54Z
источник размещен Вот