Як ви обробляєте інтегруючи код з декількох гілок / розробників кожного спринту?


42

Щойно вийшов з ретро-дзвінка, де розробники висловлювали стурбованість інтеграцією своїх історій у головну гілку кожного спринту. Всі розробники кодують всередині своєї власної гілки, і наприкінці спринту вони всі об'єднуються в одну головну гілку.

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

Як ми можемо зменшити цей тягар і полегшити злиття нашого коду? З моєї точки зору, наявність ПО або СМ розставляє пріоритети розповідей більш ефективно, щоб у нас не було подібних залежностей в одному спринті, можливо, вирішити деякі проблеми. Як усі інші вирішують це? Або це лише частина процесу?


18
У вас немає галузі розвитку, в якій здійснюється безперервна інтеграція?
Каяман

13
Я тут з Каяманом, найкраща практика для цього - впровадження постійної інтеграції.
RandomUs1r

27
З Днем Злиття! Щоразу, коли ваша проблема занадто схожа на щось на щоденному WTF, ви знаєте, що у вас проблеми.
користувач3067860

Злиття рано, злиття часто: {записуйте найменший тестовий код, який вийде з ладу (червоний), запишіть найменший виробничий код, який пройде (зелений), рефактор, повторне тестування, об'єднання}, поки не закінчено.
ctrl-alt-delor

1
Перша реєстрація виграє! Ніколи не будь останнім! :-)
ChuckCottrill

Відповіді:


88

Якщо ви використовуєте Git, кожен розробник буде перетягувати його з developвласної гілки функцій, щоб гарантувати, що вони не надто далеко від поточної базової лінії. Вони можуть робити це щодня, так що завдання, що займають більше декількох днів, залишаються синхронізованими та злиттями, вирішуються, поки вони ще невеликі.

Коли розробник закінчує свою роботу, вони створюють запит на тягу . Коли це буде затверджено, він об'єднується у developвідділення.

developФілія завжди повинен мати робочий код, і бути готовими до випуску в будь-який час. Коли ви фактично робите реліз, ви зливаєтесь developу нього masterта додаєте тег до нього.

Якщо у вас хороший сервер безперервної інтеграції, він буде будувати кожну гілку, коли буде зареєстровано зміни - особливо для запитів на виклик. Деякі сервери побудови інтегруються з вашим сервером Git для автоматичного затвердження або відхилення запиту на витяг, якщо збірка не вдається або автоматичні тести не вдається. Це ще один спосіб пошуку потенційних помилок інтеграції.


73
Важлива частина (яка лише випливає з вашої відповіді) полягає в тому, що гілки слід об'єднати, як тільки вони будуть готові, як правило, лише з 1 - 5 комітами, а не лише в кінці спринту. Одна гілка на особливість / історію, не одна гілка на розробника. Для цього потрібно, щоб історії були справді крихітними, тобто тривали максимум два дні.
амон

@amon, погодився. Додано слова "особливість гілки", але намагаємось зберегти цю відповідь досить мало. Існує маса хороших статей, які заглиблюються в цей процес.
Берін Лорич

5
Не залишайтеся ізольованими на власній гілці. Ось так починається злиття пекла. Використовуйте розробку основної лінії, ізолюйте незавершене виробництво за перемиканнями функцій або іншої конфігурації роботи.
Роб Кроуфорд

3
@Zibbobz Моя команда використовує явні "Feature Branches" для тих, хто в основному трактується як гілка розробки, але тільки для запитів на виклики та комісій, які стосуються цієї зміни. Як правило, залежно від того, скільки часу потрібно залишати окремим, кожні кілька днів хтось зливатиме зміни, що перетворюються, перетворюються на функцію та вирішують будь-які проблеми. Таким чином гілки максимально схожі, коли настає час злиття. Як зауважимо, це лише для дійсно великих переломних змін
reffu

9
"ізолювати незавершене виконання роботи за перемиканнями функцій або іншої конфігурації виконання" Ви просто уникли об'єднання пекла, перейшовши замість цього в конфігураційне пекло. "Злиття пекла" є лише проблемою для одного розробника за один раз, і його легко уникнути, просто синхронізувавшись регулярно, маючи тонни ефемерної конфігурації - це пекло для всіх майбутніх розробників назавжди.
Кубік

23

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

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


2
Це теж мій досвід. Насправді не важливо, як часто ви здійснюєте виконання, але коли ви швидко здійснили інтеграцію / об'єднання, це економить багато зусиль. Я колись був у проекті, де у нас було три різні галузі розвитку, кожна з яких мала багато місяців роботи. Об’єднання їх було не весело. Я багато чого навчився з цієї помилки :)
amon

4
Так - ось що означає "безперервна інтеграція"! Ви постійно інтегруєте свої зміни зі змінами інших розробників!
Роб Кроуфорд

@Rob, погодився. Моя заява не мала на меті припускати, що безперервна інтеграція не є, ну, постійною. Просто ми не зовсім зробили ідеал і все-таки побачили масу переваг у наближенні до нього.
Даніель

12
  • Тримайте свої гілки недовговічними (це здається, ви вже робите це).
  • Нехай ваші результати тесту говорять самі за себе.
  • Не чекайте закінчення спринту.

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

Потім, після завершення злиття, ви можете разом перевірити звіт про тест автоматизації та переконатися, що все було інтегровано успішно.

Я погоджуюся з однією з інших відповідей, де автор заявив, що Git PRs вирішить цю проблему, змусивши кожного розробника об'єднати власну роботу.

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


6

Не варто

Залежно від вашої мови та файлів, які ви редагуєте, можливо, не має сенсу кожен розробник редагувати їх у своїй гілці. Наприклад, у C # я знайшов, що найкраще одночасно редагувати будь-які файли дизайнера інтерфейсу лише одна людина. Це автогенеровані файли, і тому код іноді переміщується без видимих ​​причин - і це спричиняє загрозу для більшості інструментів злиття.

Це означає, що деякі історії можуть блокувати інші історії, поки робота інтерфейсу не буде виконана. І / або створена нова історія для простого компонування інтерфейсу користувача, а інші історії реалізують функціональність. Або, можливо, один розробник виконує весь інтерфейс, а інші реалізують функціональність цього інтерфейсу.

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


Чесно кажучи, використовуваний інструмент управління версіями є більш важливим для успішного розгалуження та об'єднання. Навіть з кодом C # і, імовірно, кодом WinForms або WebForms, з яким ви повинні працювати, зазвичай не так сильно змінюються . Якщо вони є, можливо, вам потрібно зробити кілька макетів, перш ніж грати з кодом. Користувацькі інтерфейси на основі XAML настільки ж стабільні, як звичайний код, і проміжний код не перевіряється.
Berin Loritsch

2
@BerinLoritsch WinForms дизайнерський код дійсно може змінити багато навіть при невеликих візуальних змінах. Я виявив, що самі рядки коду однакові, але впорядкування сильно відрізняється - особливо коли кілька розробників вносять правки одночасно. Можливо, це проблема інструменту VCS (ми використовували декілька, можливо, ми просто використовуємо неправильні), але для нас набагато простіше змінити наш процес.
mmathis

2
@BerinLoritsch Я маю другий mmathis тут, принаймні, для виграшних форм (ніколи не використовуваних веб-форм). Дизайнер інтерфейсу winforms любить випадковим чином упорядкувати весь код у дизайнерському файлі у відповідь на тривіальну зміну десь у формі. Якщо ви вручну не скасуєте замовлення перед кожним фіксацією (те, що легко може скласти 10 або 15 хвилин у складному вигляді), історія файлу дизайнера абсолютно марна, і якщо дві людини працюють над користувальницьким інтерфейсом форми відразу, це призведе до конфлікт злиття з пекла. Блокування - це взагалі жахливий варіант, але з формами winins справді є найменшим злом.
Ден Нілі

@DanNeely, Це лише одна з причин, через яку наша команда переїхала від коду WinForms. Ще одна причина полягає в тому, що дизайнер надзвичайно крихкий, і деякі наші складні форми ніяк не могли бути візуально відредаговані. Нам врешті-решт довелося внести зміни безпосередньо в код - позаду - напевно, тому я не пригадую надто великих потрясінь там. Це та наші користувачі, що працюють з дисплеями високої щільності, насправді підштовхнули нас до WPF. Болісний процес з високою кривою навчання, але приємною нагородою в кінці. Більшість оповідань у відставанні все одно були для різних частин програми.
Берін Лорич

@BerinLoritsch тут же. Виграшні форми оплачували більшу частину моїх рахунків протягом більшої частини десятиліття на моїй попередній роботі, але я буду дуже щасливий, що більше ніколи не торкаюся її в майбутньому.
Ден Нілі

2

Іншим можливим підходом до уникнення пізнього та великого злиття є прапорці функції : ви захищаєте свої зміни за допомогою (в ідеалі динамічно) настроюваного прапора, який заважає активізувати їх раніше, ніж призначено.

Це дозволяє вам об'єднати свої зміни на початку в ту masterчи іншу галузь спільного розвитку, нічого не порушуючи. Потім інші розробники можуть об'єднати ці зміни назад у свої гілки функцій (або відповідно відновити їх гілки).

Як вже було зазначено в інших відповідях, це слід поєднувати з рішенням безперервної інтеграції.

Функційні прапори мають додаткові переваги (наприклад, вони спрощують тестування A / B). Дивіться цю статтю Мартіна Фаулера для отримання додаткової інформації.


0

Ми дотримуємось підходу окремої галузі розробки для кожної функції, а потім ми об'єднуємо гілки в галузь QA для тестування в середовищі інтеграційного тестування.

Після завершення тестування регресії та інтеграції ми легко переміщуємо функції, готові перейти, до гілки випуску.

Якщо все піде добре, ми з’єднуємо гілку випуску назад у головну гілку.


0

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

Інші відповіді дають велике розуміння найкращих практик для комітетів, і, просто дотримуючись тих, ви, ймовірно, зменшите переважну більшість питань, пов’язаних із об'єднанням. Більше злиття майже напевно є необхідністю, але для меншої команди ваш підхід «на людину», ймовірно, працює досить добре. Звичайно, не завадить (сильно) потрапляти в більш розтяжні практики, хоча!

Однак, схоже, ніхто не звертався до одного з ваших найбільш важливих питань - що робити, коли всі ви торкаєтесь одних і тих же областей коду. Тут корисно мати ведучого, який знайомий з кодовою базою і може розпізнавати залежності різних завдань. Якщо вони не визначають терміни виконання робіт і зобов’язань, ви, швидше за все, зіткнетеся з конфліктами та об'єднанням рядків за рядком. Організувати задачі \ терміни набагато складніше з більшою командою, але з невеликою командою можливо виявити ці конфліктні завдання. Тоді ведучий може навіть перенести всі пов'язані завдання на одного і того ж інженера, щоб уникнути конфлікту взагалі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.