Как разрешить конфликты слияния в Git
Есть хороший способ объяснить, как разрешить конфликты слияния в Git?
41 ответ
Пытаться: 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 здесь и здесь
Шаг 4 Вы можете редактировать MERGED следующим образом
Если вы хотите получить изменения от REMOTE
:diffg RE
Если вы хотите получать изменения от BASE
:diffg BA
Если вы хотите получать изменения от LOCAL
:diffg LO
Шаг 5 Сохранить, выйти, зафиксировать и очистить
:wqa
сохранить и выйти из vi
git commit -m "message"
git clean
Удалите лишние файлы (например, *.orig), созданные инструментом diff.
Вот вероятный вариант использования сверху:
Вы собираетесь внести некоторые изменения, но, к сожалению, вы не в курсе:
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
Ой, о, мой, upstream изменил некоторые вещи, но просто чтобы использовать мои изменения... нет... их изменения...
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.
Та-да!
Я считаю, что инструменты слияния редко помогают мне понять конфликт или решение. Я обычно более успешно смотрю на маркеры конфликта в текстовом редакторе и использую 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>
Это показывает все коммиты, которые коснулись этого файла между общим предком и двумя головами, которые вы объединяете. (Таким образом, он не включает коммиты, которые уже существуют в обеих ветвях до слияния.) Это помогает вам игнорировать блоки различий, которые явно не являются фактором в вашем текущем конфликте.
Совет третий
Проверьте ваши изменения с помощью автоматизированных инструментов.
Если у вас есть автоматизированные тесты, запустите их. Если у вас есть ворсинки, запустите это. Если это сборочный проект, то создайте его перед фиксацией и т. Д. Во всех случаях вам нужно провести небольшое тестирование, чтобы убедиться, что ваши изменения ничего не сломали. (Черт, даже слияние без конфликтов может нарушить работающий код.)
Совет четвертый
Планировать заранее; общаться с коллегами.
Планирование заранее и знание того, над чем работают другие, может помочь предотвратить конфликты слиянием и / или помочь разрешить их раньше - пока детали еще свежи в памяти.
Например, если вы знаете, что вы и другой человек работаете над разным рефакторингом, который будет влиять на один и тот же набор файлов, вам следует заранее поговорить друг с другом и лучше понять, какие типы изменений у каждого из вас есть. изготовление. Вы можете сэкономить значительное время и силы, если планируете вносить изменения последовательно, а не параллельно.
Для крупных рефакторингов, которые затрагивают большую часть кода, вам следует настоятельно рекомендовать работать последовательно: все прекращают работать над этой областью кода, пока один человек выполняет полный рефакторинг.
Если вы не можете работать поочередно (возможно, из-за нехватки времени), то сообщение об ожидаемых конфликтах слияния по крайней мере поможет вам быстрее решить проблемы, пока детали еще свежи. Например, если сотрудник совершает серию разрушительных коммитов в течение однонедельного периода, вы можете выбрать слияние / перебазирование в этом филиале коллег один или два раза в день в течение этой недели. Таким образом, если вы обнаружите конфликты слияния / перебазировки, вы сможете разрешить их быстрее, чем если бы вы подождали несколько недель, чтобы объединить все вместе в один большой кусок.
Совет пятый
Если вы не уверены в слиянии, не форсируйте его.
Объединение может быть подавляющим, особенно когда много конфликтующих файлов и маркеры конфликта занимают сотни строк. Часто при оценке программных проектов мы не учитываем достаточно времени для таких накладных расходов, как обработка грубого слияния, поэтому кажется, что нужно потратить несколько часов на анализ каждого конфликта.
В конечном счете, заблаговременное планирование и знание того, над чем работают другие, являются лучшими инструментами для предвидения конфликтов слияний и подготовки к их правильному разрешению за меньшее время.
Определите, какие файлы конфликтуют (Git должен сообщить вам об этом).
Откройте каждый файл и изучите различия; Git разграничивает их. Надеюсь, будет очевидно, какую версию каждого блока сохранить. Возможно, вам придется обсудить это с другими разработчиками, которые передали код.
После того, как вы решили конфликт в файле
git add the_file
,Разрешив все конфликты, сделайте
git rebase --continue
или любую команду, которую Git сказал выполнить, когда вы закончите.
Конфликты слияния возникают, когда в файл одновременно вносятся изменения. Вот как это решить.
git
CLI
Вот простые шаги, которые нужно предпринять, когда вы попадаете в конфликтное состояние:
- Обратите внимание на список конфликтующих файлов с:
git status
(подUnmerged paths
раздел). Решите конфликты отдельно для каждого файла одним из следующих подходов:
Используйте графический интерфейс для разрешения конфликтов:
git mergetool
(самый простой способ).Чтобы принять удаленную / другую версию, используйте:
git checkout --theirs path/file
, Это отклонит любые локальные изменения, которые вы сделали для этого файла.Чтобы принять локальную / нашу версию, используйте:
git checkout --ours path/file
Однако вы должны быть осторожны, так как удаленные изменения, конфликты были сделаны по какой-то причине.
Связанный: Каково точное значение "наших" и "их" в git?
Отредактируйте конфликтующие файлы вручную и найдите блок кода между
<<<<<
/>>>>>
затем выберите версию сверху или снизу=====
, Смотрите: Как представлены конфликты.Конфликты пути и имени файла могут быть решены
git add
/git rm
,
Наконец, просмотрите файлы, готовые для фиксации, используя:
git status
,Если у вас все еще есть какие-либо файлы в
Unmerged paths
и вы решили конфликт вручную, а затем сообщите Git, что вы решили его:git add path/file
,Если все конфликты были успешно разрешены, внесите изменения:
git commit -a
и нажмите на пульт, как обычно.
Смотрите также: Разрешение конфликта слияния из командной строки на GitHub
DiffMerge
Я успешно использовал DiffMerge, который может визуально сравнивать и объединять файлы в Windows, macOS и Linux/Unix.
Он графически может отображать изменения между 3 файлами и позволяет автоматически объединять (когда это безопасно) и полностью контролировать редактирование полученного файла.
Источник изображения: 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-Вверх/Вниз, чтобы перейти к предыдущим / следующим изменениям.
- Al-Alt-Влево/Вправо, чтобы принять изменение слева или справа
В качестве альтернативы вы можете использовать opendiff (часть Xcode Tools), который позволяет объединить два файла или каталоги вместе, чтобы создать третий файл или каталог.
Ознакомьтесь с ответами на вопрос переполнения стека Отмена слияния в 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
Если вы часто делаете небольшие коммиты, то начните с просмотра комментариев коммитов с 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
завершит ваше слияние.
Я либо хочу свою или их версию полностью, либо хочу просмотреть отдельные изменения и принять решение для каждого из них.
Полностью примите мою или их версию:
Примите мою версию (локальную, нашу):
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
Просмотрите все изменения и примите их индивидуально
git mergetool
- Просмотрите изменения и примите любую версию для каждого из них.
git add <filename>
git commit -m "merged bla bla"
По умолчанию mergetool
работает в командной строке. Как использовать командную строку mergetool должно быть отдельным вопросом.
Вы также можете установить визуальный инструмент для этого, например, meld
и беги
git mergetool -t meld
Будет открыта локальная (наша), "базовая" или "объединенная" версия (текущий результат слияния) и удаленная (их). Сохраните объединенную версию, когда вы закончите, запустите git mergetool -t meld
снова, пока вы не получите "Нет необходимости объединять файлы", затем перейдите к Шагу 3. и 4.
Посмотрите, как представлены конфликты или, в 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
показывает общего предка,git show :2:filename
показываетHEAD
версия иgit show :3:filename
показываетMERGE_HEAD
версия.
Вы также можете прочитать о маркерах конфликта слияния и о том, как их разрешить, в разделе книги Pro Git Основные конфликты слияния.
Для пользователей 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
закончить слияние.
Бонус:
Говоря о pull / fetch / merge в приведенных выше ответах, я хотел бы поделиться интересным и продуктивным приемом:
git pull --rebase
Эта команда является самой полезной командой в моей жизни в git, которая сэкономила много времени.
Перед отправкой недавно внесенного изменения на удаленный сервер, попробуйте git pull --rebase
скорее git pull
и руководство merge
и он автоматически синхронизирует последние изменения удаленного сервера (с извлечением + слиянием) и поместит ваш локальный последний коммит вверху в git log. Не нужно беспокоиться о ручном вытягивании / слиянии.
В случае конфликта просто используйте
git mergetool
git add conflict_file
git rebase --continue
Подробности можно найти по адресу: http://gitolite.com/git-pull--rebase
Проще говоря, если вы хорошо знаете, что изменения в одном из репозиториев не важны, и хотите разрешить все изменения в пользу другого, используйте:
git checkout . --ours
разрешить изменения в пользу вашего хранилища, или
git checkout . --theirs
разрешить изменения в пользу другого или основного хранилища.
Или же вам придется использовать инструмент слияния GUI для пошагового просмотра файлов, скажем, инструмент слияния p4merge
или напишите любое имя, которое вы уже установили
git mergetool -t p4merge
и после завершения файла вам придется сохранить и закрыть, чтобы открыть следующий.
Есть 3 шага:
Найти какие файлы вызывают конфликты по команде
git status
Проверьте файлы, в которых вы найдете конфликты, помеченные как
<<<<<<<<head blablabla
Измените его так, как вы хотите, затем подтвердите с помощью команд
git add solved_conflicts_files git commit -m 'merge msg'
Пожалуйста, выполните следующие шаги, чтобы исправить конфликты слияния в Git:
Проверьте статус Git:статус Git
Получите набор патчей:git fetch (проверьте правильный патч из вашего коммита Git)
Извлечь локальную ветку (в моем примере это temp1):git checkout -b temp1
Извлеките недавнее содержимое из master:git pull --rebase origin master
Запустите mergetool, проверьте конфликты и исправьте их... и проверьте изменения в удаленной ветке с вашей текущей веткой:git mergetool
Проверьте статус снова: git status
Удалите ненужные файлы, локально созданные с помощью mergetool, обычно mergetool создает дополнительный файл с расширением *.orig. Пожалуйста, удалите этот файл, так как это просто дубликат, исправьте изменения локально и добавьте правильную версию ваших файлов.git add #your_changed_correct_files
Проверьте статус снова:git status
Зафиксируйте изменения в одном и том же идентификаторе (это позволяет избежать нового отдельного набора исправлений):git commit --amend
Push в ветку master:git push (в ваш репозиторий Git)
Ответ 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
Вы можете исправить конфликты слиянием несколькими способами, как подробно описано в других.
Я думаю, что реальный ключ в том, чтобы знать, как происходят изменения в локальных и удаленных репозиториях. Ключом к этому является понимание отслеживания ветвей. Я обнаружил, что я думаю о ветви отслеживания как о "недостающей части посередине" между мной, моим локальным каталогом файлов и удаленным, определенным как источник.
Я лично привык к двум вещам, чтобы избежать этого.
Вместо:
git add .
git commit -m"some msg"
Который имеет два недостатка -
а) Все новые / измененные файлы добавляются, и это может включать некоторые нежелательные изменения.
б) Вы не можете сначала просмотреть список файлов.
Так что вместо этого я делаю:
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 branch, fork, fetch, merge, rebase и clone, в чем различия?
Если вы хотите объединить ветвь (тест) с мастером, вы можете выполнить следующие шаги:
Шаг 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: И тогда между тестом и мастером нет конфликта. Вы можете использовать слияние напрямую.
С помощью 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>
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
(ветвь, с которой вы объединяетесь в этом случае).
Это позволит вам увидеть, какие коммиты вошли в файл в двух ветвях после их расхождения. Обычно это значительно облегчает разрешение конфликтов.
С 12 декабря 2016 года вы можете объединять филиалы и разрешать конфликты на github.com.
Таким образом, если вы не хотите использовать командную строку или какие-либо сторонние инструменты, предлагаемые здесь из более ранних ответов, используйте родной инструмент GitHub.
Этот пост в блоге объясняет подробно, но в основном это то, что после "слияния" двух ветвей через пользовательский интерфейс вы увидите опцию "разрешения конфликтов", которая приведет вас к редактору, который позволит вам справиться с этими конфликтами слияния.
Конфликты слияния могут возникать в разных ситуациях:
- При запуске "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
Я всегда выполняю следующие шаги, чтобы избежать конфликтов.
- git checkout master (приходите в ветку master)
- Git Pull (Обновите ваш мастер, чтобы получить последний код)
- git checkout -b mybranch (извлеките новую ветку и начните работать над этой веткой, чтобы ваш мастер всегда оставался верхом ствола.)
- мерзавец добавить. И git commit И git push (в вашей локальной ветке после ваших изменений)
- Git Checkout Master (Вернись к своему хозяину.)
Теперь вы можете делать то же самое и поддерживать столько локальных веток, сколько хотите, и работать одновременно, просто когда я делаю git checkout в вашу ветку, когда это необходимо.
Я понял, что такое конфликт слияния, но когда увидел результат
git diff
, мне сначала это показалось бессмысленным:
git diff
++<<<<<<< HEAD
+ display full last name boolean in star table
++=======
+ users viewer.id/star.id, and conversation uses user.id
+
++>>>>>>> feat/rspec-tests-for-cancancan
Но вот что мне помогло:
Все между
<<<<<<<
и то, что было в одном файле , иВсе между
=======
и>>>>>>>
это то, что было в другом файлеИтак, буквально все, что вам нужно сделать, это удалить эти строки из любой ветки (или просто сделать их одинаковыми), а
merge
сразу получится. Задача решена!
Этот ответ заключается в том, чтобы добавить альтернативу тем пользователям VIM, как я, которые предпочитают делать все в редакторе.
TL; DR
Tpope придумали этот замечательный плагин для VIM под названием fugitive. После установки вы можете запустить :Gstatus
проверить файлы, которые имеют конфликт и :Gdiff
открыть Git в 3 способа слияния.
После трехстороннего слияния fugitive позволит вам получить изменения в любой из веток, которые вы объединяете, следующим образом:
:diffget //2
получить изменения из оригинальной (HEAD) ветки::diffget //3
получить изменения из сливающейся ветки:
Когда вы закончите слияние файла, введите :Gwrite
в объединенном буфере.
Vimcasts выпустил отличное видео, подробно объясняющее эти шаги.
Я использую Microsoft Visual Code для разрешения конфликтов. Его очень просто использовать. Я оставляю свой проект открытым в рабочей области. Он обнаруживает и выделяет конфликты, а также предоставляет параметры графического интерфейса для выбора любых изменений, которые я хочу сохранить от HEAD или входящих.
мерзкий выбор
Git Оформить заказ вашей ветви
мастер git rebase
На этом этапе вы попытаетесь исправить конфликт, используя предпочитаемую IDE.
Вы можете перейти по этой ссылке, чтобы проверить, как исправить конфликт в файле
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
мерзавец добавить
git rebase - продолжение
git commit --amend
git push origin HEAD: ссылки / черновики /master (push как черновики)
Теперь все хорошо, и вы найдете свой коммит в геррите
Я надеюсь, что это поможет всем, кто занимается этим вопросом.
Попробуйте Visual Studio Code для редактирования, если вы еще этого не сделали. После попытки слияния (и попадания в конфликты слияния).VS код автоматически обнаруживает конфликты слияния.
Это может очень помочь вам, показывая, какие изменения были внесены в оригинал и должны ли вы принять incoming
или же
current change
(имеется в виду оригинальный перед слиянием)'?.
Это помогло мне, и это может работать на вас тоже!
PS: он будет работать, только если вы настроили git с помощью своего кода и кода Visual Studio.
Если вы используете intelliJ в качестве IDE, попробуйте объединить родителя с вашей веткой
git checkout <localbranch>
git merge origin/<remotebranch>
Это покажет все конфликты, как это
A_MBPro: проверить происхождение слияния anu$ git / авто-слияние src/test/java/com/.../TestClass.java CONFLICT (content): конфликт слияния в src / test / 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
Более безопасный способ разрешения конфликтов - использовать git-mediate (общие решения, предлагаемые здесь, довольно подвержены ошибкам imho).
Посмотрите этот пост для краткого введения о том, как его использовать.