Командная разработка с использованием Visual Studio Team Foundation Server

Стратегии ветвления и слияния

Показывать лекцию целиком

Обзор

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

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

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

Сценарии ветвления и слияния

Ниже представлены примеры сценариев, в которых может потребоваться создание ветвей и выполнение слияний:

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

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

    Типичные сценарии

    Ниже приведены наиболее типичные сценарии ветвления:

  • Сценарий 1 - без ветвей. Команда работает только из главного дерева исходного кода. В этом случае вы не создаете ветвей и не нуждаетесь в изоляции. Данный сценарий соответствует, главным образом, мелким и средним командам, не требующим изолирования групп, функций или выпусков.
  • Сценарий 2 - ветвь выпуска. Команда создает ветви для текущего сопровождения выпуска. Это наиболее распространенная ситуация. В этом случае ветвь создается для обеспечения устойчивости очередного выпуска до его выхода, а затем опять сливается с главным деревом исходного кода.
  • Сценарий 3 - ветвь сопровождения. Команда создает ветвь для обслуживания предыдущей сборки, чтобы делать это, не нарушая устойчивости текущих сборок. Обратное слияние изменений ветви сопровождения с главным деревом производится при необходимости. Допустим, оно не нужно, если вы вносите для группы клиентов специфические оперативные изменения, который не хотите включать в главную сборку.
  • Сценарий 4 - ветвь функции. Команда создает ветви, основываясь на функциях. То есть, вы создаете ветвь разработки, выполняете в ней нужную работу, а затем производите слияние с главным деревом исходного кода. Вы можете создавать самостоятельные ветви для работы над отдельными функциями, окончательная доработка которых будет происходить параллельно.
  • Сценарий 5 - ветвь группы. Ветви создаются для изолирования подгрупп, чтобы они могли работать, не мешая друг другу или двигаясь параллельно к различным контрольным точкам.
  • Вы можете столкнуться как с одним, так и с несколькими из этих сценариев. Используйте их в качестве ориентира.

    Примеры папок и их назначение

    В этом разделе приведены примеры папок, создаваемых в системе управления исходным кодом Microsoft Visual Studio® Team Foundation Server (TFS) при структурировании дерева кода по сценариям ветвления и слияния.

  • Папка Main содержит главное дерево исходного кода. Здесь соединяются изменения из других ветвей.
  • Папка Development является ответвлением Main и используется для изолирования текущей разработки. Подобные ветви могут создаваться временно, например, для проверки рискованных изменений, без влияния на Main.
  • Папка Releases содержит ветви выпусков, которые уже осуществлены, и сейчас осуществляется поддержка клиентов. Она обеспечивает изоляцию текущей разработки, которая ведется в ветви Development, а также содержит ветвь текущего выпуска, которая отделена от Main и хранит версию, заблокированную до выпуска. В этой ветви вы готовите ПО к выпуску, тогда как остальные продолжают работать в ветви Development над новыми функциями.
  • В следующих разделах на конкретных примерах показано использование ветвления в каждом из описанных сценариев.

    Сценарий 1 - без ветвей

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

    {
    My Team Project 
    Main
    Source 
    }

    Сценарий 2 - ветвь выпуска

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

    }
    My Team Project
    Main	->Главная ветвь сборки
    Source
    Releases 
    Release 1        ->Ветвь выпуска 
    Source 
    }

    Сценарий 3 - ветвь сопровождения

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

    }
    My Team Project
    Main         - >Главная ветвь сборки
    Source
    Releases	->Контейнер для ветвей сопровождения
    Release 1     ->Ветвь сопровождения 
    Source
    Другие папки ресурсов 
    Release 2      ->Ветвь сопровождения 
    Source
    Другие папки ресурсов 
    }

    Сценарий 4 - ветвь функции

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

    {
    My Team Project 
      Development	->Изолированный контейнер ветвей разработки
        Feature A	->Ветвь функции
          Source 
        Feature B	->Ветвь функции
          Source 
        Feature C 	->Ветвь функции
      Main		->Главная ветвь сборки
    Source 
    }

    Сценарий 5 - ветвь группы

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

    {
    My Team Project
       Development       	->Изолированный контейнер ветвей разработки
          Team 1	-> Ветвь группы
              Feature A	-> Изолированная ветвь разработки
                  Source
              Feature B	-> Изолированная ветвь разработки
                  Source
                  Team 2	-> Ветвь группы
              Feature A	-> Изолированная ветвь разработки
                  Source
              Feature B	-> Изолированная ветвь разработки
                  Source
                  Main	-> Главная ветвь сборки
                Source
    }

    Логическая структура

    Логическая структура выражает для каждой ветви отношения "родитель - потомок". Она может отличаться от физической структуры, отображаемой в Source Control Explorer. Например, в показанной выше физической структуре Development и Main являются папками одного уровня, тогда как с точки зрения логики Development является дочерней папкой Main.

    На рис.5.1 показан пример логической структуры ветвлений и слияний.

    (рис 5.1) Логическая связь ветвлений и слияний

    Сценарий выпуска

    На рис.5.2 представлена типичная последовательность действий при ветвлении для выпуска.

    (рис 5.2) Последовательность действий при ветвлении для выпуска

    Последовательность действий такова:

  • Когда выпуск готов к изоляции, в Main создается ветвь Release 1.
  • Периодически проводятся слияния с Main, чтобы переместить серьезные исправления в главную ветвь сборки.
  • В ветви RTM выпуск помечается с последующей слиянием с Main.
  • Выпущен пакет обновлений SP1. Сборка помечается, выполняется слияние изменений с Main.
  • Ветвь Release 1 оставляется для поддержки SP1 и для последующих пакетов обновлений.
  • Процесс повторяется для следующих выпусков.

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

    Сценарий изолированной разработки

    На рис.5.3представлена типичная последовательность действий при ветвлении для изолирования разработки. Последовательность действий такова:

  • Создается ветвь Feature A для изолирования разработки первой функции.
  • Создается ветвь Feature B для изолирования разработки второй функции.
  • Каждая группа выполняет слияние с Main по мере достижения контрольных вех, когда функцию можно объединять с главной сборкой для обеспечения доступа к ней других групп.
  • Каждая группа по графику проводит слияние с Main с целью извлечения результатов работы других групп и уменьшения числа конфликтов при проведении последующих слияний.
  • Когда функция готова, производится слияние изменений с Main, а ветвь функции удаляется.
  • (рис 5.3) Последовательность действий при ветвлении для изолирования разработки

    Различные аспекты ветвления

    Проводя ветвление, имейте в виду следующее:

  • Не следует выполнять ветвление, если команда разработчиков не нуждается в одновременной работе над одними и теми же наборами файлов. Если у вас нет уверенности по этому поводу, пометьте сборку и позже при необходимости создайте из нее ветвь. Слияние ветвей - длительный и сложный процесс, особенно при наличии существенных различий.
  • Организуйте деревья ветвей таким образом, чтобы слияния выполнялись только вдоль иерархии (вверх и вниз по дереву), но не поперек иерархии. Ветвление "по горизонтали" требует осуществления слияния без основы (baseless merge), при котором чаще приходится разрешать конфликты вручную.
  • Основу иерархии ветвей составляют родительские и дочерние ветви, структура которых может отличаться от физической структуры кода на диске. При планировании слияний учитывайте именно логическую, а не физическую структуру ветвей.
  • Не выполняйте слишком глубокого ветвления. Чем оно глубже, тем больше тратится времени на выполнение слияний и разрешение конфликтов. Это может отрицательно сказаться на графике работы по проекту и затянуть исправление ошибок.
  • Выполняйте ветвление на высоком уровне и включайте в него файлы конфигурации и исходного кода.
  • Постоянно развивайте структуру ветвления. Слиянием и разрешением конфликтов занимается один или несколько разработчиков. Код, полученный в результате слияния, должен быть всесторонне протестирован, так как нередки случаи, когда неверное слияние приводит к потере устойчивости сборки.
  • Слияние "по горизонтали" особенно сложно и требует разрешения вручную многих конфликтов, которые в ином случае могли бы быть разрешены автоматически.
  • Решение о проведении ветвления в конечном итоге сводится к сравнительной оценке затрат на непрерывное разрешение конфликтов в реальном времени и на их периодическое разрешение при слиянии ветвей.

    Особенности крупных проектов

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

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

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

  • Обратная интеграция, например, слияние из ветви разработки в главную ветвь сборки, обычно планируется заранее.
  • Прямая интеграция, например, при слиянии из главной ветви сборки в ветвь разработки, обычно, управляется событием, например, достижением вехи в разработке функции. Это происходит, когда группа, отвечающая за ветвь разработки, считает, что она готова выполнить слияние изменений из родительской ветви.
  • Корректируйте стратегию ветвления и слияния столь же часто, как вы производите сборки. Более глубокая структура ветвления требует дополнительного времени на перенос изменений из дочерних ветвей в главную ветвь сборки. Далее перечислены признаки приближения связанных с этим проблем:

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

    Далее приведен пример сложной структуры ветвления:

    {
    My Team Project
    Development	->Контейнер для изолирования активных ветвей разработки
    Feature A	->Изолированная ветвь разработки
    Source
    Feature B	->Изолированная ветвь разработки
    Source
    Main	->Главная ветвь компоновки и сборки.   Здесь сходятся все изменения. 
    Source
    Папки с другими ресурсами
    Releases	->Контейнер для текущего выпуска и ветвей сопровождения
    Release 2	->Активная ветвь сопровождения
    Source
    Папки с другими ресурсами
    Release 3	->Активная ветвь сопровождения
    Source
    Папки с другими ресурсами
    Release 4	->Ветвь с кодом,   заблокированным до выпуска
    Sourse
    Папки с другими ресурсами 
    Архив
    Release 1	->Старый выпуск в архиве
    Source
    Папки с другими ресурсами 
    }

    В данную структуру включены:

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

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

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

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

    Дополнительные ресурсы

  • Раздел "Руководство по управлению исходным кодом" В нем вы найдете дополнительные рекомендации по ветвлению и слиянию.
  • Вводный курс по ветвлению и слиянию вы найдете в статье "Branching and Merging Primer" по адресу http://msdn2.microsoft.com/en-us/library/ aa730834(VS.80).aspx.
  • Дополнительную информацию о ветвлении вы найдете в статье "How to: Branch Files and Folders" по адресу http://msdn2.microsoft.com/en-us/ library/ms181425(VS.80).aspx.
  • Дополнительную информацию о слиянии вы найдете в статье "How to: Merge Files and Folders" по адресу http://msdn2.microsoft.com/en-us/ library/ms181428(VS.80).aspx.
  • Дополнительную информацию о ветвлении и слиянии в Visual Studio 2005 вы найдете в статье "Branching and Merging Team Foundation Source Control" по адресу http://msdn2.microsoft.com/en-us/library/ms181423 (VS.80).aspx.
  • Вернуться к учебному плану