Git - как принудительно объединить конфликт и ручное слияние в выбранном файле

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

Я искал ответ:

  1. я использую --no-commit и --no-ff функции объединить, но это не то же самое.
  2. здесь и здесь кто-то задает тот же вопрос, но без решения.
  3. подобный случай, кажется как предотвратить слияние файлов использование .gitattributes по, содержащая: некий-файл.php merge=ours . Я пытался найти некоторые опции слияния, которые будут генерировать конфликт или принудительное ручное слияние, но пока не найдены.
  4. .gitattributes по, содержащая: некий-файл.php-merge никогда не объединяется автоматически и поэтому принудительное ручное слияние. Это 90% решение, но я хочу попробовать автоматическое слияние и отметить его как конфликт, независимо от того, успешен он или нет. но это пока ближе к решению. (...спасибо Чарльз Бейли осветление...)
  5. кто-то предлагает написать пользовательский драйвер слияния (1, 2), но как это сделать, мне далеко не ясно.

edit: вариант 4. описание

3 ответов


Вариант 5, пользовательский драйвер слияния, вероятно, способ приблизиться к тому, что вы хотите. Это удивительно легко сделать. Ниже приведен пример одного, который, я думаю, должен приблизить вас к желаемому поведению.

сначала создайте скрипт драйвера слияния под названием merge-and-verify-driver. Сделайте его исполняемым и поместите его в подходящее место (вы можете рассмотреть возможность проверки этого скрипта в репо, даже, поскольку файл конфигурации РЕПО будет зависеть от него). Git собирается выполнить этот сценарий оболочки для выполнения слияния конфиденциальных файлов:

#!/bin/bash
git merge-file "" "" ""
exit 1

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

затем вам нужно рассказать Git о существовании вашего пользовательского драйвера слияния. Вы делаете это в конфигурационном файле repo (.git/config):

[merge "verify"]
        name = merge and verify driver
        driver = ./merge-and-verify-driver %A %O %B

в этом примере я поставил merge-and-verify-driver в каталоге верхнего уровня РЕПО (./). Вам нужно будет указать путь к скрипту соответствующим образом.

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

*.sensitive merge=verify

здесь я сказал Git, что любой файл с именем, соответствующим шаблону *.sensitive следует использовать пользовательское слияние водитель. Очевидно, что вам нужно использовать шаблон, соответствующий вашему файлу(файлам).


Примечание: эта статья "написание драйвера слияния git для PO-файлов" иллюстрирует тип манипуляции, которую вы можете сделать при ручном слиянии файла: вы можете предварительно обработать его, чтобы ваше ручное слияние было готово к определенным данным.

git merge-file может использоваться, например, для расшифровать (и повторно зашифровать) файлы перед объединением (!)

в вашем случае выход из драйвера слияния со статусом, отличным от 0, гарантирует, что слияние будет ручной номер один.


эти две команды, похоже, имеют тот же эффект, что и при использовании пользовательского драйвера слияния:

git merge --no-commit your_target_branch
git checkout --conflict merge .   (do not forget the . and run it in the top dir of the repository)

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