Вам следует сделать и то, и другое .
Начните с принятого ответа от @Norman: используйте один репозиторий с одной именованной веткой для каждого выпуска.
Затем создайте по одному клону на каждую ветку выпуска для сборки и тестирования.
Одно ключевое замечание заключается в том, что даже если вы используете несколько репозиториев, вам следует избегать использования transplant
для перемещения наборов изменений между ними, потому что 1) он изменяет хэш и 2) он может вносить ошибки, которые очень трудно обнаружить, когда есть конфликтующие изменения между набором изменений, который вы трансплантат и целевая ветка. Вместо этого вы хотите выполнить обычное слияние (и без предварительного слияния: всегда визуально проверять слияние), что приведет к тому, что @mg сказал в конце своего ответа:
График может выглядеть по-другому, но он имеет ту же структуру и конечный результат такой же.
Более подробно, если вы используете несколько репозиториев, «основной» репозиторий (или по умолчанию, основной, для разработки, что угодно) содержит ВСЕ ревизии во ВСЕХ репозиториях. Каждый репозиторий релиза / ветки - это просто одна ветка в стволе, все они так или иначе объединены обратно в ствол, пока вы не захотите оставить старый выпуск. Следовательно, единственное реальное различие между этим основным репо и единым репо в схеме именованных ветвей состоит в том, имеют ли ветки имена или нет.
Это должно прояснить, почему я сказал: «Начните с одного репо». Это единственное репо - единственное место, где вам когда-либо понадобится искать какие-либо изменения в любом выпуске . Вы можете дополнительно пометить наборы изменений в ветках выпуска для управления версиями. Он концептуально ясен и прост и упрощает системное администрирование, поскольку это единственное, что обязательно должно быть доступно и постоянно исправимо.
Но тогда вам все равно нужно поддерживать один клон на каждую ветку / выпуск, который вам нужно собрать и протестировать. Это тривиально, насколько вы можете hg clone <main repo>#<branch> <branch repo>
, и тогда hg pull
в репозитории ветки будут извлекаться только новые наборы изменений в этой ветке (плюс наборы изменений предков в более ранних ветках, которые были объединены).
Эта настройка лучше всего подходит для модели фиксации ядра Linux с одним съемником (разве не приятно действовать как лорд Линус. В нашей компании мы называем ролевым интегратором ), поскольку основное репо - это единственное, что разработчикам нужно клонировать, а съемник необходимо втянуть. Обслуживание репозиториев филиалов предназначено исключительно для управления выпусками и может быть полностью автоматизировано. Разработчикам никогда не нужно извлекать / отправлять репозитории в ветку.
Вот пример @mg, переработанный для этой настройки. Отправная точка:
[a] - [b]
Создайте именованную ветку для версии выпуска, скажите «1.0», когда вы перейдете к альфа-версии. Зафиксируйте исправления ошибок на нем:
[a] - [b] ------------------ [m1]
\ /
(1.0) - [x] - [y]
(1.0)
не является реальным набором изменений, поскольку названная ветка не существует, пока вы не зафиксируете. (Вы можете сделать тривиальную фиксацию, например, добавить тег, чтобы убедиться, что именованные ветки созданы правильно.)
Слияние [m1]
- ключ к этой настройке. В отличие от репозитория разработчиков, где может быть неограниченное количество голов, вы НЕ хотите иметь несколько голов в основном репозитории (за исключением старой, мертвой ветки выпуска, как упоминалось ранее). Поэтому всякий раз, когда у вас есть новые ревизии в ветвях выпуска, вы должны немедленно объединить их обратно в ветку по умолчанию (или в более позднюю ветку выпуска). Это гарантирует, что любое исправление ошибки в одном выпуске также будет включено во все последующие выпуски.
Тем временем разработка ветки по умолчанию продолжается до следующего выпуска:
------- [c] - [d]
/
[a] - [b] ------------------ [m1]
\ /
(1.0) - [x] - [y]
И, как обычно, вам нужно объединить две головы в ветке по умолчанию:
------- [c] - [d] -------
/ \
[a] - [b] ------------------ [m1] - [m2]
\ /
(1.0) - [x] - [y]
А это клон ветки 1.0:
[a] - [b] - (1.0) - [x] - [y]
Теперь это упражнение по добавлению следующей ветки выпуска. Если это 2.0, то он определенно разветвится по умолчанию. Если это 1.1, вы можете выбрать ответвление 1.0 или по умолчанию. Тем не менее, любой новый набор изменений в 1.0 должен быть сначала объединен со следующей ветвью, а затем по умолчанию. Это можно сделать автоматически, если нет конфликта, в результате чего будет просто слияние.
Я надеюсь, что этот пример проясняет мои предыдущие утверждения. Таким образом, преимущества этого подхода:
- Единый авторитетный репозиторий, содержащий полный набор изменений и историю версий.
- Понятное и упрощенное управление выпусками.
- Понятный и упрощенный рабочий процесс для разработчиков и интегратора.
- Упростите итерацию рабочего процесса (обзоры кода) и автоматизацию (автоматическое слияние пустых данных).
UPDATE hg сам делает это : основное репо содержит ветвь по умолчанию и стабильную ветку , а стабильное репо - это клон стабильной ветки. Однако он не использует версионную ветвь, поскольку теги версий в стабильной ветке достаточно хороши для целей управления выпусками.