Как вы справляетесь с интеграцией кода из нескольких веток / разработчиков каждого спринта?

42

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

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

Как мы можем уменьшить эту нагрузку и облегчить объединение нашего кода? С моей точки зрения, если PO или SM приоритизируют истории более эффективным образом, чтобы у нас не было такого рода зависимостей в одном спринте, это может решить некоторые из проблем. Как все остальные справляются с этим? Или это только часть процесса?

cookiecutter
источник
18
У вас нет ветки разработки, в которой осуществляется непрерывная интеграция?
Каяман
13
Я здесь с Каяманом, лучшая практика для этого - реализовать непрерывную интеграцию.
RandomUs1r
27
С Днем Слияния! Каждый раз, когда ваша проблема слишком похожа на что-то в The Daily WTF, вы знаете, что у вас проблемы.
user3067860
Объединять рано, часто объединять: {написать наименьший тестовый код, который потерпит неудачу (красный), написать наименьший производственный код, который пройдет (зеленый), выполнить рефакторинг, провести повторное тестирование, объединить}, пока не завершено.
Ctrl-Alt-Delor
1
Первая регистрация выигрывает! Никогда не будь последним! :-)
ChuckCottrill

Ответы:

88

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

Когда разработчик завершает свою работу, он создает запрос на извлечение . Когда одобрено, это объединено в developветвь.

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

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

Берин Лорич
источник
73
Важной частью (которая подразумевается только в вашем ответе) является то, что ветви должны быть объединены, как только они будут готовы, обычно только с 1 - 5 фиксациями, а не только в конце спринта. Одна ветвь на функцию / историю, а не одна ветка на разработчика. Это требует, чтобы истории были действительно крошечными, то есть занимали не более двух дней.
Amon
@ amon, согласился. Добавлены слова «особенность ветки», но стараюсь держать этот ответ довольно маленьким. Есть много хороших статей, которые углубляются в этот процесс.
Берин Лорич
5
Не оставайтесь изолированными в своей собственной ветви. Так начинается ад слияния. Используйте основную разработку, изолируйте незавершенную работу за переключателями функций или другую конфигурацию во время выполнения.
Роб Кроуфорд
3
@Zibbobz Моя команда использует явные «ветви функций» для тех, которые в основном обрабатываются так же, как ветка разработки, но только для запросов на получение и коммитов, которые связаны с этим изменением. Как правило, в зависимости от того, как долго он должен оставаться отдельным, каждые несколько дней кто-то объединяет изменения из разработки в функцию и решает любые проблемы. Таким образом, ветви приходят как можно ближе, когда приходит время слияния. Как примечание, это только для действительно больших переломных изменений
reffu
9
«изолировать незавершенные работы за переключателями функций или другой конфигурацией во время выполнения» Вы только что избежали ада слияния, зайдя в ад настройки. «Ад слияния» является проблемой только для одного разработчика за один раз, и его легко избежать, если регулярно выполнять синхронизацию, а тонны эфемерной конфигурации - ад для всех будущих разработчиков навсегда.
Куб
23

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

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

Даниил
источник
2
Это и мой опыт. На самом деле не имеет значения, как часто вы фиксируете коммит, но после быстрой фиксации интеграция / слияние фиксации экономит много усилий. Однажды я участвовал в проекте, в котором у нас было три разных ветки разработки, каждая из которых имела многомесячную работу. Объединить их было не весело. Я многое узнал от этой ошибки :)
Амон
4
Да, это то, что означает «непрерывная интеграция»! Вы постоянно интегрируете свои изменения с изменениями других разработчиков!
Роб Кроуфорд
@Rob, согласился. Мое утверждение не должно было предполагать, что непрерывная интеграция не является непрерывной. Просто то, что мы не вполне достигли идеала и все еще видели много преимуществ в том, чтобы приблизиться к нему.
Даниэль
12
  • Держите свои ветви недолговечными (кажется, что вы уже делаете это).
  • Пусть результаты вашего теста говорят сами за себя.
  • Не ждите конца спринта.

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

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

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

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

Liath
источник
6

не

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

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

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

mmathis
источник
Честно говоря, используемый инструмент контроля версий более важен для успешного ветвления и слияния. Даже с кодом C # и предполагаемым кодом WinForms или WebForms, с которым вы должны работать, обычно это не сильно меняет . Если они есть, возможно, вам нужно сделать некоторые макеты, прежде чем играть с кодом. Интерфейсы на основе XAML так же стабильны, как и обычный код, а промежуточный код не зарегистрирован.
Берин Лорич
2
@BerinLoritsch Код конструктора WinForms действительно может многое изменить, даже с небольшими визуальными изменениями. Я обнаружил, что сами строки кода одинаковы, но порядок сильно отличается - особенно, когда несколько разработчиков делают изменения одновременно. Возможно, это проблема инструмента VCS (мы использовали несколько, может быть, мы просто используем неправильные), но для нас намного проще немного изменить наш процесс.
mmathis
2
@BerinLoritsch Я должен повторить это здесь, по крайней мере, для выигрышных форм (никогда не использовал веб-формы). Дизайнер пользовательского интерфейса winforms любит случайным образом переупорядочивать весь код в файле конструктора в ответ на тривиальное изменение где-то в форме. Если вы вручную не отмените переупорядочения перед каждым коммитом (что может легко составить 10 или 15 минут в сложной форме), история файла конструктора абсолютно бесполезна, и если 2 человека одновременно работают над пользовательским интерфейсом формы, это приведет к конфликт слияния из ада. Блокировка - вообще ужасный вариант, но с winforms действительно меньше всего зла.
Дэн Нили
@DanNeely, это одна из причин, по которой наша команда перешла от кода WinForms. Другая причина в том, что дизайнер очень хрупкий, и некоторые из наших сложных форм в любом случае нельзя редактировать визуально. В итоге нам пришлось вносить изменения непосредственно в коде - возможно, поэтому я не помню, чтобы там было слишком много потрясений. Это и наши пользователи, работающие с дисплеями высокой плотности, действительно подтолкнули нас к WPF. Болезненный процесс с высокой кривой обучения, но приятная награда в конце. В любом случае, большинство историй в бэклоге были для разных частей приложения.
Берин Лорич
@BerinLoritsch то же самое здесь. Выигрышные формы оплачивали большую часть моих счетов на протяжении большей части десятилетия на моей предыдущей работе, но я буду очень рад никогда больше не трогать их в будущем.
Дэн Нили,
2

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

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

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

Флаги функций имеют дополнительные преимущества (например, они облегчают проведение A / B-тестов). Смотрите эту статью Мартина Фаулера для получения дополнительной информации.

Флориан Брукер
источник
0

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

После завершения регрессионного и интеграционного тестирования мы легко перемещаем готовые к использованию функции в ветку релиза.

Если все идет хорошо, мы объединяем ветку релиза с мастер веткой.

emarshah
источник
0

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

Другие ответы дают некоторое представление о лучших практиках коммитов, и, просто следуя им, вы, вероятно, уменьшите подавляющее большинство проблем слияния. Большее количество слияний почти наверняка является необходимостью, но для небольшой команды ваш подход к отдельным ветвям, вероятно, работает достаточно хорошо. Конечно, не помешает (сильно) заняться более расширяемыми практиками!

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

Марс
источник