Git - как принудительно слить конфликт слияния и вручную слить на выбранный файл
Мы поддерживаем веб-приложение, имеющее общую основную ветвь и множество параллельных ветвей, по одной для каждой установки, каждая из которых имеет несколько конкретных изменений. Исходный код управляется в git, и это потрясающий инструмент, когда нам нужны функции переноса и исправления от ведущей ветки к параллельной. Но мало файлов, которые чувствительны и автоматическое слияние, обычно дают плохие результаты. Таким образом, слияние было бы намного проще, если бы их можно было каким-то образом маркировать, и каждое слияние привело бы к конфликту, требующему ручного слияния.
Я искал ответ:
- Я использую опции -no-commit и --no-ff merge, но это не то же самое.
- Здесь и здесь кто-то задает один и тот же вопрос, но без решения.
- Похоже, что подобный случай заключается в предотвращении объединения файлов с использованием.gitattributes, содержащих: somefile.php merge = ours. Я попытался найти некоторый параметр слияния, который мог бы вызвать конфликт или принудительное ручное слияние, но пока ничего не нашел.
- .gitattributes, содержащий: somefile.php -merge, никогда не сливается автоматически и, следовательно, принуждает ручное слияние. Это 90% -ное решение, но я пытаюсь попробовать автоматическое слияние и отмечать его как конфликт, независимо от того, успешно он или нет. Но это так близко к решению. (... спасибо Чарльзу Бейли за разъяснение...)
- Кто-то предлагает написать пользовательский драйвер слияния (1, 2), но как это сделать, мне далеко не ясно.
изменить: вариант 4. описание
Ответы
Ответ 1
Вариант 5, пользовательский драйвер слияния, вероятно, является способом приблизиться к тому, что вы хотите. Это удивительно легко сделать. Ниже приведен пример того, который, я думаю, должен сделать вас очень близким к поведению, которое вы желаете.
Сначала создайте драйвер слияния script под названием merge-and-verify-driver
. Сделайте его исполняемым и поместите в подходящее место (возможно, вы захотите проверить этот script на репо, даже, поскольку файл конфигурации репо будет зависеть от него). Git собирается выполнить эту оболочку script для выполнения слияния чувствительных файлов:
#!/bin/bash
git merge-file "${1}" "${2}" "${3}"
exit 1
Это просто поведение по умолчанию, которое обычно выполняет Git. Главное отличие состоит в том, что script всегда возвращает ненулевое значение (чтобы указать, что конфликт был, даже если слияние было разрешено без конфликтов).
Затем вам нужно сообщить Git о существовании вашего пользовательского драйвера слияния. Вы делаете это в конфигурационном файле repo (.git/config
):
[merge "verify"]
name = merge and verify driver
driver = ./merge-and-verify-driver %A %O %B
В этом примере я поместил merge-and-verify-driver
в каталог верхнего уровня репо (./
). Вам нужно будет указать путь к script соответственно.
Теперь вам просто нужно предоставить конфиденциальным файлам нужные атрибуты, чтобы при объединении этих файлов использовался пользовательский драйвер слияния. Добавьте это в свой .gitattributes
файл:
*.sensitive merge=verify
Здесь я сказал Git, что любой файл с именем, соответствующим шаблону *.sensitive
, должен использовать пользовательский драйвер слияния. Очевидно, вам нужно использовать шаблон, подходящий для вашего файла (ов).
Ответ 2
Примечание: в этой статье Написание драйвера слияния git для файлов PO" иллюстрирует виды манипуляций, которые вы можете выполнять при ручном слиянии файл: вы можете предварительно обработать его, чтобы ваше ручное слияние имело определенные данные.
git merge-file
можно использовать, например, для DECRYPT ( и повторно зашифровать) файлы перед слиянием (!)
В вашем случае выход из вашего слияния с условием non-0 гарантирует, что слияние будет ручной.
Ответ 3
Кажется, что эти две команды имеют тот же эффект, что и пользовательский драйвер слияния:
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)
Первая команда останавливает слияние перед созданием фиксации слияния, а вторая отмечает все файлы, измененные в двух ветвях, в качестве конфликта для решения, даже если первоначально не было конфликта.