Git Merge добавляет новый файл вместо маркеров конфликта - CONFLICT (переименовать / добавить) - PullRequest
0 голосов
/ 01 июня 2018

При запуске git merge origin master в командной строке я не получаю обычные маркеры конфликта <<<<<<, но вместо этого конфликтующие файлы копируются в мою локальную среду.

Может быть, это чем-то связанос изменяемым именем папки?

Пример:

git fetch origin master && git merge origin master
CONFLICT (rename/add): Rename javascript/main.js->js/main.js in HEAD. js/main.js added in %commit-hash%
Adding as js/main.js~%commit-hash% instead

Тогда у меня на локальном компьютере 2x файла: js/main.js & js/main.js~%commit-hash%

Как я могузаставить git работать с маркерами конфликта вместо нового файла?

& Кто-нибудь может пролить свет на то, почему это происходит?

  • примечание: %commit-hash% - этопросто заполнитель для фактического хеша коммитов для примера.

1 Ответ

0 голосов
/ 01 июня 2018

TL; DR

Попробуйте использовать -X find-renames=<value>, чтобы получить другое обнаружение переименования.Или, если это не сработает, или вам не нравится этот метод, извлеките все файлы из нескольких этапов, сохраненных в индексе, если это необходимо, а затем используйте git merge-file, чтобы создать конфликты «вручную».

Long

Это конфликт high level : конфликт, возникающий из-за нескольких разных файлов с изменяющимися именами вместо конфликта, который возникает внутри один файл .

Git сказал вам точно, в чем проблема:

Переименуйте javascript/main.js->js/main.js в HEAD ...

Таким образом, сравнивая текущий или HEAD коммит с общей базой слияния, с которой вы и они начали, Git обнаруживает, что you взял javascript/main.js и переименовал этот файл в js/main.js.

... js/main.js добавлено в hash

Они, кем бы они ни были, оставили файл javascript/main.js в javascript/main.js, но затем создал новый файл с именем js/main.js.

Поскольку может существовать только один файл с именем js/main.js, Git должен сделатьчто-то особенное.Он не может поместить ваш js/main.js (который вы переименовали из javascript/main.js) в js/main.js и положить их недавно созданных, но других js/main.js в js/main.js.Итак, он поместил их js/main.js в js/main.js~<em>hash</em>.

Как я могу заставить git работать с маркерами конфликта вместо нового файла?

Может бытьВы можете сделать это тривиально, а может и нет.

Сначала вы должны решить, является ли анализ ситуации в Git правильным. Вы переименовали javascript/main.js в js/main.js?И что сделал они делают: сделали они сохраняют свои исходные javascript/main.js и добавляют новые и отличные js/main.js, или они действительно переименовывают свои javascript/main.js, и это просто такGit не осознавал этого и думал, что они создали совершенно новый js/main.js, который не был связан с оригинальным javascript/main.js?

Если , проблема в том, что Git неправильно обнаружилДва переименования, вы можете попробовать настроить -X find-renames=<value> (имя -X rename-threshold=<value> в более старых версиях Git).Уменьшение числа делает Git более склонным воспринимать разные файлы как «один и тот же».Увеличение этого числа делает Git менее склонным рассматривать такие файлы как «одинаковые», до такой степени, что если вы установите его на 100%, содержимое файлов должно точно совпадать.

Если все это таки этот процесс идет хорошо, вы можете получить то, что вы хотите, и не нужно больше хитрости.Если нет, то:

Делаем это вручную

Если Git правильный, и ваш js/main.js действительно переименован , тогда как их js/main.js действительно новый, может быть нежелательно объединять файлы.Однако вы можете сделать это, используя git merge-file, который работает с обычными файлами в рабочем дереве.Во-первых, вам нужно получить все три файла в вашем рабочем дереве:

  • Базовая версия слияния, изначально называемая javascript/main.js в базовом коммите слияния (независимо от того, какой у нее хэш-идентификатор).
  • Версия --ours или HEAD с именем js/main.js в текущем коммите.
  • Версия --theirs, также называемая js/main.js, но в их коммите.

Две из этих трех версий уже доступны в вашем рабочем дереве, используя два имени, объявленных Git.

Также должна быть копия каждого файла в вашем индексе: база слияния естькак запись этапа 1, версия --ours или HEAD присутствует как запись этапа 2, а версия --theirs присутствует как запись этапа 3.Это означает, что вы можете использовать git show или git checkout-index, чтобы добраться до каждого.(На самом деле, вы, вероятно, можете использовать git checkout-idnex --stage=all, чтобы получить все из них как временные файлы одновременно, но я не экспериментировал с этим.) Поскольку вам все еще нужна базовая версия, вы можете использовать:

Например,
git show :1:js/main.js > main.js.base

(при условии, что используется оболочка в стиле Unix).

Когда у вас есть все три файла в вашем рабочем дереве, вы можете запустить:

git merge-file <head-version> <base-version> <their-version>

для создания в <head-version> версии файла, помеченной маркером конфликта.Если предположить имена, которые вы уже показали, и записать файл stage-1 в js/main.js.base, то это будет:

git merge-file js/main.js js/main.js.base js/main.js.~<hash>
...