Close

Git или SVN? Как компания Nuance Healthcare выбрала модель ветвления Git

Фотография Николы Паолуччи
Мэтт Шелтон

Консультант по разработке


Эта публикация от Мэтта Шелтона из Nuance Healthcare — первая статья из серии, где он описывает, как его команда переходила из Subversion в Git, почему было принято такое решение и с чем пришлось столкнуться в процессе перехода. Мэтт уже выступал на эту тему на конференции Atlassian Summit 2015. В этой серии статей он подробно расскажет обо всех темах, которые не успел затронуть в получасовом докладе.

Фон


Моя команда работает в медицинском подразделении Nuance. Мы географически распределены и размещаемся в нескольких офисах и зданиях на восточном побережье США, а также в г. Пуна. Наш коллектив разрабатывает веб-сервисы Java для поставки решений NLP [1] на рынок медицинских услуг.

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

Наша команда хорошо знакома с некоторыми сочетаниями продуктов для управления жизненным циклом приложений. Мы начали с комбинации Rally Enterprise и Seapine TestTrack Pro, примерно 14 месяцев напряженно работали с Rational Team Concert, но в итоге полностью перешли к стеку Atlassian (Jira, Confluence, Bamboo, Crucible и Bitbucket). Сначала в качестве решения SCM мы использовали Subversion версий 1.4 и 1.5 с квазинормальной структурой магистрали, веток и тегов. Мы всегда применяли maven для управления проектами сборки и зависимостями, а некоторое время назад перешли с Jenkins на Bamboo для непрерывной интеграции (CI), чтобы получить более тесную интеграцию с Jira и гибкие возможности ее агентов сборки и развертывания. Все инструменты, с которыми мы (сейчас) работаем, по определенным причинам [2] находятся за брандмауэром.

базы данных
Связанные материалы

Перемещение полного репозитория Git

Логотип Bitbucket
СМ. РЕШЕНИЕ

Изучите Git с помощью Bitbucket Cloud

Git или SVN?


Мы поддерживаем около десяти отдельных продуктов в четырех семействах, и владельцы этих продуктов постоянно борются за приоритеты и сроки. Приятно, что наша работа пользуется большим спросом, и мы вовсе не жалуемся, но нам часто приходится выпускать релизы в непривычном темпе и менять направление посреди спринта [3].

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

Я: «Мы должны немедленно передать версию 1.8.0 в отдел контроля качества для регрессионного тестирования, чтобы клиент мог перейти на бета-версию на следующей неделе». Разработчик: «Я все еще работаю над изменением ABC-123, которое находится в магистральной ветке. Оно пока не закончено». Я: «Клиенту не нужно изменение ABC-123. Мы могли бы добавить его в следующий релиз». Разработчик: «Но я работаю над ним уже несколько недель. У нас нет хорошего места для ветвления, чтобы выпустить релиз». Я: «Тогда придется извлечь все изменения вручную. У тебя есть около двух часов, иначе отдел контроля качества не уложится в срок».

Я знаю, мое поведение в этом примере отвратительно. Однако это не нарочно. Я лишь хотел в утрированной манере показать, что нам действительно нужно было придумать, как временно вытащить код, чтобы быстро выпустить релиз, а затем вернуть его обратно для следующего релиза [4]. И такое происходило постоянно.

Сейчас многие наверняка подумали: «Но Subversion же поддерживает ветки, Мэтт…». Это действительно так, и мы иногда использовали их в SVN 1.4 и 1.5. Ветвление — прекрасная операция в SVN, а вот слияние может стать серьезной проблемой. По мере своего развития система SVN, безусловно, совершенствовалась. Но мы знали, что есть варианты, которые лучше подойдут нашей команде, поэтому в итоге выбор пал на Git.

Нужно заметить, что мы бегло ознакомились с последней на тот момент версией SVN (1.8), чтобы понять, способна ли она решить наши проблемы, однако не были полностью удовлетворены. У наших коллег из другой группы был большой репозиторий Perforce. Хотя там было многое из того, что нам требовалось, мы просто не могли позволить себе такие затраты на лицензирование. Мы также рассматривали решение Mercurial, но поскольку команда была уже знакома с Git, этого оказалось достаточно, чтобы мы укрепились в выборе.

Не буду кривить душой: инструменты Atlassian ориентированы в первую очередь на команды, которые используют git. С другими системами SCM они тоже работают хорошо; наша интеграция с SVN была вполне удовлетворительной — с ее помощью мы могли перейти к месту, где вносились изменения в конкретную пользовательскую историю. Однако команды, которые используют Bitbucket Server [5], имеют больше возможностей и легче ориентируются в интерфейсе и процессах Jira Software. То же самое можно сказать и о Bamboo.

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

Выбор модели ветвления Git


После того как было принято решение о переходе, первой проблемой, с которой мы столкнулись, стал выбор модели ветвления Git для нашей команды. Подробно ознакомиться с понятием модели ветвления можно на микросайте Git компании Atlassian, а также в отличной презентации с конференции Summit 2013. Если говорить кратко, модель ветвления предписывает, как именно вы будете использовать ветки в git для управления процессом разработки.

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

  • Самый новый код находится в магистральной ветке. Релизы из магистральной ветки нумеруются следующим образом: A.B.0-{сборка}.
  • Если требуется внести исправление в магистральный релиз (например, когда обнаружена ошибка в релизе 1.2.0-64), создается ветка, из которой будут выпускаться релизы A.B.C-{сборка}, где переменная C увеличивается после каждого выпущенного релиза. Для некоторых переменных A.B такие ветки могут отсутствовать, а в других случаях их может быть несколько.
  • Кроме того, каждый релиз помечается в каталоге тегов.

Замечание по поводу версий. Много лет назад, когда я делал первые шаги в управлении командой разработчиков, наш инженер по релизам использовал систему управления версиями, которая была, скажем так, крайне неинтуитивной. По сути, каждый релиз был исправлением предыдущего (A.b.n), но без учета того, откуда происходило исправление. Чтобы выяснить, откуда взялся тот или иной код, и (почти во всех случаях) понять порядок релизов, нужно было просмотреть журнал SVN. Мы распечатали дерево и повесили его на стену для справки. Кроме того, наши клиенты обычно видели привычные для себя номера релизов, например 3.0, 3.1, 3.5 и 4.0. Однако не нужно забывать, что моя команда создает веб-сервисы, а не коробочный продукт. Наши API — это контракт. Несколько лет назад я принял решение о том, что сборки команды и ее релизы должны следовать правилам семантического метода управления версиями. Мне пришлось несколько раз отстаивать свою позицию перед высшим руководством, но теперь все понимают, почему правила именно такие, и мы не жалеем об этом решении. Партнеры ценят такую ясность.

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

Удаление целой функции из общей магистральной ветки — большая проблема. Это никому не нравилось. Хотя мы могли использовать эффективный инструмент сравнения svn blame, он не особенно удобен в работе. Я часто принимал такие ситуации близко к сердцу и считал, что именно из-за моего неудачного планирования часть функций не была готова к дате релиза [7]. Моей команде достаточно долго приходилось мириться с таким положением дел.

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

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

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

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

Несколько участников команды предпочли вариант этой модели, известный как Git-flow. Git-flow — это набор правил именования веток и правил слияния, которые разработал Винсент Дриссен. Команда сочла их очень удобными. Кроме того, нам понравилась структура, которая снимала многие вопросы, например «Что предпринять, когда нужно сделать ту или иную вещь?». Чаще всего ответ был очевиден. Не буду объяснять, что такое git-flow, — почитайте об этой модели в учебном руководстве Atlassian.

У нас оставался единственный нерешенный вопрос в отношении git-flow: что делать с долгосрочными релизами в рабочей среде? Поскольку главная ветка постоянно движется вперед, мы не могли использовать рабочий процесс быстрого исправления в git-flow, чтобы исправить ошибки предыдущего релиза. С другой стороны, нам не всегда нужна была ветка поддержки.

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

1. Код нельзя просто объединить с веткой разработки.

2. Партнер/клиент не может работать с измененным интерфейсом в последнем релизе.

3. Существует внутренняя зависимость, которую нельзя изменять[8].

Оба пакета расширения git-flow [9] поддерживают концепцию ветки поддержки, которая отсутствовала в первоначальном проекте git-flow, но стала достаточно популярной, чтобы ее включили в пакет.

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

[1]. Обработка естественного языка. МЫ МОЖЕМ ЧИТАТЬ МЫСЛИ. (Вообще-то нет.)

[2]. В облачных решениях Atlassian много привлекательных особенностей, но пока мы вынуждены держаться за свои серверы и данные. Мы сами нечасто работаем с данными PHI, а вот наше ПО — очень даже, поэтому нам нужно обеспечить максимальную безопасность.

[3]. Тсс… только не говорите Кену Шваберу.

[4]: Возможно, всего несколько дней спустя.

[5]. Раньше это решение называлось Stash. Привет осеннему ребрендингу Atlassian!

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

[7]. Обычно дело было не в этом. Как правило, чьи-то сроки сдвигались, и нам приходилось быстро реагировать.

[8]. Об этом я не могу рассказать в своем блоге. Просто поверьте мне. На это есть причины.

[9]. Первоначальный пакет Винсента Дриссена больше не поддерживается. Однако новый форк регулярно обновляется.


Footnotes

[1]: Natural Language Processing. WE CAN READ YOUR THOUGHTS. (No. Not really.)

[2]: There is a lot that is attractive about Atlassian's cloud offerings, but we need to keep our fingers wrapped tightly around our servers and data for the time being. While we don't personally need to do much with PHI data, our software does and it's important to keep it as secure as possible.

[3]: Shhhh... don't tell Ken Schwaber.

[4]: Which might have only been a few days later anyway.

[5]: Formerly known as Stash. Hello, Atlassian Fall Rebranding!

[6]: I know we could always pull it out of the previous commit. I was kidding.

[7]: This wasn't usually the case - generally it was because someone else's timeframe moved up and we had to react quickly.

[8]: This is one of those things I can't get into on my own blog. Just trust me. "Reasons".

[9]: The original package by Vincent Driessen isn't being maintained any longer. A new fork, however, is regularly updated.

Matt Shelton
Matt Shelton

Мэтт Шелтон — консультант и практик DevOps, курирующий предоставление услуг DevOps и других сопутствующих сервисов Atlassian в Северной и Южной Америке. Сейчас он редко пишет в блог и посвящает все свое время воспитанию нового поколения консультантов по передовым практикам работы.


Поделитесь этой статьей
Следующая тема

Рекомендуемые статьи

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

Люди сотрудничают друг с другом, используя стену со множеством инструментов

Блог Bitbucket

Рисунок: DevOps

Образовательные программы DevOps

Демонстрация функций в демо-зале с участием экспертов Atlassian

Как инструмент Bitbucket Cloud работает с Atlassian Open DevOps

Подпишитесь на информационную рассылку по DevOps

Thank you for signing up