Разрешить конфликты Git слияния в пользу их изменений во время вытягивания
Как мне разрешить конфликт git merge в пользу изменений?
По сути, мне нужно удалить все конфликтующие изменения из рабочего дерева без необходимости проходить через все конфликты с git mergetool
сохраняя все бесконфликтные изменения. Желательно делать это во время вытягивания, а не после.
20 ответов
Вы можете использовать рекурсивную опцию "их" стратегии:
git merge --strategy-option theirs
От мужчины:
ours
This option forces conflicting hunks to be auto-resolved cleanly by
favoring our version. Changes from the other tree that do not
conflict with our side are reflected to the merge result.
This should not be confused with the ours merge strategy, which does
not even look at what the other tree contains at all. It discards
everything the other tree did, declaring our history contains all that
happened in it.
theirs
This is opposite of ours.
Примечание. Как сказано в справочной странице, опция "наша" стратегия слияния сильно отличается от "нашей" стратегии слияния.
git pull -s recursive -X theirs <remoterepo or other repo>
Или просто для хранилища по умолчанию:
git pull -X theirs
Если вы уже в конфликтном состоянии...
git checkout --theirs path/to/file
Если вы уже находитесь в конфликтном состоянии и хотите просто принять все их:
git checkout --theirs .
git add .
Если вы хотите сделать наоборот:
git checkout --ours .
git add .
Это довольно радикально, поэтому убедитесь, что вы действительно хотите уничтожить все, как это, прежде чем делать это.
Хорошо, представьте сценарий, в котором я только что был:
Вы пытаетесь merge
или, может быть, cherry-pick
и вы остановились с
$ git cherry-pick 1023e24
error: could not apply 1023e24... [Commit Message]
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
Теперь вы просматриваете конфликтующий файл и действительно не хотите сохранять свои изменения. В моем случае выше, файл конфликтовал только на новой строке, которая была автоматически добавлена в моей IDE. Чтобы отменить изменения и принять их, самый простой способ:
git checkout --theirs path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php
Обратное утверждение (перезаписать входящую версию вашей версией)
git checkout --ours path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php
Удивительно, но я не мог найти этот ответ очень легко в сети.
Если вы уже находитесь в конфликтном состоянии и не хотите проверять пути один за другим. Вы можете попробовать
git merge --abort
git pull -X theirs
git pull -X theirs
ответы могут создать уродливый коммит слияния или выдать
ошибка: ваши локальные изменения в следующих файлах будут перезаписаны слиянием:
Если вы хотите просто игнорировать любые локальные изменения в файлах из репозитория, например, на клиенте, который всегда должен быть зеркалом источника, запустите это (замените master
с нужной веткой)
git fetch && git reset --hard origin/master
Как это работает? git fetch
делает git pull
но без слияния. затемgit reset --hard
заставляет ваше рабочее дерево соответствовать последнему коммиту. Все ваши локальные изменения в файлах в репо будут отброшены, но новые локальные файлы будут оставлены в покое.
После git merge, если у вас возникнут конфликты, и вы хотите, чтобы ваш или их
git checkout --theirs .
git checkout --ours .
Пожалуйста, не то, что иногда это не будет работать:
git checkout --our path / to / file
или же
git checkout - их путь / к / файлу
Я сделал это вместо этого, предполагая, что HEAD наша, а MERGE_HEAD их
git checkout HEAD -- path/to/file
или же:
git checkout MERGE_HEAD -- path/to/file
После того как мы это сделаем и у нас все хорошо
git add .
Если вы хотите понять больше, посмотрите замечательный пост от torek здесь: git checkout --ours не удаляет файлы из списка незакрытых файлов
VS Code (интегрированный Git) IDE Пользователи:
Если вы хотите принять все входящие изменения в файле конфликта, выполните следующие действия.
1. Go to command palette - Ctrl + Shift + P
2. Select the option - Merge Conflict: Accept All Incoming
Точно так же вы можете сделать для других опций, таких как Принять все оба, Принять все текущие и т. Д.,
Чтобы разрешить все конфликты с версией в конкретной ветке:
git diff --name-only --diff-filter=U | xargs git checkout ${branchName}
Итак, если вы уже находитесь в состоянии слияния и хотите сохранить основную версию конфликтующих файлов:
git diff --name-only --diff-filter=U | xargs git checkout master
Обновление 2023!
Если вы хотите принять все текущие изменения и игнорировать любые входящие изменения, вы можете сделать это:
git merge [branch] --strategy-option ours
[branch]
следует заменить именем ветки, которую вы объединяете с текущей веткой.
Если вместо этого вы знаете, что хотите перезаписать любые текущие изменения и принять все конфликты от входящих изменений, вы можете использоватьtheirs
стратегия вместо этого:
git merge [branch] --strategy-option theirs
git checkout --ours/theirs
не разрешает конфликты исключительно. Он проверяет (берет весь файл) либо из
ours/theirs
.
Предположим, у нас есть файл с изменениями в двух коммитах / ветках / деревьях / чем угодно. Если был конфликт, внесенный ими, а также модификация, и мы хотим разрешить конфликт, используя
ours
- затем используя
checkout --ours foo
отбросит изменения, вызывающие конфликты, но также и модификации.
Использование SED
Разрешите, используя их:
sed -i -e '/<<<<<<</,/=======/d' -e '/>>>>>>>/d' foo
-
-i
Измените файл на месте, -
/<<<<<<</,/=======/d
удалить все между включительно<<<<<<<
и=======
(наш) -
/>>>>>>>/d
удалить оставшийся маркер конфликта -
-e
указать несколько шаблонов для SED -
foo
файл
Разрешите с помощью наших:
sed -i -e '/<<<<<<</d' -e '/=======/,/>>>>>>>/d' foo
с https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging
Это в основном сделает поддельное слияние. Он будет записывать новый коммит слияния с обеими ветвями как родителями, но он даже не будет смотреть на ветвь, с которой вы сливаетесь. В результате слияния он просто записывает точный код в вашей текущей ветке.
$ git merge -s ours mundo
Слияние, сделанное по "нашей" стратегии.
$ git diff HEAD HEAD~
Вы можете видеть, что нет разницы между ветвью, в которой мы были, и результатом слияния.
Часто это может быть полезно, чтобы обмануть Git, думая, что ветвь уже объединена при последующем слиянии. Например, допустим, что вы разветвили ветку релиза и выполнили некоторую работу над ней, чтобы в какой-то момент вам захотелось вернуться обратно в вашу основную ветку. Тем временем некоторые исправления на master необходимо перенести в ветку релизов. Вы можете объединить ветку исправления ошибок с веткой выпуска, а также слить нашу ветку с нашей той же веткой в вашу основную ветку (даже если исправление уже существует), поэтому, когда вы позже снова объедините ветку выпуска, не возникнет конфликтов с исправлением ошибки.
Ситуация, которую я нашел полезной, если я хочу, чтобы master отражал изменения в новой ветке темы. Я заметил, что -Xtheirs не сливается без конфликтов в некоторых обстоятельствах... например
$ git merge -Xtheirs topicFoo
CONFLICT (modify/delete): js/search.js deleted in HEAD and modified in topicFoo. Version topicFoo of js/search.js left in tree.
В этом случае решение, которое я нашел, было
$ git checkout topicFoo
из topicFoo, первое слияние в master с использованием -s нашей стратегии, это создаст поддельный коммит, который является просто состоянием topicFoo. $ git merge - наш мастер
проверить созданный коммит слияния
$ git log
сейчас оформляю мастер ветку
$ git checkout master
объедините ветку темы обратно, но на этот раз используйте рекурсивную стратегию -Xtheirs, теперь вы увидите основную ветку с состоянием topicFoo.
$ git merge -X theirs topicFoo
Начнем с примера: у нас есть ветка и ветка с некоторыми конфликтами.
Получайте обновления перед оформлением заказа, чтобы основная ветка была актуальной:
git checkout main
git pull
git checkout dev
Затем объедините:
- если вы хотите принять входящие изменения из основного источника истины:
git merge --strategy-option theirs main
- если вы хотите принять текущие изменения в разработке как источник истины:
git merge --strategy-option ours main
ours
иtheirs
здесь особые слова, они имеют значение и не являются привычными, ноmain
илиdev
это могут быть любые другие две ветки, которые вы хотите объединить.
Принять удаленные изменения (theirs
) и в случае конфликтов вы получите следующую ошибку:
fatal: Not possible to fast-forward, aborting.
поэтому вы можете захотеть получить и принять их изменения с помощью быстрой перемотки вперед:
$ git pull -X theirs --ff
У меня был давний next-version
ветвь с тоннами удалений файлов, которые были изменены на develop
, файлы, которые были добавлены в разных местах обеих веток и т. д.
Я хотел взять все содержимое next-version
разветвляться в develop
Все в одном колоссальном слиянии коммитов.
Комбинация приведенных выше команд, которая сработала для меня, была:
git merge -X theirs next-version
# lots of files left that were modified on develop but deleted on next-version
git checkout next-version .
# files removed, now add the deletions to the commit
git add .
# still have files that were added on develop; in my case they are all in web/
git rm -r web
Не новый ответ, просто комбинируя кусочки из множества ответов, отчасти чтобы убедить, что вам могут понадобиться все эти ответы.
В Emacs, использующем режим слияния, чтобы разрешать все маркеры конфликтов, используя либо мои, либо их маркеры, мы можем определить:
(defun smerge-keep-mine-all ()
""
(interactive)
(beginning-of-buffer)
(while (progn (smerge-next) t)
(smerge-keep-mine)))
(defun smerge-keep-other-all ()
""
(interactive)
(beginning-of-buffer)
(while (progn (smerge-next) t)
(smerge-keep-other)))
Несмотря на то, что здесь уже есть отличные ответы, я хотел опубликовать этот ответ, чтобы задокументировать, как разрешать все конфликты слияния в Visual Studio (в качестве примера в пользу наших изменений).
Если вместо этого вы хотите принять входящие изменения ( их изменения), как указано в этом вопросе, просто заменитеours
на шаге 6 ниже сtheirs
. Это так просто.
Краткое изложение того, что я здесь делаю:
Объедините dev в мою ветку и при этом, если возникнут какие-либо конфликты слияния, внесите изменения из моей ветки.
(После того, как это будет сделано, я создам PR, чтобы окончательно передать изменения из моей ветки в dev ).
Шаг 1
Проверьте ветку, в которую вы хотите объединиться, перейдя в « Управление ветками » и дважды щелкнув имя своей ветки. В моем случае этоfeature\InterimBranchToDev2-AshK
.
Шаг 2:
Щелкните правой кнопкой мышиdev
и нажмитеMerge 'dev' into 'feature/InterimBranchToDev2-AshK'
Шаг 3:
Вы увидите массу конфликтов слияния!
Теперь очень утомительно щелкать правой кнопкой мыши каждый из этих файлов и нажиматьKeep Current (feature/InterimBranchToDev2-AshK)
, так что давайте позаботимся об этом с помощью командной строки.
Шаг 4:
УдарятьAbort
Шаг 5:
Открытьcmd
Шаг 6:
Типgit merge --strategy-option ours --no-commit dev
и нажмите ввод
Что это в основном означает: «Объединить dev в текущую ветку и, если есть какие-либо конфликты слияния, взять версию из текущей ветки, а также пока не выполнять слияние».
Это будет вывод:Automatic merge went well; stopped before committing as requested
Шаг 7:
Теперь перейдите в Visual Studio, конфликты хорошо улажены, и вы можете ввести свое сообщение и зафиксировать:
Я обнаружил, что мне нужно указать origin main как ветку, в которую я сливался.
git merge **origin main** --strategy-option theirs
Это решено.Чтобы разрешить все конфликты, выполните следующие простые шаги.
git fetch && git reset --hard origin/master
git pull -X theirs
git pull origin master