Подтвердить что ты не робот

Как управлять открытой и коммерческой версиями одного и того же проекта с использованием источника управления?

Мы разрабатываем проект с открытым исходным кодом, и мы используем Mercurial для управления исходным кодом. Репозиторий Mercurial для этого проекта является общедоступным (мы используем Bitbucket).

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

Но проблема в том, что нам нужно [время от времени] изменять слияние (например, новые функции или исправления ошибок) из открытого репозитория в наш частный репозиторий.

Какой лучший способ достичь этого? Я читал, что можно объединить два или более хранилища Mercurial, но история будет потеряна. Также слияние может быть болезненным из-за многих конфликтов. Что делать, если в будущем мы получим еще несколько клиентов, как мы должны управлять своими репозиториями? Должны ли мы использовать один репозиторий и несколько веток? Что делать, если две версии проекта начинаются в разных направлениях, а два хранилища становятся все более разными?

Поделитесь своим опытом об этом.

Спасибо заранее!

4b9b3361

Ответ 1

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

hg clone open private

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

Когда исправления и новые функции помещаются в репозиторий open как часть обычного процесса с открытым исходным кодом, вы переносите их в репозиторий private:

cd private
hg pull
hg merge

Таким образом, вы сохраняете инвариант: репозиторий private всегда содержит все в открытой версии плюс частные улучшения. Если вы работаете над частной версией и обнаруживаете ошибку, не забудьте взглянуть на открытую версию, чтобы узнать, существует ли там ошибка. Если это так, тогда сначала исправьте его в открытой версии и объедините исправление в приватную версию. Если вы исправите ошибку в приватной версии по ошибке, используйте hg transplant, чтобы скопировать исправление в другую открытую версию.

Там не будет никакой потери истории. Вам придется разрешить слияние, как обычно, когда вы делаете hg merge, и конфликты будут только такими, насколько это требуется вашими частными изменениями.

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

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

Ответ 2

В принципе базовая модель относительно проста; иметь отдельный приватный репозиторий, который является клоном (ветвью) публичного, делать все частные изменения там, а затем регулярно объединять публичный в частный. Нет проблем в сохранении истории, я не знаю, почему вы читаете, что произойдет.

Однако задача состоит в том, чтобы не оказаться в неимоверном слиянии ад, и это может быть достигнуто только через строгую дисциплину.

Самые основные правила для любых долгоживущих ветвей:

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

  • Слияние часто. Чем чаще, тем лучше. Если вы этого не сделаете, когда вы захотите интегрировать изменения из общего репозитория, вы получите одно супер-слияние, у которого будет тонна конфликтов.

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

В идеале вы бы моделировали настраиваемые функции как плагин или внешнюю библиотеку, даже отдельный проект. Это может не всегда быть легко достижимым, в этом случае, по крайней мере, попытайтесь написать все частные модификации с точки зрения подклассов оригинала, которые вы создаете с помощью методов factory. Сделав все ваши изменения в независимых файлах, которые существуют только на частной ветке, вы минимизируете риск конфликтов.

Также напишите автоматизированные тесты. Многие из них. Кроме того, вы не будете быстро обнаруживать проблемы слияния (что произойдет), и частная ветвь часто будет нарушена.

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

Ответ 3

Как обычно, проект состоит из набора модулей. По моему опыту иногда даже лучше иметь некоторые модули в отдельных хранилищах-источниках-репозиториях. Например, некоторый модуль-модуль или основной модуль, такой как web-framework или модуль DAO (ORM). В этом случае вы можете использовать ветки в исходных элементах управления, поскольку они должны использоваться для поддержки разработки и поддержки каждой версии выпущенной версии в одном хранилище исходных элементов управления, чтобы иметь возможность объединять ветки.

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

На самом деле это очень интересная задача - я потратил на нее много времени в прошлом году. Мое решение состоит в том, чтобы один core-repositoy (open-source) с полностью функционирующей задачей maven выпустил его. И отдельное репо для каждого клиента, которое поддерживает только настройку дизайна и некоторую бизнес-логику, ориентированную на клиента (просто используйте псевдонимы в клиентском spring XML для переопределения ваших "основных" сервисов spring - см. BeanDefinitionOverriding), а задача maven для моего клиента основана на использовании основных артефактов (часто распространяет некоторые из них - см., например, "наложения" в maven-war-plugin, что позволяет продлить существующую WAR). В таком случае у вас никогда не будет клона того же класса в другой ветке - вы будете использовать его или расширять его точно так же, как вы используете классы log4j в своем приложении. Вы должны просто расширить выпуск с открытым исходным кодом.

Еще одна интересная задача - управлять конфигурационными файлами. Я рекомендую вам увидеть Maven Remote Resources Plugin вместо стандартного Плагин Maven Resources. Он позволяет вам иметь шаблон конфигурационных файлов и переместить все значения в профили maven, которые должны быть конкретными для каждого клиента. И посмотрите на Maven Tiles Plugin - это помогает мне значительно упростить "pom.xml" в проекте клиента (я могу повторно использовать "плитки" maven сборка и сборка)

Ответ 4

Ну, некоторые расширения и варианты.

  • Для рабочего процесса Martin вы можете использовать парадигму "Branch Per Task" (ветки должны быть созданы в базовом проекте, "Open" ) и "push -b -new-branch" (публиковать только ветку, а не весь набор изменения также в mainline) до "Private", в котором ветвь также должна быть объединена по умолчанию.

Увеличенное количество вилок в этом случае стоит "+2 команды +1 репозиторий" на fork

  • Вариация ветвления: реестр разработчиков с одним разработчиком, много названных ветвей (Branch per Target + Branch per Task). Небольшое отклонение v.1 - только одно репо-процесс разработки, в котором Open & Private называются ветвями (среди других ветвей short-termb). Задача также (как и в п. 1) реализована в отдельной ветке, которая (без толчка) сливается с нужными целями (Open и Private). Пользовательские открытые и закрытые репозитории должны обновляться также с помощью кнопки -b

Увеличенное количество вилок в этом случае стоит "+1 команда +1 ветвь" для каждой вилки

  • Патч-модель. Единый общий код, все изменения выполняются поверх наборов кодовых таблиц "Ванильный Open". С включенным MQ только с применением патчей в конверте очереди Open to Private. Если случай "существует в Open, не должен существовать в Private", мы перейдем к ситуации трехуровневого управления версиями Core-Open-Private. Для такой ситуации необходимо использовать разные патч-наборы поверх Core. "Различные патч-наборы" могут быть: а) разным названием ветвей для разных целей и ручного применения и контроля; б) использования охранников; в) для довольно свежего Mercurial возможно, что отдельные очереди и для каждой уникальной цели также имеют уникальную очередь. Задачи могут быть разработаны в ветвях, как и раньше, или в MQ-patch (позже qfinish) или

Увеличение количества вилок в этом случае стоит "+1 патч" для каждой вилки и, возможно, "+1 очередь" (см. выше). Я предпочитаю одиночную очередь с защитой для простоты и управляемости.