(Предварительное примечание: я не использую ни один из этих инструментов. Вместо этого я устанавливаю merge.conflictStyle
в diff3
, который использует немного другой формат разметки в файле рабочего дерева. В большинстве случаев я могу легко решить эту проблему непосредственно в vim
. Если это слишком беспорядочно, иногда я буду использовать git show
для прямого извлечения трех входных данных, например, git show :1:path
. Но все разные, поэтому см. настройте KDiff3 как инструмент слияния и инструмент сравнения.)
Как настроить git так, чтобы мой любимый инструмент слияния открывался до возникновения конфликта?
Вы не можете. Что ж, вы могли бы, если бы написали свою собственную стратегию слияния — эквивалент git merge-recursive
— но никто не делал ничего подобного уже много лет, потому что это слишком сложно. К счастью, вам не нужно:
Я хотел бы слить вручную, а не разрешать вручную :)
Если возникает конфликт, Git записывает собственную попытку слияния с файлом рабочего дерева.1 Это то, что вы видите здесь в своем редакторе. Но Git оставил три входных файла в том, что Git называет по-разному: index, staging area и (редко в наши дни) cache. Это три имени для одного и того же: staging area относится к тому, как вы его используете, а cache относится к различным внутренним аспектам и index это какой-то бессмысленный термин. В этом случае лучше всего использовать слово «индекс», и я буду использовать его здесь.
Когда вы запускаете git mergetool
, Git должен запустить выбранный вами инструмент слияния для всех трех входных файлов, а также для четвертого (Git-attempt-at-merge с маркерами конфликта) файла рабочего дерева. Затем этот инструмент может показать вам некоторые или все эти различные входные данные. Затем вы можете использовать инструмент, независимо от того, как работает сам инструмент, чтобы выполнить разрешение вручную, полностью игнорируя попытку Git выполнить слияние, если хотите.
Обратите внимание, что три входных файла — база слияния, левый или локальный наш --ours
и правый или удаленный или --theirs
— которые git mergetool
предоставляет вашему инструменту слияния, являются просто временными файлами. Они не будут использоваться в качестве результата слияния. Файл, который будет использоваться в качестве результата слияния, когда ваш инструмент слияния сообщит Git, что слияние завершено, является основным файлом рабочего дерева: тем, в котором есть беспорядок. Таким образом, ваш инструмент должен перезаписать этот файл результатом слияния.
В отличие от Mercurial, ядро Git не имеет встроенных инструментов слияния (ну, кроме своего собственного по умолчанию, который он все равно всегда запускает, как часть стратегии слияния, которую вы выбираете с помощью -s
). Следовательно, вы или кто-то, кто настраивает для вас дистрибутив Git, должны указать Git, как запускать какой-либо конкретный внешний инструмент слияния. Каждая установка Git, как правило, будет иметь некоторый набор предварительно настроенных внешних инструментов слияния, которые могут включать или не включать нужный вам инструмент. Если вам нужно настроить собственный внешний инструмент слияния, см. раздел Git в Windows: как настроить инструмент слияния? (несмотря на заголовок, некоторые из его ответов хороши для систем, отличных от Windows. См., в частности, ответ CB Bailey.)
Четыре имени, с которыми должен работать ваш инструмент слияния, предоставляются как переменные среды: $BASE
— имя базового файла слияния (из промежуточного слота № 1 в индексе), $LOCAL
— имя файла --ours
(промежуточный слот № 2 в индексе), $REMOTE
— имена. файл --theirs
(промежуточный слот №3), а $MERGED
– это имя файла, который git mergetool
ожидает, что ваш инструмент слияния обновит его до того, как инструмент слияния сообщит об успешном или неудачном выполнении скрипта git mergetool
2.
1Помните, что Git хранит пригодные для использования копии ваших файлов в вашем рабочем дереве, но на самом деле создает коммиты из файлов специального формата Git, которые хранятся (косвенно) в индексе. Во время конфликтного слияния Git просто оставляет все три входных файла в индексе, используя ненулевые номера слотов индекса. Файл, который, по мнению Git, он разрешил сам по себе, помещается в обычную запись индекса с нулевым слотом, стирая ненулевые слоты, поэтому три входных файла здесь не так легко доступны. (На мой взгляд, это своего рода дефект, но Git не спрашивает моего мнения. Технически Git даже не записывает записи файлов в ненулевые слоты индекса, если он может тривиально объединить их при обработке файлов. Это вероятно для скорости и/или лени.)
2Ваш инструмент должен сигнализировать об успешном или неудачном завершении с помощью кода выхода на уровне ОС. Если это так, и вы настроили этот инструмент с trustExitCode
установленным на true
, git mergetool
будет знать, следует ли автоматически git add
файл $MERGED
. Если вы настроите trustExitCode
на false
, git mergetool
будет использовать некоторую эвристику, чтобы угадать, верить ли, что инструмент успешно объединил файлы.
person
torek
schedule
25.11.2019