Продолжаете ли вы разработку в ветке или в стволе? [закрыто]


170

Предположим, вы разрабатываете программный продукт, который периодически выпускается. Каковы лучшие практики в отношении ветвления и слияния? Отрезание веток периодического выпуска для широкой публики (или от того, кем является ваш клиент), а затем продолжение разработки в стволе, или рассмотрение ствола в качестве стабильной версии, периодически помечая ее как выпуск и выполнение экспериментальной работы в ветвях. Что думают люди, считается ли сундук «золотым» или «песочницей»?


3
Хотите знать, может ли это быть переназначено без svn, поскольку это довольно универсально для управления исходным кодом?
Скотт Саад

4
Кажется, это один из тех "религиозных" вопросов.
Джеймс МакМахон

@ Джеймс МакМэхон - более того, есть действительно две взаимоисключающие лучшие практики, но некоторые люди думают, что есть только одна. Это не помогает, что ТАК хочет, чтобы у вас был один правильный ответ.
Кен Лю

Ответы:


151

Я пробовал оба метода с большим коммерческим применением.

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

Лучший метод в целом (по моему опыту): багажник должен быть всегда устойчивым.

Вот некоторые рекомендации и преимущества этого метода:

  • Кодируйте каждую задачу (или связанный набор задач) в отдельной ветке, тогда у вас будет гибкость, когда вы захотите объединить эти задачи и выполнить выпуск.
  • QA должен быть сделан на каждой ветви, прежде чем она будет объединена с транком.
  • Проведя QA в каждой отдельной ветке, вы будете точно знать, что стало причиной ошибки.
  • Это решение подходит для любого количества разработчиков.
  • Этот метод работает, так как ветвление является почти мгновенной операцией в SVN.
  • Отметьте каждый релиз, который вы выполняете.
  • Вы можете разрабатывать функции, которые вы не планируете выпускать какое-то время, и решать, когда именно их объединять.
  • За всю работу, которую вы делаете, вы можете получить выгоду от фиксации своего кода. Если вы работаете только из транка, вы, вероятно, будете часто сохранять свой код незафиксированным, а значит, незащищенным и без автоматической истории.

Если вы попытаетесь сделать обратное и выполнить всю разработку в стволе, у вас возникнут следующие проблемы:

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

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

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


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


35
Извините, но этот ответ неверен. Все развитие должно происходить в багажнике. Если у вас есть что-то, что «пикирует» или какая-то «рискованная» функция, создайте ветвь функции. Ветви должны поддерживаться для каждой версии продукта в производстве, или, если есть отдельная версия, используйте ветку интеграции.
Mitch Wheat

52
Я не утверждал, что это был единственный путь, просто это лучший способ. Конечно, если вы считаете, что у вас достаточно причин, по которым вы думаете, что я не прав, вы должны опубликовать это. По крайней мере, мой ответ оправдан.
Брайан Р. Бонди

5
Это проблематично, так как разработчики могут долго работать над веткой, которая расходится с основным стволом. Интеграция этих вещей позже может привести к большим головным болям. Для меня всегда было проще поддерживать передовой ствол с некоторыми минимальными требованиями (всегда должны компилироваться) и ветвить материал, который должен быть стабилизирован для выпуска.
Мнемент

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

8
@Mnementh, это не оправдание. Лучшие практики и здравый смысл говорят, что все в команде должны обновить свои ветви с помощью trunk. Основная магистраль не предназначена для того, чтобы быть совершенной, и при этом она не должна быть тем, что вы подталкиваете к производству, она просто нуждается в компиляции, и поэтому в хороших средах разработки большинство разработчиков очень хорошо уверены, что это происходит, а если нет, то Команда имеет право дать этому человеку трудные времена ... также такие инструменты, как Круиз-контроль и другие непрерывные настройки сборки. Вот что такое непрерывная интеграция! У вас есть QA-тестирование ваших ветвей, а не магистральной линии
PositiveGuy

66

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

Те люди выше, кто возражает, говоря, что у вас

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

вероятно, не использовали методы непрерывной интеграции.

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

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

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

Прочитайте статью Мартина Фаулера о непрерывной интеграции . Мы развернули нашу собственную такую ​​систему для крупного проекта (3000kSLOC) примерно в 2000 линиях Posix sh.


1
Какое отношение имеет «непрерывная интеграция» к вероятности того, что одна команда опоздала со своей функцией и задержала весь цикл выпуска? Это лучший способ пойти «для тебя»! Выполнение нескольких сборок в день не решает никаких потенциальных проблем, кроме тех, которые вы знаете, это сборка! Ваши аргументы не являются доказательством того, что это лучший способ (хотя я обычно так и делаю).
Jeach

CI необходим для этого ответа, но также и для Брайана.
jyoungdev

2
@Jeach, выполнение нескольких сборок в день дает вам уверенность в том, что они собираются, чтобы вы могли регулярно запускать тесты, будь то простые тесты smkoke в течение дня или регрессионные тесты вечером. Если вы оставите сборку до регрессионного тестирования до вечерней сборки, вы можете отложить весь проект на день только потому, что не можете собрать. Это означает, что все разработчики не смогут увидеть результаты регрессионных тестов для нового кода, который они представили. Довольно дорого, потому что, например, кто-то зарегистрировал код, содержащий синтаксическую ошибку.
Роб Уэллс

Что, если на создание одной функции уходит 2 месяца, а на создание другой - 6 месяцев, вам нужно использовать там ответвления, в таких случаях не все можно проверить на транк
Kalpesh Soni

1
@ Волк, ты путаешь путаницу с путаницей, люди создают продукты, не все работают на девопов
Kalpesh Soni

36

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

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


19

Обе.

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

Релизы хранятся в своем собственном каталоге, в них вносятся только исправления ошибок (а затем объединяются в транк).

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


3
Я с вами на этом ... разработчики, которые все время придерживаются только одного метода, являются проблемой!
Jeach

14

Мне нравится и использую подход, описанный Хенриком Книбергом в Управлении версиями для нескольких гибких команд . Хенрик проделал большую работу, объяснив, как управлять управлением версиями в гибкой среде с несколькими командами (работает и для одной команды в традиционных средах), и нет смысла перефразировать его, поэтому я просто выложу «шпаргалку» (которая самоочевидно) ниже:

альтернативный текст альтернативный текст

Я люблю его, потому что:

  • Это просто: вы можете получить это с картинки.
  • Он работает (и масштабируется) без особых проблем слияния и конфликта.
  • Вы можете выпустить «работающее программное обеспечение» в любое время (в духе Agile).

И на случай, если это не было достаточно явным: разработка выполняется в «рабочей ветви (ветках)», транк используется для кода DONE (освобождаемого). Проверьте Управление версиями для нескольких Agile команд для всех деталей.


Мой личный опыт показывает, что это работает ТОЛЬКО для небольших команд, в отличие от вашего комментария. По мере роста команд и перебазирования историй все остальные команды тратят значительное количество команд на слияния. И в очень больших проектах (много файлов и KLOC) регулярно появляются проблемы слияния, особенно когда существует большая нестабильность кода.
Jeach

@Jeach Это хорошо сработало для нас в большом проекте с 5 командами, организованными в художественные команды, хотя я не отрицаю, что слияние имеет цену.
Паскаль Thivent

11

Хорошей ссылкой на процесс разработки, который поддерживает стабильную работу магистрали и выполняет всю работу в филиалах, является Ultimate Ultimate Quality Development System . Краткое резюме:

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

Для этого они используют SVN, но это легко сделать с любой из распределенных систем контроля версий.


10

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

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

Предполагается, что ответвления будут настоящими песочницами, хотя ствол также должен будет играть эту роль: теги будут указывать, является ли код «золотым» в тот момент времени, пригодным для выпуска.


8

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


5

Это зависит от ваших ситуаций. Мы используем Perforce и, как правило, имеем несколько направлений развития. Магистраль считается «золотой», и вся разработка происходит в ветвях, которые объединяются с основной линией, когда они достаточно стабильны для интеграции. Это позволяет отклонить функции, которые не делают разрез, и может предоставить солидную инкрементную возможность с течением времени, которую могут подобрать независимые проекты / функции.

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

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


4

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

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

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


4

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

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

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

Вам придется экспериментировать, если у вас большая группа разработчиков и вы почувствуете, что работает в вашей ситуации. Вот страница от Microsoft, которая может быть несколько полезной: http://msdn.microsoft.com/en-us/library/aa730834(VS.80).aspx


4

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


1
Почему правило отсутствия базы данных меняется в ветке?
Бьорн Реппен

У нас просто есть правило, потому что оно облегчает слияние версий нашей базы данных. Это может быть связано с тем, что при обновлении базы данных мы используем последовательность в именах файлов сценариев, и я уверен, что если есть другой метод, изменения в базе данных можно было бы изменить в ветви.
adriaanp

2

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

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


2

Мы придерживаемся принципа ствола = текущий поток разработки, ветвь = релиз (ы). При выпуске клиенту мы разветвляем ствол и просто продолжаем вращать ствол. Вам нужно будет решить, сколько выпусков вы готовы поддержать. Чем больше вы поддерживаете, тем больше слияний вы будете исправлять. Мы стараемся держать наших клиентов не более чем в двух выпусках за стволом. (Например, Dev = 1.3, поддерживаемые выпуски 1.2 и 1.1).


1

Магистраль, как правило, является основной линией развития.

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


1

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

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


1

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

Под CVS я бы просто работал в "транке" и никогда не использовал теги / ветки, потому что было очень больно делать иначе.

В SVN я делал бы свои «передовые» вещи в транке, но когда пришло время делать push на сервере, помечали соответствующим образом.

Я недавно перешел на git. Теперь я обнаружил, что никогда не работаю в багажнике. Вместо этого я использую именованную ветвь с песочницей «new-featurename», а затем объединяюсь с фиксированной веткой «current-production». Теперь, когда я думаю об этом, мне действительно нужно создать ветки "release-VERSIONNUMBER", прежде чем вернуться к "current-production", чтобы я мог вернуться к более старым стабильным версиям ...


1

Это действительно зависит от того, насколько хорошо ваша организация / команда управляет версиями и какой SCM вы используете.

  • Если то, что будет дальше (в следующем выпуске), может быть легко спланировано, вам лучше заниматься разработкой в ​​стволе. Управление филиалами требует больше времени и ресурсов. Но если следующий план не может быть легко спланирован (это происходит постоянно в крупных организациях), вы, вероятно, в конечном итоге закончите сбором вишен (сотни / тысячи), а не филиалами (несколько или десятки).
  • С Git или Mercurial управлять ветвями намного проще, чем cvs и subversion. Я бы пошел на методологию стабильных стволовых / тематических веток. Это то, что использует команда git.git. прочитайте: http://www.kernel.org/pub/software/scm/git/docs/gitworkflows.html
  • С Subversion я впервые применил методологию разработки в багажнике. Когда дело дошло до даты релиза, было довольно много работы, потому что каждый раз мне приходилось выбирать коммиты (моя компания плохо разбиралась в планировании). Теперь я эксперт в Subversion и хорошо знаю, как управлять ветками в Subversion, поэтому я перехожу к методологии стабильных стволовых / тематических веток. Это работает намного лучше, чем раньше. Сейчас я пытаюсь понять, как работает команда git.git, хотя мы, вероятно, будем придерживаться Subversion.

1

Вот дизайн SVN, который я предпочитаю:

  • корень
    • развитие
      • ветви
        • feature1
        • feature2
        • ...
      • ствол
    • бета
      • теги
      • ствол
    • релиз
      • теги
      • ствол

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

Теги могут быть сделаны в бета-версии или в ветке релиза, чтобы мы могли отслеживать конкретный релиз как для беты, так и для релиза.

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


0

Метод, который мы используем, - это подход Perforce, который подробно обсуждается в великой книге Лоры Вингер:

http://oreilly.com/catalog/9780596101855/index.html

В то время как книга ориентирована на перформанс (Wingerd - менеджер по продуктам Perforce), концепции можно применять к любой или ко всем VCS.

Подход перформанса (и платформа) послужил нам очень хорошо. Он используется во многих фирмах (Google, Intuit и, как я слышал, сама Microsoft Windows).

Книга стоит того, чтобы ее прочитать.



0

ИМХО нет единого универсального ответа на вопрос о соглашении о подрывной деятельности.

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

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

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


-1

@ Brian R. Bondy: Обратите внимание, что это не решение, когда ваша команда достигает определенного количества задач / заданий, параллельно выполняемых в проекте.

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

В этом решении также отсутствует этап интеграции.


У нас есть несколько QA, участвующих в нашей команде. Они проверяют каждую функцию из полного установщика, созданного из ветви, до ее объединения.
Брайан Р. Бонди
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.