Git - как принудительно объединить конфликт и ручное слияние в выбранном файле
мы поддерживаем веб-приложение, которое имеет общую главную ветвь и множество параллельных ветвей, по одной для каждой установки, каждая из которых имеет несколько конкретных изменений. Исходный код управляется в git, и это потрясающий инструмент, когда нам нужно перенести функции и исправления из главной ветви в параллельные. Но мало файлов, которые чувствительны и автоматическое слияние обычно дает плохие результаты. Поэтому слияние было бы намного проще, если бы они могли быть каким-то образом отмечены, и каждое слияние привело бы к конфликту, требующему ручное слияние.
Я искал ответ:
- я использую --no-commit и --no-ff функции объединить, но это не то же самое.
- здесь и здесь кто-то задает тот же вопрос, но без решения.
- подобный случай, кажется как предотвратить слияние файлов использование .gitattributes по, содержащая: некий-файл.php merge=ours . Я пытался найти некоторые опции слияния, которые будут генерировать конфликт или принудительное ручное слияние, но пока не найдены.
- .gitattributes по, содержащая: некий-файл.php-merge никогда не объединяется автоматически и поэтому принудительное ручное слияние. Это 90% решение, но я хочу попробовать автоматическое слияние и отметить его как конфликт, независимо от того, успешен он или нет. но это пока ближе к решению. (...спасибо Чарльз Бейли осветление...)
- кто-то предлагает написать пользовательский драйвер слияния (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)
первая команда останавливает слияние перед созданием фиксации слияния, а вторая отмечает все файлы, измененные в двух ветвях, как конфликт для решения, даже если изначально конфликта не было.