Могу ли я настроить, как Git обнаруживает конфликты слияния

У меня есть инструмент, который может сравнивать и объединять двоичные файлы. Он также может попытаться автоматически объединить указанные двоичные файлы и прервать работу, если есть изменения, которые нельзя принять без вмешательства человека. Можно ли настроить git для использования моего инструмента, чтобы определить, приводит ли слияние к конфликту слияния?

Например, допустим, он может работать с.png-файлами. Если у меня есть две ветви A и B и на ветви A были изменения в пикселе в [150,100] и на ветви B были изменения в пикселе в [200, 50], Если я теперь объединю ветвь B с веткой A, мой инструмент обнаружит, что нет конфликтующих изменений, и просто автоматически объединит изображение, не вызывая конфликта.

2 ответа

TL;DR: вам нужен драйвер слияния, который вы объявляете для определенных файлов в .gitattributes, (Сам драйвер вы настраиваете в .git/config, Смотрите документацию по gitattributes.)

Вы не можете настроить, как Git решает, что какой-то файл должен быть объединен. Алгоритм принятия решения слишком прост для этого, поскольку он состоит из:

  1. Укажите три файла в базе слияния и две стороны (левую и правую, или наши и их).

    То есть предположим, что база слияния имеет файл с именем path/to/abc.png и обе стороны также имеют файлы с именем path/to/abc.png, Git предполагает, что все три имени представляют один и тот же базовый файл.

    Если, скажем, правильно (--theirs) сторона не имеет path/to/abc.png, но имеет different/path/to/xyz.png и этот файл, кажется, только что создан (не существует в базе слияния) и содержимое xyz.png достаточно похожи на те из базы abc.png Git может выбрать для идентификации их xyz.png с базой abc.png в конце концов, но теперь правая сторона имеет изменение имени, а также потенциальную разницу в содержании. Это - переименование файла - изменение высокого уровня.

    Точно так же, если одна сторона полностью удаляет файл, это также изменение высокого уровня. (Если обе стороны полностью удаляют файл, здесь нет проблем: результатом слияния является просто "удалить файл".) Решение о том, что одна или обе стороны удалили файл, возникает из-за отсутствия несопоставленного файла (такого как этот вновь созданный файл). xyz.png) это выглядит достаточно похожим.

  2. Теперь, когда мы / Git определили эти три файла как "одинаковые", требуется нетривиальное слияние, если выполняется одно из следующих условий:

    • И левая, и правая стороны изменили содержимое на другое. То есть хэши больших двоичных объектов в левой и правой сторонних коммитах для файла отличаются, и оба они отличаются от хэша BLOB-объекта базовой фиксации. Обратите внимание, что это еще не означает, что существует конфликт! Это просто означает, что требуется слияние.

    • Или, по крайней мере, одна сторона изменила содержимое, а другая сторона произвела изменение на высоком уровне, например, переименование или удаление файла. Это автоматически конфликт высокого уровня.

Если конфликт, обнаруженный в этот момент, является конфликтом высокого уровня, Git остановится и получит помощь. Однако он может сначала вызвать драйвер слияния для трех входных файлов, если это необходимо.

Оставляя в стороне любые конфликты высокого уровня или требования слияния, Git теперь решает, следует ли вызывать драйвер слияния низкого уровня для трех входных файлов. Это происходит, если (и только если):

  • на самом деле есть три файла (ни один из трех не отсутствует или не удален), и
  • Хэши BLOB-объектов для всех трех отличаются.

Низкоуровневый драйвер слияния - это тот, который вы настроили через .gitattributes файл. Если вы не настроили один через .gitattributes Это либо встроенный драйвер слияния текстовых файлов, либо встроенный драйвер слияния двоичных файлов.

Встроенный драйвер слияния текстовых файлов пытается объединить изменения, используя обычный метод diff-and-stick-merge-конфликта-markers-in. Если существует конфликт, который не может разрешить драйвер слияния текста низкого уровня, Git остановится и получит помощь.

Встроенный драйвер слияния двоичных файлов просто объявляет сбой. Git остановится и получит помощь.

Если вы предоставляете свой собственный драйвер слияния, вы несете ответственность за получение правильного результата слияния и / или указание Git прекратить работу и получить помощь. Так что если у вас есть драйвер слияния, который знает, как слить .png файлы, вы можете установить это как ваш драйвер слияния низкого уровня для *.png,

Насколько я знаю, если вы попытаетесь выполнить слияние, включающее два PNG или другие двоичные файлы, вы будете зависеть от алгоритма обнаружения конфликтов слияния в Git. Этот алгоритм помечает конфликты слияния изменениями в текстовых файлах, которые включают различия в определенной близости друг к другу (например, изменения в нескольких строках друг от друга).

Хотя для вас не является невозможным использование вашего двоичного инструмента слияния в Git, вам, возможно, придется сделать собственную сборку / разветвление Git, чтобы это произошло.

В целом, однако, вам следует избегать контроля версий двоичных файлов в Git, поскольку он плохо обрабатывает двоичный контент.

Другие вопросы по тегам