Есть ли хороший способ объяснить, как разрешать конфликты слияния в Git?
Попробуйте: 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 mergetool -y
чтобы сохранить несколько нажатий клавиш, если вы объединяете много файлов одновременно.
git mergetool
для меня привел к использованию vimdiff
. Вместо этого вы можете установить один из следующих инструментов: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge
.
Здесь вероятный прецедент, сверху:
Вы собираетесь внести некоторые изменения, но, к сожалению, вы не в курсе:
git fetch origin
git pull origin master
From ssh://[email protected]: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://[email protected]: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://[email protected]:22/projectname
* branch master -> FETCH_HEAD
Already up-to-date.
Та-да!
Я нахожу, что инструменты слияния редко помогают мне понять конфликт или разрешение. Я обычно более успешно смотрю маркеры конфликтов в текстовом редакторе и используя git журнал в качестве дополнения.
Вот несколько советов:
Самое лучшее, что я нашел, это использовать стиль конфликта слияния "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
Это не то же самое, что использовать инструмент слияния, так как инструмент слияния будет включать все неконфликтующие diff-ханки. Я считаю, что это отвлекает.
Кто-то уже упомянул об этом, но понимание намерения за каждым словом diff обычно полезно для понимания того, откуда возник конфликт и как его обрабатывать.
git log --merge -p <name of file>
Это показывает все коммиты, которые касались этого файла между общим предком и двумя головами, которые вы объединяете. (Таким образом, он не включает в себя коммиты, которые уже существуют в обеих ветвях до слияния.) Это помогает игнорировать различия, которые явно не являются фактором в вашем текущем конфликте.
Проверьте свои изменения с помощью автоматизированных инструментов.
Если у вас есть автоматические тесты, запустите их. Если у вас есть lint, запустите его. Если это строительный проект, тогда его необходимо построить до того, как вы совершите и т.д. Во всех случаях вам нужно немного пройти тестирование, чтобы убедиться, что ваши изменения ничего не сломали. (Черт, даже слияние без конфликтов может нарушить рабочий код.)
Планируйте заранее; общаться с коллегами.
Планирование вперед и осознание того, что работают другие, может помочь предотвратить конфликты слияния и/или помочь решить их раньше - в то время как детали все еще актуальны.
Например, если вы знаете, что вы и другой человек работают над различными рефакторингами, которые будут влиять на один и тот же набор файлов, вам следует поговорить друг с другом заблаговременно и лучше понять, какие типы изменений каждый из вас делает. Вы можете сэкономить немало времени и усилий, если проводить запланированные изменения поочередно, а не параллельно.
Для крупных рефакторингов, которые пересекают большой фрагмент кода, вы должны серьезно рассмотреть возможность работы последовательно: каждый перестает работать над этой областью кода, а один человек выполняет полный рефакторинг.
Если вы не можете работать последовательно (из-за временного давления, возможно), то общение о ожидаемых конфликтах слияния, по крайней мере, поможет вам решить проблемы раньше, пока детали еще свежи. Например, если сотрудник совершает разрушительную серию коммитов в течение одной недели, вы можете захотеть объединить/переупаковать эту ветку один или два раза в день на этой неделе. Таким образом, если вы найдете конфликты слияния/переадресации, вы можете решить их быстрее, чем если вы подождете несколько недель, чтобы объединить все вместе в один большой кусок.
Если вы не уверены в слиянии, не заставляйте его.
Слияние может ощущаться подавляющим, особенно когда есть много конфликтующих файлов, а маркеры конфликтов охватывают сотни строк. Часто при оценке программных проектов мы не включаем достаточно времени для надбавок, таких как обработка сумасшедшего слияния, поэтому он чувствует себя как реальное сопротивление, чтобы потратить несколько часов на анализ каждого конфликта.
В долгосрочной перспективе планирование вперед и осознание того, что работают другие, являются лучшими инструментами для прогнозирования конфликтов слияния и подготовки к правильному их решению за меньшее время.
p4merge
Perforce, который можно устанавливать и использовать отдельно от других инструментов Perforce (которые я не использовал, но слышал жалобы).
Определите, какие файлы находятся в конфликте (Git должен сказать вам это).
Откройте каждый файл и изучите различия; Git демаркирует их. Надеюсь, будет очевидно, какую версию каждого блока сохранить. Возможно, вам придется обсудить это с другими разработчиками, которые совершили код.
Как только вы разрешили конфликт в файле git add the_file
.
Как только вы разрешите конфликты all, выполните git rebase --continue
или любую команду
Git сказал, когда закончите.
Проверьте ответы в вопросе Отмена слияния в 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
CLIВот простые шаги, которые нужно предпринять, когда вы попадаете в конфликтное состояние:
git status
(в разделе Unmerged paths
).Решите конфликты отдельно для каждого файла одним из следующих подходов:
Используйте GUI для разрешения конфликтов: git mergetool
(самый простой способ).
Чтобы принять удаленную/другую версию, используйте: git checkout --theirs path/file
. Это отклонит любые локальные изменения, которые вы сделали для этого файла.
Чтобы принять локальную/нашу версию, используйте: git checkout --ours path/file
Однако вы должны быть осторожны, поскольку удаленные изменения по каким-то причинам были устранены.
Отредактируйте конфликтующие файлы вручную и найдите блок кода между <<<<<
/>>>>>
, затем выберите версию сверху или снизу =====
. Смотрите: Как конфликты представлены.
Конфликты путей и имен файлов могут быть решены с помощью git add
/git rm
.
Наконец, просмотрите файлы, готовые для фиксации, используя: git status
.
Если у вас все еще есть файлы под Unmerged paths
, и вы разрешили конфликт вручную, то пусть Git знает, что вы его решили: git add path/file
.
Если все конфликты были успешно решены, скопируйте изменения: git commit -a
и нажмите на удаленный, как обычно.
См. также: Разрешение конфликта слияния из командной строки в GitHub
Я успешно использовал DiffMerge, который может визуально сравнивать и объединять файлы в Windows, macOS и Linux/Unix.
Он графически может отображать изменения между 3-мя файлами и позволяет автоматическое слияние (когда это безопасно) и полный контроль над редактированием результирующего файла.
Источник изображения: DiffMerge (снимок экрана Linux)
Просто загрузите его и запустите в репо как:
git mergetool -t diffmerge .
На 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 "$@"
Затем вы можете использовать следующие сочетания клавиш:
В качестве альтернативы вы можете использовать opendiff (часть Xcode Tools), которая позволяет объединить два файла или каталоги вместе, чтобы создать третий файл или каталог.
Если вы делаете частые мелкие коммиты, начните с просмотра комментариев коммита с помощью git log --merge
. Затем git diff
покажет вам конфликты.
Для конфликтов, которые связаны с несколькими строками, легче увидеть, что происходит во внешнем GUI-инструменте. Мне нравится opendiff - Git также поддерживает vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, emerge из коробки, и вы можете установить другие: git config merge.tool "your.tool"
установит ваш выбранный инструмент, а затем git mergetool
после неудачного слияния покажет вам различия в контексте.
Каждый раз, когда вы редактируете файл для разрешения конфликта, git add filename
обновляет индекс, и ваш diff больше не будет его показывать. Когда все конфликты обрабатываются и их файлы были git add
-ed, git commit
завершит слияние.
См. Как конфликты представлены или в Git, документации git merge
, чтобы понять, что такое маркеры конфликтов слияния.
Кроме того, в разделе Как разрешить конфликты объясняется, как разрешать конфликты:
После просмотра конфликта вы можете сделать две вещи:
Решите не сливаться. Единственные очистители, которые вам нужны, - это reset индексный файл для фиксации
HEAD
для обратного преобразования 2. и для очистки рабочих деревенских изменений, сделанных в 2. и 3;git merge --abort
можно использовать для этого.Разрешить конфликты. Git будет отмечать конфликты в рабочем дереве. Отредактируйте файлы в форме и
git add
их в индекс. Используйтеgit commit
, чтобы запечатать сделку.Вы можете работать в конфликте с помощью нескольких инструментов:
Используйте mergetool.
git mergetool
, чтобы запустить графический mergetool, который будет работать через слияние.Посмотрите на различия.
git diff
отображает трехсторонний diff, выделяя изменения как из версийHEAD
, так иMERGE_HEAD
.Посмотрите на различия между каждой ветвью.
git log --merge -p <path>
будет показывать diff сначала для версии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
чтобы завершить слияние.
Проще говоря, если вы хорошо знаете, что изменения в одном из репозиториев не важны, и хотите разрешить все изменения в пользу другого, используйте:
git checkout . --ours
разрешить изменения в пользу вашего хранилища, или
git checkout . --theirs
разрешить изменения в пользу другого или основного хранилища.
Или же вам придется использовать инструмент слияния GUI для пошагового просмотра файлов, скажем, инструмент слияния p4merge
, или написать любое имя, которое вы уже установили
git mergetool -t p4merge
и после завершения файла вам придется сохранить и закрыть, чтобы открыть следующий.
Я либо хочу свою или их версию полностью, либо хочу просмотреть отдельные изменения и принять решение для каждого из них.
Полностью примите мою или их версию:
Примите мою версию (локальную, нашу):
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: статус 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)
Вы можете исправить конфликты слияния несколькими способами, как другие детализировали.
Я думаю, что реальный ключ - это знание того, как изменения текут с локальными и удаленными репозиториями. Ключом к этому является понимание ветвей отслеживания. Я обнаружил, что я думаю о ветке отслеживания как "недостающей части в середине" между мной, моим локальным, фактическим файловым каталогом и удаленным, определяемым как происхождение.
Я лично привык к двум вещам, чтобы помочь избежать этого.
Вместо:
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 ветвь, fork, fetch, merge, rebase и clone, каковы различия?
git checkout master
git fetch
и git rebase --hard origin/master
git add .
Сохранит ли он наши локальные модификации, чтобы мы могли продолжить работу с git checkout master
? или это два разных сценария?
Говоря о 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
Ответ 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
Есть 3 шага:
Найти какие файлы вызывают конфликты по команде
git status
Проверьте файлы, в которых вы найдете конфликты, помеченные как
<<<<<<<<head
blablabla
Измените его так, как вы хотите, затем подтвердите с помощью команд
git add solved_conflicts_files
git commit -m 'merge msg'
С 12 декабря 2016 года вы можете объединять ветки и разрешать конфликты на github.com
Таким образом, если вы не хотите использовать командную строку или любые сторонние инструменты, предлагаемые здесь из более старых ответов, перейдите к собственному инструменту GitHub.
Это сообщение в блоге подробно объясняется, но основы заключаются в том, что при объединении двух ветвей через пользовательский интерфейс вы увидите" разрешить конфликты, который приведет вас к редактору, позволяющему справиться с этими конфликтами слияния.
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
(ветвь, в которую вы сливаетесь в этом случае).
Это позволит вам увидеть, какие коммиты вошли в файл в двух ветвях после их расхождения. Обычно это упрощает разрешение конфликтов.
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 к вашей ветке, когда это необходимо.
Конфликты слияния могут возникать в разных ситуациях:
Вам нужно установить инструмент слияния, совместимый с 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
Если вы хотите объединить ветвь (тест) с мастером, вы можете выполнить следующие шаги:
Шаг 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: И тогда между тестом и мастером нет конфликта. Вы можете использовать слияние напрямую.
Этот ответ заключается в том, чтобы добавить альтернативу тем пользователям VIM, как я, которые предпочитают делать все в редакторе.
Tpope придумали этот замечательный плагин для VIM под названием fugitive. После установки вы можете запустить :Gstatus
для проверки конфликтующих файлов и :Gdiff
чтобы открыть Git тремя способами слияния.
После трехстороннего слияния fugitive позволит вам получить изменения в любой из веток, которые вы объединяете, следующим образом:
:diffget//2
, получить изменения из оригинальной (HEAD) ветки::diffget//3
, получить изменения из ветки слияния: Как только вы закончите объединение файла, введите :Gwrite
в объединенном буфере. Vimcasts выпустил отличное видео, подробно объясняющее эти шаги.
git fetch
git checkout ваша ветка
git мастер переадресации
На этом шаге вы попытаетесь исправить конфликт, используя предпочитаемый вами вариант IDE
Вы можете перейти по этой ссылке, чтобы проверить ho, чтобы исправить конфликт в файле
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
git добавить
git rebase - продолжить git commit --amend
git push origin HEAD: refs/drafts/master (нажмите, как черновики)
Теперь все прекрасно, и вы найдете свою фиксацию в геррите
Я надеюсь, что это поможет каждому в решении этой проблемы.
Попробуйте Visual Studio Code для редактирования, если вы еще этого не сделали. После попытки слияния (и попадания в конфликты слияния).VS код автоматически обнаруживает конфликты слияния.
Это может помочь вам очень хорошо, показывая, какие изменения были внесены в оригинал, и если вы принимаете incoming
или
current change
(имеется в виду оригинальное перед слиянием) '?.
Это помогло мне, и это может работать на вас тоже!
PS: он будет работать, только если вы настроили git с помощью своего кода и кода Visual Studio.
Вы можете попробовать Gitlense для VS Code, ключевые характеристики которого:
Мне уже нравится эта функция:
И есть много возможностей, вы можете проверить их здесь.
Я следую нижеописанному процессу.
Процесс устранения конфликта слияния:
Сначала вытащите последнюю из ветки назначения, к которой вы хотите объединить git pull origin develop
По мере того, как вы получаете последнее сообщение от адресата, теперь разрешите конфликт вручную в среде IDE, удалив лишние символы.
Сделайте git add
, чтобы добавить эти отредактированные файлы в очередь git, чтобы она могла быть commit
и push
той же ветки, над которой вы работаете.
Как git add
, выполните a git commit
, чтобы зафиксировать изменения.
Теперь переместите изменения в рабочую ветвь на git push origin HEAD
Это он, и вы увидите, что он разрешен в вашем запросе на pull, если вы используете Bitbucket или GitHub.
Если вы используете intelliJ как IDE Попробуйте объединить родителя с веткой на
git checkout <localbranch>
git merge origin/<remotebranch>
Он отобразит все конфликты вроде этого
A_MBPro: test anu $ git слияние источника/автоматическое слияние 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
Для тех, кто использует Visual Studio (2015 в моем случае)
Закройте свой проект в VS. Особенно в больших проектах VS, как правило, увлекается слиянием с использованием пользовательского интерфейса.
Сделайте слияние в командной строке.
git checkout target_branch
git merge source_branch
Затем откройте проект в VS и перейдите в Team Explorer → Branch. Теперь есть сообщение, в котором говорится, что Merge находится в ожидании, и конфликтующие файлы перечислены прямо под сообщением.
Нажмите конфликтующий файл, и у вас будет возможность объединить, сравнить, взять источник, принять цель. Инструмент слияния в VS очень прост в использовании.
У меня установлен Beyond Compare, поэтому при использовании git mergetool
он запускает BC, который имеет очень приятный графический интерфейс для выполнения любого слияния.
Если вы не хотите использовать какой-либо сторонний или графический инструмент, выполните шаги, указанные в этих документах, чтобы разрешить конфликты слияния.
https://githowto.com/resolving_conflicts
https://confluence.atlassian.com/bitbucket/resolve-merge-conflicts-704414003.html
git checkout branch1
git fetch origin
git rebase -p origin/mainbranch
Если есть конфликты слияния, исправьте их. Затем продолжите процесс git rebase –-continue
выполнив: git rebase –-continue
после исправления вы можете зафиксировать и передать свою локальную ветку в удаленную ветку.
git push origin branch1
Более безопасный способ разрешения конфликтов - использовать git-mediate (общие решения, предлагаемые здесь, являются довольно склонными к ошибкам imho).
См. этот пост для быстрого введения того, как его использовать.
Это всегда было быстрее и проще для меня, чем использование Git. Это особенно полезно, если изменения запутывают запрос на извлечение и ваша IDE не очень хорошо обрабатывает слияния Git.
В соответствии с github сообщение в блоге "Теперь вы можете разрешать простые конфликты слияния на GitHub прямо из ваших запросов на тягу, сохраняя вас в поездке на командной строки и помогать вашей команде сжимать запросы на загрузку быстрее".
Простыми словами, что вы делаете, нажимайте свои изменения в удаленный репозиторий на GitHub и объединить ваши изменения в запрос на перенос.
Пожалуйста, используйте следующую официальную github link, которая объясняет процесс простым шагом.
Если вы не хотите использовать github, вы всегда можете использовать diffftool. Мой рекомендуемый. См. Видео-учебник здесь.
Вот что я сделал на Windows 10
Настройте mergetool
, запустив
git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false
Бежать
git mergetool
Прервите любой из упомянутых конфликтов, пока все не будет сделано
Если вы не используете инструмент для слияния, сначала скопируйте код снаружи:
- 'checkout master'
- 'git pull' / get new commit
- 'git checkout' to your branch
- 'git rebase master'
Это разрешит конфликт, и вы сможете скопировать свой код.