Git merge: получать конфликты как отдельные файлы для слияния с внешним инструментом - PullRequest
0 голосов
/ 06 декабря 2018

Когда я вытащил, у меня возник конфликт, но, как обычно, конфликт помечен в конфликтном файле как встроенный.

Я хотел бы получить «мои» и «их» как два / три отдельных файла.(.MINE, .THEIRS), чтобы я мог использовать специальный инструмент для этого типа файлов для выполнения слияния.

Возможно ли это с помощью git?

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Установите mergetool, чтобы Git открывался при запуске git mergetool.Git предоставляет 4 переменные с путями, которые вы можете передать команде, которая откроет ваш инструмент.Начиная с man git-mergetool:

Когда git mergetool вызывается с помощью этого инструмента (через опцию -t или --tool или переменную конфигурации merge.tool), будет вызываться сконфигурированная командная строкас $BASE, установленным на имя временного файла, содержащего общую базу для слияния, если доступно;$LOCAL установить имя временного файла, содержащего содержимое файла в текущей ветви;$REMOTE установить имя временного файла, содержащего содержимое файла для слияния, а $MERGED установить имя файла, в который инструмент слияния должен записать результат разрешения слияния.

Это может выглядеть, например:

[merge]
    tool = vimdiff

[mergetool "vimdiff"]
    cmd = vimdiff $LOCAL $BASE $REMOTE $MERGED -c '$wincmd w | wincmd J'
0 голосов
/ 06 декабря 2018

Да.Когда слияние завершается конфликтами, индекс содержит все три входных файла (не только ours и theirs, но также версию base из коммита слияния-базы).

Файл рабочего дерева, который вы просматривали, - это не то, о чем Git действительно очень заботится.Git напишет на рабочем дереве все возможное для объединения трех входов из индекса - то, что Git заботится о здесь, - и ваша задача, как человека, который наблюдает за слиянием, состоит в том, чтобы затем подойтис правильным результатом слияния и вставкой его обратно в индекс.Если вы можете сделать это только с тем беспорядком, который Git оставил в рабочем дереве, отлично.Если нет ...:

В индексе обычно есть только одна копия каждого файла.Эта одна копия помещается в «нулевой слот», и первоначально она соответствует подтвержденному вами извлеченному коммиту.

Копия файла рабочего дерева существует для , которую вы можете использовать, ноGit на самом деле его не использует, кроме случаев, когда вы запускаете git add <em>file</em>.Затем Git копирует копию файла рабочего дерева поверх поверх индексной копии, чтобы индексная копия снова соответствовала копии рабочего дерева (и, вероятно, больше не совпадает с копией текущего коммита).

Во времяпри слиянии копия с нулевым временным интервалом оказывается в гнезде 2 (--ours).Копия того же файла из базы слияния попадает в слот 1. Копия того же файла из другого коммита - того, который вы объединяете - попадает в слот 3 (--theirs).Git пытается объединить все три копии, и если Git преуспевает сам по себе, Git помещает объединенную версию в нулевой слот (и копирует ее в рабочее дерево) и очищает слоты слияния.Если Git завершается неудачно, он оставляет занятые слоты слияния с пустым нулевым слотом.

Так что, если беспорядок рабочего дерева, оставленный Git, недостаточно хорош, вы можете просто извлечь все три индексные копии.Способ сделать это вручную - использовать git checkout-index, но в целом более простой (если не совсем понятный) способ сделать это - использовать git mergetool.

Команда git mergetool по сути, это большой сценарий оболочки, который запускает git checkout-index на всех трех копиях каждого еще не распакованного файла, а затем запускает любую команду по вашему выбору для этих трех копий.Эта команда должна записать правильный объединенный файл в четвертый файл:

... настроенная командная строка будет вызываться с $BASE, установленным на имя временного файла, содержащего общую базу дляобъединить, если доступно;$LOCAL установить имя временного файла, содержащего содержимое файла в текущей ветке;$REMOTE установить в качестве имени временного файла, содержащего содержимое файла для слияния, а $MERGED установить в качестве имени файла, в который инструмент слияния должен записать результат разрешения слияния.

Опять же, все эти временные файлы создаются с помощью git mergetool с использованием git checkout-index для извлечения их из индекса.Когда ваш инструмент завершает работу, сценарий использует git add в файле $MERGED, чтобы удалить записи слота 1-3 и записать запись с нулевым слотом.

Появляется фраза , если доступна выше, потому что в нескольких угловых случаях произошел конфликт слияния из-за того, что в одном файле отсутствует .Например, конфликт добавления / добавления возникает, когда нет базы слияния версии newfile.ext, но оба --ours и --theirs do имеютnewfile.ext и два файла не совпадают.Здесь база будет отсутствовать;$LOCAL и $REMOTE оба будут существовать.Конфликт изменение / удаление возникает, когда в базовом коммите было file.ext, вы (--ours) или они (--theirs) изменили файл, а другойВы / они удалили файл.Здесь $BASE будет существовать, но будет существовать только один из $LOCAL или $REMOTE.

Поскольку git mergetool - это сценарий оболочки , выможете скопировать и изменить его - вам понадобится несколько смежных файлов;исследуйте отсюда, и они должны быть очевидны - если вы хотите каким-то образом изменить его работу, которая не поддерживается с помощью флагов и конфигурации инструмента.

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