Лучшая стратегия ветвления при непрерывной интеграции?

Какую стратегию ветвления лучше всего использовать, если вы хотите осуществлять непрерывную интеграцию?

  1. Ветвление выпуска: разрабатывайте в основной ветке, сохраняйте ветку для каждого выпуска.
  2. Ветвление функций: разрабатывайте каждую функцию в отдельной ветке, сливайте только после стабильной работы.

Имеет ли смысл использовать обе эти стратегии вместе? Например, вы разветвляетесь для каждого выпуска, но вы также разветвляетесь для больших функций? Лучше ли сочетается одна из этих стратегий с непрерывной интеграцией? Будет ли иметь смысл использование непрерывной интеграции при использовании нестабильной магистрали?


person KingNestor    schedule 28.02.2009    source источник
comment
Боковое примечание: некоторые утверждают, что даже когда в него добавляются новые функции, все всегда должно быть стабильным. С другой стороны, это может быть несколько идеалистическим.   -  person Keith Pinson    schedule 30.05.2013


Ответы (12)


Я считаю эту тему действительно интересной, так как в своей повседневной работе я сильно полагаюсь на филиалы.

  • Я помню, как Марк Шаттлворт предложил модель сохранения основной ветки в первозданном виде, выходя за рамки обычного CI. Я опубликовал об этом здесь .
  • Поскольку я знаком с круиз-контролем, я также писал в блоге о ветвях задач и CI здесь. Это пошаговое руководство, объясняющее, как это сделать с помощью Plastic SCM.
  • Наконец, я нашел некоторые темы о CI (и, возможно, о ветвлении) в книге Дюваля о CI тоже очень интересно.

Надеюсь, вы найдете ссылки интересными.

person pablo    schedule 17.03.2009
comment
Мы добавили поддержку Bamboo для выполнения ветки для каждой задачи codicesoftware.blogspot.com/2012/02/, и кажется, что их последняя версия будет делать это изначально с несколькими элементами управления версиями, включая dvcs. - person pablo; 05.04.2012

Ответ зависит от размера вашей команды и качества системы управления версиями, а также от способности правильно объединять сложные наборы изменений. Например, при полном управлении исходным кодом ветви, таком как слияние CVS или SVN, может быть сложно, и вам может быть лучше с первой моделью, в то время как при использовании более сложной системы, такой как IBM ClearCase, и с большим размером команды вам может быть лучше со второй. модель или их комбинация.

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

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

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

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

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

person Jiri Klouda    schedule 03.03.2009
comment
Я не уверен, согласен ли я с тем, что то, что вы описываете, не имеет смысла для команд до 50 разработчиков. Я также вижу выгоду для гораздо меньших команд. +1 - person Aardvark; 24.04.2009
comment
Конечно, есть преимущества для команд любого размера. Вопрос в том, при каком размере команды преимущества перевешивают затраты, связанные с тяжелым процессом. - person Jiri Klouda; 10.03.2012
comment
Это похоже на модель GitFlow и / или GitHubFlow. Я не думаю, что эти модели способствуют непрерывной интеграции (CI). На мой взгляд, разработка на основе магистрали является значительным улучшением этих моделей. - person Yani; 22.03.2019
comment
Вы можете видеть, что этот комментарий на самом деле предшествует первоначальному выпуску git flow. Не совсем понимаю, что вы имеете в виду под словом «лучше». Я поддерживал команды из 1, 5, 25, 150, 1000 и 20 000 разработчиков, работающих над проектами, которые были в той или иной степени интегрированы. Требования меняются, и лучше - это очень относительный термин. Вам когда-нибудь нужно было делать бэкпорт кода? Исправления безопасности? Если нет, то ваша жизнь проста. SaaS является прямым результатом ограничений, налагаемых разработкой на основе магистрали. Флаги функций так же сложны, как и ветви функций. За исключением того, что вы узнаете об этом только от клиентов, когда их перестановка сломается. - person Jiri Klouda; 23.03.2019

Лично я считаю, что иметь стабильный ствол и разветвляться по функциям намного удобнее. Таким образом, тестировщики и им подобные остаются на одной «версии» и обновляются из магистрали, чтобы протестировать любую функцию, которая является завершенным кодом.

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

В качестве дополнительного бонуса есть некоторый уровень интеграционного тестирования, который выполняется автоматически.

person Adnan    schedule 28.02.2009
comment
Кроме того, вы все еще разветвляете и помечаете каждый основной выпуск? Или просто отметьте? - person KingNestor; 28.02.2009
comment
Он хорошо работает с CI до тех пор, пока функциональные ветки объединяются в ствол с некоторой дисциплиной, чтобы не иметь сломанных сборок. Я делаю ветвление и теги для каждого производственного выпуска, который будет использоваться только для исправления ошибок. Это может быть немедленно объединено в стабильный ствол. - person Adnan; 28.02.2009
comment
@king Я бы сказал, что это, вероятно, зависит от того, что вы называете основным выпуском, но в любом случае вы можете пометить и ветвиться позже, когда вам это нужно (на основе тега :)) - person eglasius; 28.02.2009

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

http://martinfowler.com/articles/continuousIntegration.html#EveryoneCommitToTheMainlineEveryDay

РЕДАКТИРОВАТЬ

Я немного читал эту книгу на CI и авторы предполагают, что ветвление по выпуску является их предпочтительной стратегией ветвления. Я должен согласиться. При использовании CI ветвление по функциям не имеет для меня смысла.

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

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

ДРУГОЙ РЕДАКТИРОВАНИЕ

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

http://jamesmckay.net/2011/07/why-does-martin-fowler-not-understand-feature-branches/

person Phil Hale    schedule 27.06.2011
comment
интересно, больше не могу найти этот пост. - person Jirong Hu; 30.11.2016

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

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

Так что для меня использование обоих механизмов - очень хорошая стратегия.

Интересная ссылка из Книги SVN.

person SirFabel    schedule 21.03.2010

Недавно мне понравилась эта модель при использовании git. Хотя ваш вопрос помечен как «svn», вы все равно можете его использовать.

Непрерывная интеграция может до некоторой степени происходить в ветке «разработка» (или как вы ее называете) в этой модели, хотя наличие длительных функциональных веток для будущих выпусков не сделает ее настолько жесткой, чтобы учитывать каждое изменение, происходящее где-то в коде. Остается вопрос, действительно ли вы этого хотите. Мартин Фаулер знает.

person hermannloose    schedule 21.03.2010

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

Было сказано, что ...

  • нет причин, по которым CI нельзя использовать в обоих описанных вами подходах
  • эти подходы хорошо работают в сочетании
  • ни один из двух не работает «лучше», чем другой
  • CI имеет смысл при нестабильном стволе

На все это был дан ответ в четвертом вопросе на странице, с которой вы взяли диаграммы: http://blogs.collab.net/subversion/2007/11/branching-strat/

person Zac Thompson    schedule 21.03.2010

Если вы понимаете принципы, вы всегда можете заново изобрести лучшие практики. Если вы не понимаете принципов, лучшие практики уведут вас так далеко, прежде чем развалится из-за противоречивых внешних требований.

Чтобы лучше познакомиться с основной моделью, прочтите это: https://web.archive.org/web/20120304070315/http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf

Прочтите ссылку. Когда вы освоите основы, прочтите следующую статью достопочтенного Хенрика Книберга. Это поможет вам связать основную модель с непрерывной интеграцией.

http://www.infoq.com/articles/agile-version-control

person zvolkov    schedule 15.04.2009
comment
Глава О'Рейли больше недоступна - person Jason S; 02.10.2015

Когда мы создавали нашу команду, мы унаследовали стратегию на основе релизов от поставщика, который изначально разработал систему, за которую мы собирались отвечать. Это работало до тех пор, пока наши клиенты не потребовали, чтобы некоторые разработанные функции не были включены в релиз (например, ~ 250 тыс. Строк кода, ~ 2500 файлов, Scrum с XP SDLC).

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

Последний «гвоздь в крышку гроба» чистых SC-стратегий пришел, когда мы решили, что у нас должен быть 1. стабильный ствол и 2. рабочий должен содержать ST, UAT и регрессивно протестированные БИНАРИИ (а не только исходный код - подумайте CC).

Это привело нас к разработке стратегии, которая представляет собой гибрид между стратегиями SC на основе функций и релизов.

Итак, у нас есть багажник. В каждом спринте мы разветвляем ветвь спринта (для не-гибких людей спринт - это просто ограниченная по времени разработка с переменным выходом в зависимости от сложности). Из ветки спринта мы создаем ветви функций, и в них начинается параллельная разработка. После того, как функции завершены, система протестирована и мы получаем намерение развернуть их, они объединяются в ветвь спринта - некоторые из них могут перемещаться по нескольким спринтам, обычно более сложные. Когда спринт подходит к концу и все функции завершены ... мы «переименовываем» ветвь спринта в «регрессию» (это позволяет CruiseControl выбрать ее без какой-либо реконфигурации), а затем начинается регрессионное / интеграционное тестирование на cc-built. УХО. Когда все это будет сделано, оно будет запущено в производство.

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

Теперь вопрос к сообществу - у нас, очевидно, возникают проблемы с непрерывной интеграцией из-за того, что разработка происходит во многих ветвях, и из-за накладных расходов на реконфигурацию CruiseControl. Может кто подскажет и посоветует?

person XAvatar    schedule 22.06.2011
comment
Я не обязательно согласен с выводами, но спасибо за обсуждение вашего процесса. Не существует универсального решения. - person RaoulRubin; 19.02.2014

Дэйв Фарли, автор Непрерывная доставка, ссылка на на основе магистрали Разработка (TBD) как краеугольный камень непрерывной интеграции (CI) и непрерывной доставки (CD). Он говорит:

Любая форма ветвления противоположна непрерывной интеграции.

Он также говорит:

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

Trunk Based Development (TBD) - это практика интеграции изменений кода в магистраль (также известную как master, mainline) по крайней мере один раз в день, желательно несколько раз в день. Непрерывная интеграция (CI) - аналогичная практика, за исключением того, что она также включает проверку изменений кода с помощью автоматических тестов. Лучшая стратегия ветвления для этого - работать непосредственно из магистрали и выполнять обзоры кода с помощью парного программирования. Если по какой-то причине вы не можете создать пару или просто хотите разветвиться, убедитесь, что ваши ветки недолговечны (менее суток).

Я работаю над Trunk, «мастером» в репозиториях GIT. Я обязуюсь выполнять локальное управление и сразу же, когда я подключен к сети, отправляю в центральное главное репозиторий, где работает CI. Вот и все!

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

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

person Yani    schedule 22.03.2019
comment
Дэйв Фарли и Джез Хамбл просто ошибаются в своей позиции относительно ветвления. Причина этого в том, что он кодирует важное предположение, что вам никогда не придется манипулировать кодом на уровне функций, и если, тогда это нормально, если это будет дорогостоящая операция, и они основывают свою оценку на другом предположении, слияние слишком дорого, а автоматическое слияние почти невозможно в масштабе. Если эти два предположения не верны, если вы живете в мире, где слияние обходится дешево, но вам нужно манипулировать кодом на уровне функций для обратных портов и исправлений безопасности, тогда их утверждения не работают. Хотя это редкий случай. - person Jiri Klouda; 25.03.2019
comment
Некоторым компаниям также необходимо перенести функции в будущие выпуски после того, как эти функции столкнутся с препятствиями при реализации и задерживают выпуск. Иногда есть возможность оставить код, как в продуктах SaaS, но если код предоставляется клиентам, это может быть не вариант, поскольку его могут проанализировать конкуренты. В наши дни так много кода не компилируется, и даже если это так, флаги определений / функций в коде находятся на том же уровне сложности, что и ветки. - person Jiri Klouda; 25.03.2019

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

Когда и что делать ветвью, обычно зависит от размера команды и размера разрабатываемых функций. Я не думаю, что есть золотое правило. Убедитесь, что вы используете стратегию, при которой вы можете получать обратную связь раньше / часто, и это включает в себя обеспечение качества с самого начала функций. Бит качества означает, что по мере того, как вы автоматизируете по мере развития команды, если вы переходите к большому набору функций, который создает команда, вы также должны иметь качественное участие в команде.

ps Где вы взяли эти ссылки на подходы? - не кажется, что эти графики представляют все варианты

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

person eglasius    schedule 28.02.2009
comment
Есть еще несколько. Но мне кажется, что ветвление функций и ветвление выпуска - два наиболее распространенных. - person KingNestor; 28.02.2009

Я думаю, что инструменты, которые вы используете, играют здесь большую роль.

  • Если вы используете Subversion, придерживайтесь варианта 1 и выпустите из веток.
  • Если вы используете GIT, вам подойдет вариант 2.
person Tony Zampogna    schedule 01.04.2014
comment
Разветвление функций может быть легко достигнуто с помощью любого SCM. - person hdost; 02.12.2015