У меня есть несколько локальных файлов, я вытаскиваю из удаленной ветки и возникают конфликты. Я знаю, что хотел бы сохранить свои локальные изменения и игнорировать удаленные изменения, вызывающие конфликты. Есть ли команда, которую я могу использовать, чтобы фактически сказать «пометить все конфликты как разрешенные, используйте локальные»?
git
merge
conflict
git-merge-conflict
Том Демилль
источник
источник
Ответы:
git checkout
имеет--ours
возможность проверить версию файла, который вы имели локально (в отличие--theirs
от версии, которую вы извлекли). Вы можете перейти,.
чтобыgit checkout
сказать это, чтобы проверить все в дереве. Затем вам нужно пометить конфликты как разрешенные, что вы можете сделатьgit add
, и зафиксировать свою работу после того, как закончите:Обратите внимание
.
наgit checkout
команду. Это очень важно и легко пропустить.git checkout
имеет два режима; один, в котором он переключает ветви, и другой, в котором он извлекает файлы из индекса в рабочую копию (иногда сначала вытягивая их в индекс из другой ревизии). Это отличает то, передали ли вы имя файла; если вы не передали имя файла, он пытается переключить ветки (хотя, если вы не передаете и ветку, он просто попытается снова проверить текущую ветку), но он отказывается это делать, если есть измененные файлы. что это повлияет. Итак, если вы хотите поведение, которое будет перезаписывать существующие файлы, вам нужно передать.
или имя файла, чтобы получить второе поведениеgit checkout
.Это также хорошая привычка иметь при передаче имени файла смещение
--
, напримерgit checkout --ours -- <filename>
. Если вы этого не сделаете, а имя файла совпадает с именем ветви или тега, Git подумает, что вы хотите проверить эту ревизию вместо того, чтобы проверить это имя файла, и, таким образом, использовать первую формуcheckout
команды ,Я немного подробнее расскажу о том, как конфликты и слияния работают в Git. Когда вы объединяете чужой код (который также происходит во время извлечения; извлечение - это, по сути, извлечение, за которым следует слияние), существует несколько возможных ситуаций.
Самое простое, что вы на одной ревизии. В этом случае вы «уже в курсе», и ничего не происходит.
Другая возможность состоит в том, что их ревизия просто является вашей наследницей, и в этом случае у вас по умолчанию будет «быстрое слияние», при котором ваше
HEAD
обновление будет обновлено до их фиксации, без слияния (это можно отключить, если вы очень хочу записать слияние, используя--no-ff
).Затем вы попадаете в ситуации, когда вам действительно нужно объединить две ревизии. В этом случае есть два возможных результата. Во-первых, слияние происходит чисто; все изменения находятся в разных файлах или в одних и тех же файлах, но достаточно далеко друг от друга, чтобы оба набора изменений можно было применить без проблем. По умолчанию, когда происходит чистое слияние, оно автоматически фиксируется, хотя вы можете отключить это с помощью,
--no-commit
если вам нужно отредактировать это заранее (например, если вы переименуете функциюfoo
вbar
, а кто-то еще добавит новый код, который вызываетfoo
, она слится чисто , но создайте сломанное дерево, так что вы можете захотеть очистить его как часть коммита слияния, чтобы избежать каких-либо битых коммитов).Последняя возможность состоит в том, что существует реальное слияние и возникают конфликты. В этом случае Git будет делать столько слияния , как он может, и создавать файлы с маркерами конфликтов (
<<<<<<<
,=======
и>>>>>>>
) в вашей рабочей копии. В индексе (также известном как «промежуточная область»; место, в котором хранятся файлыgit add
перед их фиксацией), у вас будет 3 версии каждого файла с конфликтами; Существует исходная версия файла от предка двух ветвлений, которые вы объединяете, версияHEAD
(с вашей стороны слияния) и версия из удаленной ветки.Чтобы разрешить конфликт, вы можете либо отредактировать файл, который находится в вашей рабочей копии, удалив маркеры конфликта и исправив код, чтобы он работал. Или вы можете проверить версию с одной или других сторон слияния, используя
git checkout --ours
илиgit checkout --theirs
. После того, как вы поместили файл в нужное вам состояние, вы указываете, что завершили слияние файла, и он готов к фиксации с помощьюgit add
, а затем вы можете зафиксировать слияние сgit commit
.источник
git add --all
все файлы добавляются в хранилище, так что это может добавить больше файлов, чем предполагалось, если ваши.gitignore
шаблоны не находятся в идеальном состоянии.git add -u
Вероятно, больше подходит для этой ситуации, у вас меньше шансов отредактировать отслеживаемые файлы, которые вы не хотите добавлять при разрешении слияния.git checkout --ours .
. Это.
важно; Передача имени файла (в данном случае всего каталога) позволяет выбрать один из двух режимов работы:checkout
один переключает ветви и другой перемещает файлы из индекса в рабочую копию. Я согласен, это очень запутанно. Вы такжеgit checkout --ours -- <filename>
можете проверить отдельный файл за раз.Убедитесь происхождения конфликта: если это результат
git merge
, см Брайан Кэмпбелл «s ответ .Но если это результат a
git rebase
, чтобы отбросить удаленные (их) изменения и использовать локальные изменения, вам необходимо выполнить:См. « Почему значения«
ours
»и«theirs
»поменялись местами», чтобы увидеть, какours
и какtheirs
они меняются во время перебазирования (потому что ветвь вверх по течению проверена).источник