GIT: Каким наилучшим образом решаются постоянно возникающие конфликты при слиянии веток develop и production?
Вопрос наверняка имеет очевидный ответ, на который мне просто не удается правильно составить поисковый запрос. Тем не менее, ситуация такова:
Есть две ветки, в одной из них ведется разработка продукта, в другой - хранится версия для выката на рабочий сервер. Очевидно, что эти две ветки имеют разные настройки окружения, возьмем как пример самое простое - в файле конфигурации в случае ветки для разработки указано окружение local, в файле для рабочего сервера - production.
Соответственно, при слиянии этих двух веток будет постоянно происходить замена значения этой переменной с production на local.
Так вот, вопрос: каким образом выстраивается рабочий процесс, дабы этого не происходило? Да и вообще, как верно производить слияние, если в двух ветках репозитория должны быть тем не менее всегда какие-то постоянно присутствующие различия?
Уточнение: различий, конечно же, намного больше, так что не интересует какой-то ручной процесс, желательно именно выстраивание рабочего процесса таким образом, чтобы о данной проблеме не болела лишний раз голова.
Решение, вроде, вполне очевидное - выносите все настройки в (конфигурационные) файлы, которые игнорируются git-ом. Делайте шаблоны этих файлов (оставляем в git), а в README проекта описываем процедуру их копирования в нужное место и "донастройки" (какие переменные нужно изменить, какие добавить/убрать и т.д.). На конкретной площадке (production, stage, test, dev, local etc) свои настройки, все логично
Еще как вариант - использование environment-переменных (переменных окружения), тогда файлы как таковые вообще не понадобятся. Но:
- их поведением часто сложно управлять, и, как следствие, сложно отлавливать ошибки при неверных значениях
- все равно их нужно где-то прописывать (bash-скрипты, .htaccess и т.д.), но теперь уже в разных местах
- все равно лучше задокументировать, хотя бы чтоб самому потом не забыть :)
Сергей: Совершенно верно. И есть некая переменная (из общего конфига), которая идентифицирует текущее окружение (dev, prod, local и т.д.). В зависимости от этой переменной вы подключаете разные конфиги (уже без суффикса EXAMPLE)
Сергей: Отличное решение, согласен. Но только лишь для файлов настроек, вообще же между проектами в принципе могут быть различия, о чем я в примечании написал, в том числе в коде. Как пример - постоянно присутствие различных dev-инструментов - тех же тестов. Как быть с ними?
Станислав: Это уже неправильная архитектура, которая жестко привязывается к конкретной среде ) Выделяйте такие блоки кода куда-то наружу, завязывайте их на конфиг-файлы.
Если проект ведет себя по-разному в различных environment-ах (что, в общем-то, нормально для более-менее серьезных проектов), то "смежный" код нужно выносить в отдельные модули, библиотеки и т.п.
sim3x: да, это понятно, но тем не менее каждый раз их накатывать обратно та еще морока. Выше предложили решение, делать файлы примеров настроен для разных сред различными файлами, типа .env.example-dev и .env.example-prod. Но что, если есть различия в коде и файлах, которые постоянные. Те же тесты, например, которые только в локальном хотелось бы оставить, и при этом хранить их в репозитории, конечно.
Станислав: если настроек много, то логично их хранить в отдельных файлах
Таких различий быть не должно
Даже теоретически
Тесты нужны везде. Економия на спичках никогда не доводила до добра
Станислав: Может, тогда есть смысл смотреть в сторону sub-repository? Отдельно репозиторий с кодом, отдельно - с тестами. На продакш идет только "ядро", на тестовых/локальных - дополнительно выкачиваются тесты
sim3x: ну почему, если сделать два репозитория, смотрящие на один и тот же каталог, но на разные его подкаталоги, и закрыть их друг от друга перекрывающими друг друга настройками игнорирования. Весьма элегантное решение.
Станислав: собственно
При первом же пулле основного репозитория, тесты сломаются. Тк никто не придумает, как синхронизировать тесты и основную репу, будет предложен вариант делать только приемочные тесты. А потом не делать их вообще, потому что они отстали уже на пару версий и вообще у половиы команды их нет
sim3x: вынужден согласиться, с оговоркой - такое действительно обязательно произойдет, описанный вариант не приведет к проблемам только при разработке в одни руки и тщательном контроле самого себя.
sim3x: возможно, мы с вами не поняли друг друга - никто не предлагает версионировать один и тот же код в двух местах. Тесты лежат отдельно и им отдельный репозиторий, сам проект - тоже отдельно. Представьте это, как два различных package.
Станислав:
те
написал тест
сделал тег
запушил на внешний сервис
прицепил тег в композер
обновил композер в основном проекте
начал писать код в основном проекте
?
sim3x: я не спорю, что это добавит головняков, но если задача стоит все-таки именно таким образом - да, вполне себе решение. Удлинить промежутки времени, между которыми пишутся тесты, и в целом ничего страшного, кроме того, что придется писать достаточно вдумчиво. Или вообще можно перейти на TDD, писать десяток тестов, и потом под них писать код :)
sim3x: да, на ночь глядя уже не соображал, но вообще я к тому TDD упомянул, что можно писать несколько тестов. Но в общем, конечно, да, способ не особо выходит. Надо подумать, в общем.