Как мне разрешить конфликты слияния в Git?
git
установке по умолчанию . Мне удалось попасть на стартовую страницу SE сегодня, 2017, с 1,3 млн просмотров и тысячами голосов в обе стороны. Захватывающий.
Как мне разрешить конфликты слияния в Git?
git
установке по умолчанию . Мне удалось попасть на стартовую страницу SE сегодня, 2017, с 1,3 млн просмотров и тысячами голосов в обе стороны. Захватывающий.
Ответы:
Пытаться: 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 mergetool -t bc3
).
Вот вероятный вариант использования сверху:
Вы собираетесь внести некоторые изменения, но, к сожалению, вы не в курсе:
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 merge --help
this question
Я считаю, что инструменты слияния редко помогают мне понять конфликт или решение. Я обычно более успешно смотрю на маркеры конфликта в текстовом редакторе и использую 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>
Это показывает все коммиты, которые коснулись этого файла между общим предком и двумя головами, которые вы объединяете. (Таким образом, он не включает коммиты, которые уже существуют в обеих ветвях до слияния.) Это помогает вам игнорировать блоки различий, которые явно не являются фактором в вашем текущем конфликте.
Проверьте свои изменения с помощью автоматизированных инструментов.
Если у вас есть автоматизированные тесты, запустите их. Если у вас есть ворсинки , запустите это. Если это проект для сборки, то создайте его перед фиксацией и т. Д. Во всех случаях вам нужно провести небольшое тестирование, чтобы убедиться, что ваши изменения ничего не сломали. (Черт, даже слияние без конфликтов может нарушить работающий код.)
Планировать заранее; общаться с коллегами.
Планирование заранее и знание того, над чем работают другие, может помочь предотвратить конфликты слиянием и / или помочь разрешить их раньше - пока детали еще свежи в памяти.
Например, если вы знаете, что вы и другой человек работаете над разным рефакторингом, который будет влиять на один и тот же набор файлов, вам следует заранее поговорить друг с другом и лучше понять, какие типы изменений у каждого из вас есть. решения. Вы можете сэкономить много времени и усилий, если планируете вносить изменения последовательно, а не параллельно.
Для крупных рефакторингов, которые затрагивают большую часть кода, вы должны строго рассмотреть возможность последовательной работы: все прекращают работать над этой областью кода, пока один человек выполняет полный рефакторинг.
Если вы не можете работать поочередно (возможно, из-за нехватки времени), то сообщение об ожидаемых конфликтах слияния по крайней мере поможет вам быстрее решить проблемы, пока детали еще свежи. Например, если сотрудник совершает серию разрушительных коммитов в течение однонедельного периода, вы можете выбрать слияние / перебазирование в этом филиале коллег один или два раза в день в течение этой недели. Таким образом, если вы обнаружите конфликты слияния / перебазировки, вы сможете решить их быстрее, чем если бы вы подождали несколько недель, чтобы объединить все в один большой кусок.
Если вы не уверены в слиянии, не форсируйте его.
Объединение может быть слишком сложным, особенно когда существует много конфликтующих файлов, а маркеры конфликтов занимают сотни строк. Часто при оценке программных проектов мы не учитываем достаточно времени для таких накладных расходов, как обработка грубого слияния, поэтому кажется, что нужно потратить несколько часов на анализ каждого конфликта.
В конечном счете, заблаговременное планирование и понимание того, над чем работают другие, являются лучшими инструментами для предвидения конфликтов слияний и подготовки к их правильному разрешению за меньшее время.
p4merge
, который можно установить и использовать отдельно от других инструментов Perforce (которые я не использовал, но слышал жалобы).
git config merge.conflictstyle diff3
- Спасибо, сэр. Это удивительно и освободило меня от попыток найти (и заплатить $$) за хороший 3-х сторонний графический интерфейс слияния. IMO, это лучше, потому что он показывает общего предка, а также локальный / удаленный, и показывает последние строки журнала коммитов, которые (AFAIK) никакой графический интерфейс не делает. Коммиты определенно помогут вам определить, какой код принадлежит какой ветке.
Определите, какие файлы конфликтуют (Git должен сообщить вам об этом).
Откройте каждый файл и изучите различия; Git разграничивает их. Надеемся, будет очевидно, какую версию каждого блока сохранить. Возможно, вам придется обсудить это с другими разработчиками, которые передали код.
После того, как вы решили конфликт в файле git add the_file
.
После того, как вы разрешите все конфликты, выполните git rebase --continue
или любую другую команду, которую Git сказал выполнить по завершении.
git add
файлы в индекс; это ничего не добавляет к хранилищу. git commit
добавляет вещи в хранилище. Такое использование имеет смысл для слияний - слияние автоматически ставит все изменения, которые могут быть слиты автоматически; Вы несете ответственность за объединение остальных изменений и добавление их в индекс после завершения.
Ознакомьтесь с ответами на вопрос переполнения стека. Отмена слияния в 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?
Отредактируйте конфликтующие файлы вручную и найдите блок кода между <<<<<
/ >>>>>
затем выберите версию сверху или снизу =====
. Смотрите: Как представлены конфликты .
Конфликты пути и имени файла могут быть решены с помощью git add
/ git rm
.
Наконец, проверьте файлы готовы для фиксации с помощью: git status
.
Если у вас есть какие - либо файлы в Unmerged paths
, и ты разрешить конфликт вручную, то пусть Git знаю , что вы решили его: git add path/file
.
Если все конфликты были успешно решены, передайте изменения с помощью: git commit -a
и нажмите на удаленный, как обычно.
Смотрите также: Разрешение конфликта слияния из командной строки на GitHub
Для практического руководства, проверьте: Сценарий 5 - Исправление конфликтов слияния по Katacoda .
Я успешно использовал 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), который позволяет объединить два файла или каталоги вместе, чтобы создать третий файл или каталог.
Если вы часто делаете небольшие коммиты, начните с просмотра комментариев коммитов 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
, git commit
завершится слияние.
Посмотрите, как представлены конфликты или, в 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 « Основные конфликты слияния» .
Я либо хочу свою или их версию полностью, либо хочу просмотреть отдельные изменения и принять решение для каждого из них.
Полностью принять мою или их версию :
Примите мою версию (локальную, нашу):
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.
Для пользователей 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. Не нужно беспокоиться о ручном вытягивании / слиянии.
В случае конфликта просто используйте
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
и после завершения файла, вам придется сохранить и закрыть, чтобы открыть следующий.
Пожалуйста, выполните следующие шаги, чтобы исправить конфликты слияния в 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)
Есть 3 шага:
Найти какие файлы вызывают конфликты по команде
git status
Проверьте файлы, в которых вы найдете конфликты, помеченные как
<<<<<<<<head
blablabla
Измените его так, как вы хотите, затем подтвердите с помощью команд
git add solved_conflicts_files
git commit -m 'merge msg'
Вы можете исправить конфликты слиянием несколькими способами, как подробно описано в других.
Я думаю, что реальный ключ в том, чтобы знать, как происходят изменения в локальных и удаленных репозиториях. Ключом к этому является понимание отслеживания ветвей. Я обнаружил, что я думаю о ветви отслеживания как о «недостающей части посередине» между моей локальной, действительной папкой с файлами и удаленной, определенной как источник.
Я лично привык к двум вещам, чтобы избежать этого.
Вместо:
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, в чем различия?
git checkout master
и git fetch
и git rebase --hard origin/master
git add .
, сохранит ли он наши локальные изменения, чтобы мы могли продолжить git checkout master
? или это два разных сценария?
$ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option
hard 'использование: git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] или: git rebase [-i] [ параметры] [--exec <cmd>] [--onto <newbase>] --root [<branch>] или: git rebase --continue | --abort | --skip | --edit-todo `
Ответ 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 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>
С 12 декабря 2016 года вы можете объединять филиалы и разрешать конфликты на github.com.
Таким образом, если вы не хотите использовать командную строку или какие-либо сторонние инструменты, предлагаемые здесь из более ранних ответов , используйте родной инструмент GitHub.
Этот пост в блоге объясняет подробно, но в основном это то, что после «слияния» двух ветвей через пользовательский интерфейс вы увидите опцию «разрешения конфликтов», которая приведет вас к редактору, позволяющему вам справиться с этими конфликтами слияния.
Если вы хотите объединить ветку (тест) с мастером, вы можете выполнить следующие шаги:
Шаг 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 : И тогда между тестом и мастером нет конфликта. Вы можете использовать слияние напрямую.
Я всегда выполняю следующие шаги, чтобы избежать конфликтов.
Теперь вы можете делать то же самое и поддерживать столько локальных веток, сколько хотите, и работать одновременно, просто когда я делаю git checkout в вашу ветку, когда это необходимо.
Конфликты слияния могут возникать в разных ситуациях:
Вам необходимо установить инструмент слияния, совместимый с 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
Этот ответ - добавить альтернативу тем пользователям VIM, как я, которые предпочитают делать все в редакторе.
Tpope придумали этот замечательный плагин для VIM под названием fugitive . После установки вы можете запустить, :Gstatus
чтобы проверить конфликтующие файлы и :Gdiff
открыть Git тремя способами слияния.
После трехстороннего слияния fugitive позволит вам получить изменения в любой из веток, которые вы объединяете, следующим образом:
:diffget //2
получить изменения из оригинальной ( HEAD ) ветки::diffget //3
получить изменения из сливающейся ветки: Как только вы закончите объединение файла, введите :Gwrite
объединенный буфер. Vimcasts выпустил отличное видео, подробно объясняющее эти шаги.
git fetch
git checkout ваша ветка
git rebase master
На этом этапе вы попытаетесь исправить конфликт, используя предпочитаемую 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: refs / drafts / master (push как черновики)
Теперь все хорошо, и вы найдете свой коммит в геррите
Я надеюсь, что это поможет всем, кто занимается этим вопросом.
Попробуйте Visual Studio Code для редактирования, если вы еще этого не сделали. После попытки слияния (и попадания в конфликты слияния) .VS код автоматически обнаруживает конфликты слияния.
Это может очень помочь вам, показывая, какие изменения были внесены в оригинал и должны ли вы принять incoming
или
current change
(имеется в виду оригинальный перед слиянием) '?.
Это помогло мне, и это может работать на вас тоже!
PS: он будет работать, только если вы настроили git с помощью своего кода и кода Visual Studio.
Более безопасный способ разрешения конфликтов - это использовать git-mediate (общие решения, предлагаемые здесь, довольно подвержены ошибкам imho).
Посмотрите этот пост для краткого введения о том, как его использовать.
Для тех, кто использует Visual Studio (2015 в моем случае)
Закройте свой проект в VS. Особенно в больших проектах VS имеет тенденцию сходить с ума при слиянии с использованием пользовательского интерфейса.
Выполните слияние в командной строке.
git checkout target_branch
git merge source_branch
Затем откройте проект в VS и перейдите в Team Explorer -> Branch. Теперь есть сообщение о том, что Merge находится на рассмотрении, а конфликтующие файлы перечислены прямо под сообщением.
Нажмите конфликтующий файл, и у вас будет возможность объединить, сравнить, взять источник, взять цель. Инструмент слияния в VS очень прост в использовании.
Если вы используете 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
Я использую визуальный код Microsoft для разрешения конфликтов. Его очень просто использовать. Я держу свой проект открытым в рабочей области. Он обнаруживает и выделяет конфликты, кроме того, дает опции графического интерфейса, чтобы выбрать любое изменение, которое я хочу сохранить от HEAD или входящего.