Стратегії об'єднання 1 рік розробки у Visual Studio


32

У мене є клієнт, який наполягав на тому, щоб ми повністю тримали нашу нову розробку від основних гілок протягом усього 2016 року. У них було ще 3-4 команди, які працювали над заявкою в різних можливостях. Було внесено чимало великих змін (переключення того, як робиться ін'єкція залежності, очищення коду за допомогою ReSharper тощо). Зараз на мене впало головне об'єднання в нашу нову відділення розробників, щоб підготуватися до зміни наших ланцюгів.

Під час мого початкового об'єднання TFS повідомив про ~ 6500 файлів із вирішенням конфлікту. Деякі з них будуть легкими, але деякі з них будуть набагато складнішими (зокрема, деякі з javascript, api-контролерів та сервісів, що підтримують ці контролери).

Чи є такий підхід, який мені полегшить?

Для уточнення, я висловлював велику стурбованість цим підходом кілька разів на цьому шляху. Клієнт був і усвідомлює труднощі з цим. Оскільки вони вирішили скоротити персонал із забезпечення якості (1 тестер на 4 дивіжа, автоматичне тестування, невелике регресійне тестування), вони наполягали на тому, щоб ми тримали нашу філію ізольованою від змін у головній галузі під видом, що це зменшить потребу в наших тестер, щоб знати про зміни, які вносяться в інших місцях.

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


63
Ні. У вас є дві окремі галузі, які активно розвивалися протягом року. Злиття збирається смоктати.
17 з 26

2
Яка міра змін, які внесла ваша команда? Можливо, буде більш ефективним виявити ці зміни, а потім вручну застосувати їх до поточної основної бази кодів.
kdgregory

2
Це цілий 2015 чи 2016 рік? Якщо у 2015 році його 2 роки, це означає, що він подвоїться.
Девід каже, що поверніть Моніку

1
Чому клієнт хвилює, якщо робота, яку ви виконуєте для них, знаходиться на окремому відділенні вашої системи контролю версій?
Іксрек

17
Що б ви не робили, переконайтеся, що ви платите щогодини.
Шон Мак-Що-небудь

Відповіді:


37

Був би простий спосіб, який би тримав вашу нову розробку окремо від головної гілки, не вводячи вас у цю нещасну ситуацію: будь-які зміни зі стовбура повинні були щодня вливатися у вашу галузь розробників . (Чи справді ваш клієнт був настільки короткозорим, що не міг передбачити, що вашого відділення потрібно перетворити на головну лінію якогось дня?)

У будь-якому випадку, найкращим підходом є ІМХО, який намагається переробити те, що мало б статися з перших рук:

  • визначте семантику змін на основній лінії за 1 день після створення гілки. Застосуйте їх до вашої поточної бази кодів, а також можете. Якщо це була "локальна зміна", вона повинна бути простою, якщо це був "наскрізний рефакторинг", як перейменування широко використовуваного класу, застосуйте його семантично еквівалентним чином до вашої поточної бази кодів. Сподіваємось, протягом цього року жодної суперечливої ​​наскрізної зміни в кодовій базі не було внесено на "вашу" гілку, інакше це може стати справжнім мозком-тизером
  • перевірити результат (я згадав, що вам потрібен гарний тестовий набір для цього завдання)? Виправте всі помилки, виявлені тестом
  • тепер повторіть цей процес, щоб змінити основний рядок на 2 день, потім на 3 день тощо.

Це може спрацювати, коли команди суворо дотримуються класичних правил контролю версій ("виконувати лише компільовані, перевірені стани" та "перевіряти рано та часто").

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

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

Варто додати, що ви можете спробувати це також із переключеними сторонами - реінтегруючи зміни від вашої гілки невеликими порціями до основної лінії. Це може бути простішим, коли у вашій гілці розробників було значно менше змін, ніж на магістралі, або більшість змін відбулися в нових вихідних файлах, які наразі не входять до магістралі. Це можна побачити як "перенесення" функції від продукту A (гілка розробника) до дещо іншого продукту B (поточний стан стовбура). Але якщо більшість наскрізних реконструкцій було виконано на головній лінії, і вони впливають на ваш новий код (зіткнення злиття 6500, здається, є деяким свідченням цього), може бути простішим способом, який я описав спочатку.


9
Якщо ви продовжуєте розробку на магістралі під час реінтеграції, я пропоную вам спочатку розв'язати кінчик магістралі та розвиватись із цього. Інакше ви ефективно зливаєте минуле і майбутнє одночасно. Але я відкладаю Дока Брауна на будь-які перебіги простору та часу, природно.
radarbob

1
@radarbob: те, що ви пропонуєте, має сенс лише в тому випадку, якщо ОП інтегрується від "дев" до "магістралі", але не тоді, коли він вирішить об'єднатись від ствола до "розробника", як я це описав спочатку. Якщо ОП щодня переносить зміни зі стовбура у свою гілку розробників (починаючи зі змін 365 днів у минулому), не має значення, чи буде продовжуватися розвиток на магістралі. Йому просто доведеться продовжувати цю тактику, поки він не дійде до сьогодення (припускаючи, що він може інтегрувати та перевірити зміни цих 3-4 команд за один день менш ніж за один день).
Док Браун

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

Це хороша порада. Дивіться редагування, щоб вирішити кілька речей тут.
користувач258451

1
@ user258451: значить, у вас були різні команди QA для магістралі та нової гілки розробників, які не хотіли спілкуватися між собою? Великий Скотт: - ((
Док. Браун

14

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

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

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

Ключ - продовжувати йти.

Редагувати:

Слово попередження, такий підхід означатиме, що історія контролю версій стане «пошкодженою», оскільки ви втратите докази злиття між галузями, а також історію нерозподіленої гілки.

Завдяки коментарям від 'Jack Aidley' та '17 of 26 '


1
Основна проблема такого підходу полягає в тому, що він знищить запис змін, що залишилися в системі управління версіями.
Джек Едлі

По суті, вносячи всі ті самі зміни вдруге під час злиття, у вас все-таки буде журнал змін, це було б просто в порядку, виконаному в об'єднанні, замість того, як вони були виконані під час розробки. Не ідеально, але краще, ніж нічого. Плюс у вас все-таки залишився б оригінальний стан без навантаження, якби він зберігався в контролі версій.
Erdrik Ironrose

У вас був би журнал змін, але ви не мали б історичних доказів того, що зміни були об'єднані від гілки до гілки. Це було б величезною угодою у TFS, яка пропонує вам лише без наборів змін, на вибір, під час злиття від гілки до гілки.
17 з 26

@ 17of26 Хоча я погоджуюся, що ви можете відновити деякий запис змін, 17 з 26 правильно, що цей запис не буде повним чи точним. Можливо, такий підхід є досить простим, щоб зробити цю втрату запису прийнятним компромісом, враховуючи погану ситуацію, в якій вони зараз перебувають. Однак, я думаю, що це важливий недолік визнати незалежно від того, що вони вирішили.
Джек Едлі

1
@Jack Aidley Я, безумовно, погоджуюсь, що це досить проблема, тому я додав трохи до своєї відповіді, щоб задуматися. Я сподіваюся, що це добре?
Erdrik Ironrose

8

Кілька років тому у нас був клієнт з однаковими вимогами зберігати відділення. Так ми і зробили.

Ми ніколи не об'єднували їх гілки назад. У них була своя унікальна версія. Ми платили їм додатково за зміни, оскільки фактично у нас було два основні стовбури замість 1 головного стовбура та гілок.

Ми намагалися злитись назад до магістралі, але через 2 тижні ми вирішили відмовитися від цих зусиль, оскільки це горіло години, не маючи відчутних переваг.

Отже, не зливайте його назад. Попереднє об'єднання критичних виправлень до цього відділення клієнта за необхідності, а будь-які вдосконалення будуть спеціально стягнуті з цього клієнта.


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

1

Це не буде весело, але наскільки це буде боляче, залежить від характеру змін та наскільки вони відокремлені.

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

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

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

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

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