Разрешение конфликта мерзавец слияния в пользу наших или их, не принимая весь файл из - PullRequest
1 голос
/ 03 мая 2019

Существует множество вопросов о том, как разрешать конфликты слияний в пользу того или иного филиала.Но самый распространенный ответ, который я нахожу, это использование git checkout --ours или git checkout --theirs.

Проблема в том, что git checkout примет файл весь из любой ветви.Могли быть части файла, которые слились просто отлично, и мы не хотим, чтобы они удалялись.

Итак, вопрос в том, что если файл находится в конфликтном состоянии, есть ли способ удалить конфликт?маркеры в пользу "наших" или "их" без применения этой стратегии ко всему слиянию или извлечения всего файла из "наших" или "их"?

Это определенно возможно припростой скрипт, но я хочу знать, есть ли существующее решение, которое я не нахожу.

Ответы [ 3 ]

2 голосов
/ 03 мая 2019

Если вы хотите разрешить все оставшиеся конфликты в файле с нашим или их файлом, это просто sed для каждой стороны и вашего стиля конфликта.

Для большинства файлов кода, где маркеры конфликта настолько чужды, что вам не нужно быть осторожными при их идентификации, вы можете просто набрать его:

sed -si '/^<<</,/^>>>/ {/^<<</,/^===/d;/^>>>/d}'  thefile  # keep theirs
sed -si '/^<<</,/^>>>/ {/^<<</d;/^===/,/^>>>/d}'  thefile  # keep ours

и сделать это для всего,

sed -si $yourpattern $(git ls-files -m | uniq)

самый простой.

Чтобы быть осторожнее с маркерами конфликтов, лучше создать простой скрипт, на который вы ссылались, а стиль отчета о конфликтах diff3 также нуждается в некоторых изменениях. Обычный счетчик символов конфликта равен 7, для большей безопасности установите диапазон sed /^<<<<<<< ours$/,/^>>>>>>> theirs$/, и с помощью diff3, сообщающего, "удалить наши" диапазон удаления начинается с ^||||||| base$, а не ^=======$.

Редактировать: sed на Mac был убит, чтобы отказаться от встроенных изменений без создания файла резервной копии, вы должны сделать, например, -si.bak и затем удалите резервную копию.

1 голос
/ 03 мая 2019

Я думаю, ты не должен так работать.Вместо этого вам следует установить подходящий редактор слияния (например, KDiff3), запустить git mergetool (который перебирает конфликтующие файлы и запускает установленный редактор слияний) и просмотреть изменения вручную.

Инструмент слиянияоткроет три версии файла в конфликте, автоматически примет все решаемые изменения так, как вы хотели, выделит оставшиеся конфликты.Если вы действительно не хотите просматривать их один за другим, выберите пункт меню «Объединить -> Выберите xxx для каждого неразрешенного конфликта» и tadah.

Если вы действительно уверены, что не хотитечтобы использовать инструмент визуального слияния, у вас есть следующие опции, ниже упомянутых torek.

Если вы хотите применить эту стратегию к каждому конфликтующему файлу во время одного слияния, используйте «наши»или «их» подопция стандартной стратегии слияния:

git merge -Xours ...

Не путайте с выбором всей стратегии слияния с помощью -s ours, которая просто забирает все у нас, не пытаясь сделатьслияние.

Если вы хотите применить эту стратегию к некоторым конкретным файлам во время при каждом слиянии , вы можете определить собственный драйвер слияния (в .gitconfig) и применитьэто к тем файлам (в .gitattributes).Это звучит намного сложнее, чем есть.Определение драйвера слияния просто означает определение командной строки, которая берет три входных файла и создает один выходной файл, например, вы можете использовать git merge-file, как объяснил @torek.После определения вы можете назначить такой драйвер слияния любому файлу или шаблону, создав файл .gitattributes в корне хранилища и зафиксировав его.Просто прочитайте об этом в https://git -scm.com / docs / gitattributes .

1 голос
/ 03 мая 2019

Редактировать: Как отмечает Маркус в комментарии, git mergetool может быть вызвано для одного файла.С правильным аргументом merge.tool или -t и настройкой mergetool.<tool>.cmd вы можете заставить его вызывать крошечный скрипт, который:

  • помещает версию файла --ours в рабочее деревоcopy, затем
  • использует это плюс базовую и --theirs версии файла в качестве аргументов для git merge-file --ours или git merge-file --theirs.

Код выхода этого "редактора"можно доверять (см. merge.<tool>.trustExitCode), что позволяет git mergetool запускать git add для вас.Таким образом, вы, вероятно, можете несколько сократить сценарий.

(я никогда этого не делаю, и фактически я никогда не использую git mergetool. Если бы я был , используя git mergetool, я бы хотелоцените результаты самостоятельно, как Маркус предлагает в своем ответе .)


Для этого не существует команды в одну строку, хотя, вероятно, должно быть и Вы можете написать его самостоятельно.

Команда, которая выполнит эту работу: git merge-file.Однако прежде чем вы сможете запустить git merge-file, вам понадобятся три входных файла, которые git merge видел.

Эти три файла существуют; проблема заключается визвлекая их.Команда git mergetool решает эту проблему, 1 , но, к сожалению, она решает ее не слишком полезным для вас способом.Вы хотите решить это для одного файла , но git mergetool повторяет его для всех необработанных файлов (и затем запускает на них выбранный вами инструмент слияния, обычно какой-то трехсторонний редактор)по одному).

git mergetool использует git checkout-index с опцией --stage.Три версии некоторого файла file.ext все находятся в index , как этап 1 (базовая версия слияния), этап 2 (--ours версия) и этап 3 (--theirs версия).При использовании git mergetool скрипт извлекает три в <em>file.ext</em>.BASE, <em>file.ext</em>.LOCAL и <em>file.ext</em>.REMOTE соответственно.Вы должны делать более или менее одно и то же, хотя вы можете выбрать разные имена.См. сценарий git mergetool (и, если хотите, его основной вспомогательный сценарий , хотя все, что вам здесь нужно, это основной - я связал непосредственно со строками, которые извлекаютфайлы, в то время как функция, которая реализует это в другом месте основного файла) для кода.

Как только у вас есть три входных файла, просто запустите на них git merge-file с правильными аргументами.См. документацию git merge-file , чтобы увидеть, что это за аргументы.Проверьте результат и, если хотите, поместите его на место вместо существующего файла рабочего дерева с разметкой конфликтов и используйте git add, чтобы исключить три файла с более высоким номером и записать объединенный файл в нулевой этап,где он готов к фиксации.

Разрешите оставшиеся неразрешенные файлы, как вам нравится.


1 Ну, то есть, он решает это в большинстве случаев.Для конфликтов переименования / переименования git mergetool просто запутывается: здесь немного не хватает информации в индексе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...