Лучшие практики ветвления и объединения в Git

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

Мы используем облегченную версию Git Flow. У нас есть dev, staging и master ветки, которые линейны друг с другом.

  • постановка ответвлена ​​от мастера
  • dev отделен от постановки

Вдобавок к этому мы используем ветки функций и исправлений для работы над новыми функциями и исправления ошибок.

У меня есть следующие вопросы:

  1. Должны ли мы разветвлять функциональные ветки от разработчика или от мастера?
  2. Когда функциональная ветка готова, следует ли нам объединить функциональную ветвь в dev, затем объединить dev в промежуточную или объединить функциональную ветку в промежуточную, а затем функциональную ветвь в мастер?

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

Каково твое мнение? Какие лучшие практики?


person Gaui    schedule 05.07.2014    source источник
comment
Возможный дубликат git с ветвями разработки, подготовки и производства   -  person Liam    schedule 21.02.2017
comment
ИМХО это не дубликат. Близко родственник? да. Дубликат? Нет. Этот вопрос основан на модели потока git, а связанный вопрос ссылается на статью с аналогичным, но не идентичным рабочим процессом.   -  person Sascha Wolf    schedule 21.02.2017
comment
git-scm.com/docs/merge-strategies   -  person Shiwangini    schedule 17.07.2020


Ответы (3)


Хотя Git Flow - отличная модель ветвления, вопросы, которые вы задаете, являются симптомом более серьезной проблемы: Git Flow слишком тяжел для небольшой команды, работающей над потребительским веб-продуктом (я предполагаю, что вы работаете в потребительской сети). продукт, не стесняйтесь игнорировать, если вы кодируете диспетчерскую АЭС).

Я хотел бы призвать вас рассмотреть возможность непрерывного развертывания (CD) с чрезвычайно простой моделью ветвления:

Мастер -› Филиал

В настоящее время настроить компакт-диск очень просто:

  1. Используйте Travis, CodeShip, Jenkins или аналогичную систему для запуска полной сборки и набора тестов при каждой фиксации, отправляемой в каждую ветку вашей кодовой базы.
  2. Настройте Travis / Codeship / Jenkins для развертывания в производственной среде каждой фиксации для мастера, которая проходит тесты.
  3. Создайте новую ветку от master для каждой новой функции.
  4. Закодируйте новую функцию и протестируйте ее в ветке.
  5. Объедините функциональную ветку с master и посмотрите, как она заработает.

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

Я призываю вас попробовать. Это освободит ваш разум, чтобы сосредоточиться на самом важном: создании отличного продукта! Если вы мне не верите, взгляните на эту отличную презентацию из Github.

person quarterdome    schedule 14.05.2015
comment
Спасибо, это цель мечты. Но менеджеры хотят, чтобы код был развернут для тестовых, промежуточных и живых сред. Не уверен, как это вписывается в эту простоту. - person Gaui; 15.05.2015
comment
Это действительно очень хорошо подходит. Независимо от того, что вы помещаете в ветку, можно пройти любое количество тестов: вы можете протестировать на своей машине и выполнить слияние, или вы можете поставить это на промежуточную стадию и набросить на нее команду QA из 10 человек на две недели. Вам необходимо использовать соответствующий уровень тестирования для каждой функции. Изменение однострочного обмена сообщениями не должно проходить тот же процесс тестирования, что и процесс оформления новой корзины покупок. CD позволяет вам делать это, сохраняя простоту ветвления. - person quarterdome; 15.05.2015
comment
Как вы упомянули, это кажется лучшим решением для небольших команд. Нет причин усложнять процесс. Спасибо, что поделились слайд-шоу. - person Adam; 01.11.2017
comment
Другая точка зрения на то, что сказал @Airborne: похоже, лучшее решение - иметь команды меньшего размера (и кросс-функциональные). Нет причин усложнять процесс. - person Matruskan; 17.01.2018
comment
Мне нравится этот ответ, но первая реакция - отпрянуть. Какие? нам нужны все эти ветки, процессы и блокировки, чтобы ошибки не отправлялись. Но этот поток происходит, я думаю, потому, что вещи в вашем разделе ifs пропущены. Это то, что монолитные сборки каждые x недель пугают людей. - person redOctober13; 14.12.2018

Это всегда зависит от того, как вы хотите работать, и согласия в команде. Тем не менее.

  1. Функция начинается с ветки разработки в ее собственную ветку. Из основной ветки следует выполнять ветвление только исправлений, потому что основная ветвь всегда должна быть стабильной версией вашего программного обеспечения.
  2. Когда ветка функций создана, ее следует объединить с разработчиком, а затем в какой-то момент вам следует перейти к следующему выпуску от разработчика (включая некоторые функции) в новая ветка 'release / *', которая будет объединена в главную, как только она будет стабилизирована и хорошо протестирована.

На странице Atlassian у вас есть очень хорошее объяснение этого рабочего процесса

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

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

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

Также похоже, что этот вопрос задавали раньше

person Pablo Carranza    schedule 05.07.2014
comment
Что делать, если у вас нет (заранее определенных) выпусков и вы не хотите, чтобы все, начиная с dev, попало в staging или master? Не лучший способ отделить функцию от мастера, поработать над этой функцией изолированно, а затем объединить ее с разработчиком. Если все в порядке, объедините функциональную ветку до стадии подготовки. Если принято, объедините функциональную ветку в master и разверните в продакшн. Если мы объединим функциональную ветку с разработчиком, а затем слим девиз с промежуточной стадией, могут быть некоторые функции, которые нам не нужны. Также, если что-то находится на стадии постановки, не следует переходить к мастеру. - person Gaui; 05.07.2014
comment
Обычно dev - это то, что вы можете назвать вашим следующим выпуском. Я сделал что-то вроде того, что вы говорите в одном проекте, и все закончилось хорошо, но при слиянии пришлось много доработать, в основном потому, что вы можете объединить функцию в мастере, полученную из давно забытой версии, а кодовая база сильно изменилась . Так что это зависит от вас и от того, как вы планируете свою работу, но я предполагаю, что в какой-то момент вы сможете сказать что-то вроде: хорошо, эти функции должны быть выпущены в следующий раз, и тогда вам придется слиться с разработчиком или поцарапайте dev и просто используйте ветки релизов от master. - person Pablo Carranza; 05.07.2014

Мы остановились на рабочем процессе под названием Git Flow, но вместо функций ветвления from dev, мы ответвляем их от текущего релиза. Это позволяет нам работать над отдельными проблемами с разной скоростью. Если они успешны в QA, они переходят в релиз.

По поводу веток и развертывания:

  • Ветвь dev автоматически развертывается на тестовых серверах.
  • Текущая ветвь выпуска автоматически развертывается на промежуточных серверах.
  • Ветвь master вручную развертывается на действующих серверах мастером выпуска.

Рабочий процесс следующий:

  1. Создайте ветку выпуска из master в начале каждого выпуска / спринта, например выпуск / 2015-май.
  2. Создайте ветку dev от выпуска / 2015-май
  3. Работая над новой функцией, перейдите от выпуска и назовите его feature / ISSUE_NUMBER.
  4. Работайте над своей функцией.
  5. Когда он будет готов к тестированию, слейте его с dev.
  6. Если он принят, объедините его с веткой текущего выпуска.
  7. Если он не принят, переходите к шагу 4.
  8. Когда релиз будет готов, объедините его в master

После того, как выпуск был развернут в реальном времени и обнаружена критическая ошибка, мы разветвляем ветку исправлений от мастера (например, hotfix / ISSUE_NUMBER), объединяем ее обратно в мастер и снова развертываем.

person Gaui    schedule 14.05.2015
comment
Но каким будет этот подход, если предположить, что 2+ новых фичи запускаются параллельно? Например, release / 2015-may - ›dev -›, затем feature / 1 и feature / 2. Итак, что было бы, если бы и функция / 1, и функция / 2 были объединены в dev и принималась только функция / 1? - person Kamalakannan J; 13.02.2017
comment
@KamalakannanJ Тогда только функция / 1 будет объединена в постановку / выпуск. - person Gaui; 22.02.2017
comment
Итак, мы должны объединить функцию / 1 непосредственно в постановку / выпуск ?? не через разработку / выпуск? - person Kamalakannan J; 28.02.2017
comment
Да, сначала объедините эту функцию с dev. Если это принято на разработке, вы объединяете эту функцию в стадию / выпуск. - person Gaui; 02.03.2017