В настоящее время у нас есть одна основная ветвь для нашего PHP-приложения в общем хранилище. У нас более 500 клиентов, которые являются подписчиками нашего программного обеспечения, большинство из которых имеют некоторые настройки для различных целей, каждый в отдельном филиале. К настройке может относиться другое имя текстового поля, совершенно новая функция или модуль или новые таблицы / столбцы в базе данных.
Сложность, с которой мы сталкиваемся, заключается в том, что, поскольку мы поддерживаем эти сотни настраиваемых веток и распространяем их среди клиентов, время от времени мы предоставляем новую функцию и обновляем нашу основную ветку, и мы хотим перенести изменения основной ветки в пользовательские ветви, чтобы обновить их до последней версии.
К сожалению, это часто приводит к многочисленным конфликтам в пользовательском коде, и мы тратим много часов, просматривая каждую ветку, чтобы разрешить все конфликты. Это очень неэффективно, и мы обнаружили, что ошибки нередки при разрешении этих конфликтов.
Я ищу более эффективный способ обновления веток выпуска наших клиентов с помощью основной ветки, что приведет к меньшим усилиям при слиянии.
источник
Ответы:
Вы полностью злоупотребляете ветками! У вас должна быть возможность настройки на основе гибкости в вашем приложении, а не гибкости в управлении версиями (которая, как вы обнаружили, не предназначена / не предназначена для такого рода использования).
Например, чтобы метки текстового поля исходили из текстового файла, а не были жестко закодированы в ваше приложение (так работает интернационализация). Если некоторые клиенты имеют разные функции, сделайте свое приложение модульным , со строгими внутренними границами, управляемыми строгими и стабильными API, чтобы можно было подключать функции по мере необходимости.
Основная инфраструктура и любые общие функции должны храниться, обслуживаться и тестироваться только один раз .
Вы должны были сделать это с самого начала. Если у вас уже есть пятьсот вариантов продукта (!), Исправить это будет огромной работой… но не более, чем текущим обслуживанием.
источник
Наличие 500 клиентов - это хорошая проблема. Если вы потратили время на то, чтобы избежать этой проблемы с филиалами, вы, возможно, никогда не смогли бы торговать достаточно долго, чтобы привлечь клиентов.
Во-первых, я надеюсь, что вы платите своим клиентам достаточно, чтобы покрыть ВСЕ расходы по обслуживанию их пользовательских версий. Я предполагаю, что клиенты ожидают получить новые версии без необходимости платить за свои настройки, которые будут сделаны снова. Я бы начал с поиска всех одинаковых файлов в 95% ваших веток. Эти 95% являются стабильной частью вашего приложения.
Затем найдите все файлы, которые отличаются только несколькими строками между ветвями - попробуйте ввести систему конфигурации, чтобы эти различия можно было устранить. Так, например, вместо того, чтобы иметь сотни файлов с разными текстовыми метками, у вас есть 1 файл конфигурации, который может переопределить любую текстовую метку. (Это не нужно делать за один раз, просто настройте метку текстового поля в первый раз, когда клиент захочет его изменить.)
Затем перейдите к более сложным вопросам, используя шаблон Стратегии, внедрение зависимостей и т. Д.
Рекомендуется хранить json в базе данных, а не добавлять столбцы для собственных полей клиента - это может работать для вас, если вам не нужно искать эти поля с помощью SQL.
Каждый раз, когда вы проверяете файл в ветке, вы ДОЛЖНЫ добавлять его в main и обосновывать каждое отдельное изменение, включая пробелы. Многие изменения не понадобятся и могут быть удалены до регистрации. Это может быть связано только с тем, что один разработчик имеет разные настройки в своем редакторе для того, как форматировать код.
Вы стремитесь сначала перейти от 500 веток с большим количеством разных файлов, к большинству веток только с несколькими разными файлами. Пока еще зарабатываю достаточно денег, чтобы жить.
У вас может быть еще 500 филиалов за много лет, но если ими намного легче управлять, то вы выиграли.
На основании комментария br3w5:
Делайте это только после того, как вы получили легкое зерно, и сначала проведите его с несколькими уроками.
источник
В будущем задайте тестовые вопросы Джоэля в своем интервью. Скорее всего, вы не войдете в крушение поезда.
Это, ну, как бы сказать ... действительно, очень плохая проблема. «Процентная ставка» по этому техническому долгу будет очень, очень высокой. Это не может быть восстановлено ...
Насколько интегрированы с «ядром» эти пользовательские изменения? Можете ли вы сделать их собственной библиотекой и иметь одно «ядро», и у каждого конкретного клиента будет свое «дополнение»?
Или это все очень незначительные конфигурации?
Я думаю, что решение представляет собой сочетание:
Ни один из них не будет тривиальным, как если бы вы оказались здесь с более чем 500 клиентами, и вы, вероятно, не сделали в этом особого различия. Я ожидаю, что ваши изменения в отделении будут очень трудоемкой задачей.
Я также подозреваю, что у вас возникнут серьезные проблемы с простым выделением и категоризацией всего кода, специфичного для клиента.
Если большинство ваших изменений являются конкретно формулировкой различия, я предлагаю читать такие вопросы , как это о языковой локализации. Независимо от того, используете ли вы несколько языков целиком или только подмножество, решение остается тем же. Это конкретно PHP и локализация.
источник
Это один из худших анти-паттернов, которые вы можете использовать с любым VCS.
Правильный подход здесь состоит в том, чтобы превратить пользовательский код во что-то, управляемое конфигурацией, и тогда каждый клиент может иметь свою собственную конфигурацию, либо жестко запрограммированную в файле конфигурации, либо в базе данных, либо в каком-либо другом месте. Вы можете включить или отключить все функции, настроить внешний вид ответов и т. Д.
Это позволяет вам сохранить одну основную ветку с вашим рабочим кодом.
источник
if(getFeature(FEATURE_X).isEnabled())
всему.Цель филиалов - исследовать один из возможных путей развития, не рискуя нарушить стабильность основной отрасли. Они должны быть в конечном итоге объединены обратно в подходящее время или отброшены, если они ведут в тупик. То, что у вас есть, - это не столько ветки, сколько 500 вилок одного и того же проекта, и попытка применить жизненные наборы изменений ко всем из них - задача сизифова.
Вместо этого вам следует сделать так, чтобы ваш основной код находился в своем собственном репозитории с необходимыми точками входа, чтобы изменить поведение через конфигурацию и ввести поведение, разрешенное инвертированными зависимостями .
Различные настройки, которые у вас есть для клиентов, могут либо просто различать друг друга по некоторому внешне настроенному состоянию (например, базе данных), либо, если необходимо, жить как отдельные репозитории, которые добавляют ядро как подмодуль.
источник
Все важные вещи были предложены хорошими ответами здесь. Я хотел бы добавить свои пять пенсов в качестве предложения процесса.
Я хотел бы предложить вам решить эту проблему в долгосрочной или среднесрочной перспективе и принять вашу политику, как вы разрабатываете код. Попробуйте стать гибкой командой обучения. Если кто-то разрешил иметь 500 репо вместо того, чтобы настраивать программное обеспечение, то пришло время спросить себя, как вы работали до сих пор, и вы будете делать это с этого момента.
Что значит:
Это никоим образом не должно создавать атмосферу плохого давления в вашей команде. Я предпочитаю, чтобы вы сначала прояснили эти моменты для себя и, где бы вы ни чувствовали поддержку, организуйте это вместе со своей командой. Пригласите дружелюбных людей за стол, чтобы улучшить ваш опыт.
Затем попытайтесь установить длительное временное окно, где вы готовите эту вещь на небольшом огне. Предложение: попытайтесь объединить как минимум два репозитория каждую неделю и удалите хотя бы одно . Вы можете узнать, что часто, вы можете объединить более двух ветвей, так как вы получаете рутину и контроль. Таким образом, за один год вы можете иметь дело с худшими (самыми дорогими?) Филиалами, а через два года вы можете уменьшить эту проблему, чтобы получить явно лучшее программное обеспечение. Но не ожидайте большего, потому что в конце концов никто не будет «иметь время» для этого, но вы тот, кто больше этого не допустит, поскольку вы являетесь архитектором программного обеспечения.
Вот как бы я попытался справиться с этим, если бы был на вашем месте. Однако я не знаю, как ваша команда примет такие вещи, как программное обеспечение действительно позволяет это, как вас поддерживают, а также то, что вам еще предстоит изучить. Вы архитектор программного обеспечения - просто пойти на это :-)
источник
В отличие от всех скептиков, давайте предположим, что это действительно необходимо для бизнеса.
(например, результат - это исходный код, клиенты принадлежат к одному и тому же бизнесу и поэтому являются конкурентами друг другу, а ваша бизнес-модель обещает сохранить свои секреты в секрете)
Кроме того, давайте предположим, что в вашей компании есть инструменты для поддержки всех филиалов, то есть либо рабочая сила (скажем, 100 разработчиков, занятых слиянием, предполагающих 5-дневную задержку выпуска, или 10 разработчиков, предполагающих 50-дневную задержку выпуска в порядке), или такое удивительное автоматическое тестирование, что автоматические слияния действительно проверяются как на базовую спецификацию, так и на спецификацию расширения в каждой ветви, и, таким образом, только изменения, которые не объединяются «чисто», требуют вмешательства человека. Если ваши клиенты платят не только за настройки, но и за их обслуживание, это может быть действительной бизнес-моделью.
Мой (и непослушный) вопрос: есть ли у вас специальный человек, ответственный за доставку каждому клиенту? Если вы, скажем, компания с 10000 человек, это может быть так.
В некоторых случаях это может быть обработано архитектурой плагинов , скажем, ваше ядро является транком, плагины могут храниться в транке или ветвях, а конфигурация для каждого клиента представляет собой файл с уникальным именем или хранится в ветке клиента.
Плагины могут быть загружены во время выполнения или встроены во время компиляции.
Поистине, многие проекты выполняются таким образом, в принципе все та же проблема: простые базовые изменения тривиальны для интеграции, конфликтные изменения необходимо либо откатить, либо изменения необходимы для многих плагинов.
Бывают случаи, когда плагины не достаточно хороши, поэтому нужно настроить так много внутренних компонентов ядра, что количество интерфейсов плагинов становится слишком большим для обработки.
В идеале это должно быть обработано аспектно-ориентированным программированием , где транк - это основной код, а ветки - это аспекты (то есть дополнительный код и инструкции, как подключить дополнительные компоненты к ядру).
В простом примере вы можете указать, что custom
foo
запускается до или после ядра,klass.foo
или что он заменяет его, или который оборачивает его и может изменять ввод или вывод.Для этого есть множество библиотек, однако проблема конфликтов слияний не исчезает - AOP занимается чистыми слияниями, а конфликты все еще требуют вмешательства человека.
Наконец, такой бизнес действительно должен заниматься обслуживанием филиала , а именно, является ли специфическая для клиента функция X настолько распространенной, что дешевле перенести ее в ядро, даже если за нее платят не все клиенты?
источник
Вы не решаете первопричину болезни, глядя на симптом. Использование подхода «управления кодом» является симптомом, но не решит проблему для вас в долгосрочной перспективе. Основной причиной является отсутствие «хорошо управляемых» возможностей продукта, его функций, расширений и вариаций.
Ваш «пользовательский» код представляет собой не что иное, как расширения функций и возможностей продукта и изменения полей данных в других.
Насколько обширные пользовательские функции, насколько они разные, насколько схожи по контексту или нет, сыграют большую роль в «дезинфекции» кодовой базы вашего продукта.
Это не просто код и версия, это место, где управление продуктом, архитектура продукта и архитектура данных вступают в игру. Шутки в сторону.
Потому что, в конце концов, код - это не что иное, как предложение бизнес-функций и продуктов / услуг вашим клиентам. Это то, за что платит ваша компания.
Чтобы лучше справиться с этим, нужно исходить из точки зрения «возможностей», а не из кода.
Вы, ваша компания и продукт не можете быть всем для всех. Теперь, когда у вас есть приличная база доходов в 500 клиентов, пришло время продумать, кем вы собираетесь быть.
И если вы предлагаете несколько вещей, имеет смысл упорядочить возможности вашего продукта.
Насколько широкими и глубокими будут ваши продукты? В противном случае это приведет к проблемам «качества обслуживания» и «разбавления и фрагментации продукта» по мере продвижения по линии.
Будете ли вы быть CRM или ERP или обработки заказов / отправки или Microsoft Excel?
Ваши существующие расширения должны быть свернуты и согласованы так, как крупное программное обеспечение привлекает и объединяет продукты, приобретенные при запуске.
Вам понадобится специалист по управлению продуктами и архитектуре данных, который сопоставит следующее:
... создать дорожную карту ассимиляции и гармонизации всех этих незакрепленных потоков / веток продукта в общем контексте вашего основного приложения.
PS: связывайтесь со мной, я знаю человека, который может помочь вам это исправить :)
источник
Я могу относиться к этому. Я взял много проектов. Фактически, 90% наших разработок - это исправление таких вещей. Не все идеальны, поэтому я предлагаю вам правильно использовать контроль версий и, где вы находитесь, если это возможно, вы можете сделать следующее.
Я лично импортировал репозиторий из GitHub с 40 ветками в Bitbucket и создал 40 репозиториев. Это заняло всего четыре часа. Это были вариации темы WordPress, так что push и pull были быстрыми.
Есть много причин для того, чтобы «делать это неправильно с первого раза», и я думаю, что те, кто быстро их примут и перейдут к «сделать это правильно в этот раз», всегда будут успешными.
источник