Підтримуйте сотні спеціалізованих гілок над головною гілкою


140

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

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

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

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


11
Вибачте, що не давали відповіді "ви можете використовувати інструмент X", але такої немає.
Гонки легкості по орбіті

3
Або під час збирання (що, мабуть, частіше). Просто .. не зовсім окремо кодові бази.
Гонки легкості по орбіті

15
@FernandoTan - Ваш видимий симптом може бути кодом, але першопричиною вашої хвороби є фрагментація продукту. Лікування повинно випливати з картографічного фокусування продукту / можливості продукту, а не очищення коду - це згодом станеться. Я детальніше розповів у своїй відповіді - programmers.stackexchange.com/a/302193/78582
Alex S

8
Це також може бути економічною проблемою. Ви справді заробляєте гроші на всіх цих 500 клієнтів? Якщо ні, то вам не доведеться переосмислити свою модель ціноутворення та відхилити запити на зміни, якщо клієнт не заплатить додаткову плату.
Крістіан Стремпфер

13
Це зробило моє серце просто маленьким шматочком. На щастя, інші вже кричать правильні відповіді - моя єдина додаткова рекомендація - ви напишіть це та подайте до TheDailyWTF.
zxq9

Відповіді:


314

Ви повністю зловживаєте гілками! У вас повинна бути налаштована гнучкість у вашому додатку, а не гнучкість у керуванні вашими версіями (яка, як ви виявили, не призначена / не призначена для такого типу використання).

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

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

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


142
+1 для "Ви повинні були зробити це з самого початку". Цей рівень технічної заборгованості може знищити компанію.
Daenyth

31
@Daenyth: Відверто кажучи, п'ять сотень спеціальних гілок я вражений, що цього ще не зробив. Хто дозволяє речі так погано? lol
Гонки легкості в орбіті

73
@FernandoTan Я так, так, так шкода вам ...
enderland

20
@FernandoTan: Я теж. :( Можливо, ви мали б задати більше питань на співбесіді?;) Щоб було зрозуміло, "ви" у моїй відповіді - це організація. Це абстракція. Я не прагну доручити вину особам.
Гонки легкості по орбіті

58
Спочатку отримайте більше розуміння. Нехай розробники роблять різницю між поточною версією та спеціалізованою гілкою. Так ви принаймні знаєте, які існують відмінності. Цей список дозволяє вам побачити, де ви можете виграти якнайшвидше скорочення гілок. Якщо 50 мають власні імена полів, просто зосередьтеся на цьому, і це заощадить 50 гілок. Тоді шукайте наступну. Можливо, ви також матимете такі, які не підлягають відновленню, але тоді принаймні сума буде меншою, і вона не зростатиме далі, коли ви отримаєте більше клієнтів.
Люк Франкен

93

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

По-перше, я сподіваюся, що ви стягуєте своїх клієнтів достатньо, щоб покрити ВСІ витрати на підтримку їхніх користувацьких версій. Я припускаю, що клієнти розраховують отримати нові версії, не платячи за їх налаштування, щоб зробити це знову. Я б почав з пошуку всіх однакових файлів у 95% ваших відділень. Ці 95% є стабільною частиною вашої заявки.

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

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

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

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

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

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


На основі коментаря br3w5:

  • Ви можете взяти кожен клас, який відрізняється між клієнтами
  • Складіть “xxx_baseclass”, який визначає всі методи, які викликаються в класі поза його межами
  • Перейменуйте клас так, щоб xxx називався xxx_clientName (як підклас xxx_baseclass)
  • Використовуйте введення залежності, щоб правильна версія класу була використана для кожного клієнта
  • А тепер для розумного розуміння придумали br3w5! Використовуйте інструмент аналізу статичного коду, щоб знайти дублюваний код і перемістити його в базовий клас тощо

Робіть вищезазначене лише після того, як ви отримаєте легке зерно, і спочатку простежте його кількома класами.


28
+1 за спробу запропонувати підхід до реальної проблеми
Ян

35
Я дуже хвилювався, що ви вітаєте себе зі своєю відповіддю, поки я не зрозумів, що ви не той самий @Ian, який написав відповідь.
Терон Лун

2
Можливо, вони повинні використовувати інструмент аналізу статичного коду, щоб звузити, які частини коду дублюються (після виявлення всіх однакових файлів)
br3w5

1
Також створюємо пакунки з версією, щоб допомогти команді відслідковувати, який клієнт має, яка версія коду
br3w5

1
Це звучить як довгий звивистий вислів "просто рефактор вашого коду"
Roland Tepp

40

Надалі задайте тестові запитання Джоела у своєму інтерв'ю. Ви з більшою ймовірністю не будете заїжджати на користь поїзда.


Це, а, як сказати ... насправді, дуже погана проблема. "Процентна ставка" за цим технічним боргом буде дуже-дуже високою. Це не може бути відновлено ...

Наскільки інтегровані з "ядром" ці користувацькі зміни? Чи можете ви зробити їх власною бібліотекою і мати єдине "ядро", а кожен конкретний клієнт має власне "доповнення?"

Або це все дуже незначні конфігурації?

Я думаю, що рішення - це поєднання:

  • Зміна всіх твердо кодованих змін на елементи конфігурації. У цьому випадку у всіх є однакова основна програма, але користувачі (або ви) включають / вимикають функціональність, встановлюють назви тощо за потребою
  • Переміщення функціональних можливостей / модулів, орієнтованих на клієнта, для розділення проектів, тому замість одного "проекту" у вас є один "основний проект" з модулями, який ви можете легко додавати / видаляти. Ви також можете зробити ці параметри конфігурації.

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

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

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


1
Крім того, оскільки це буде величезним завданням (якщо не менше), це буде серйозним завданням навіть переконати ваших менеджерів кинути велику кількість часу і грошей на цю проблему. @FernandoTan На цьому сайті можуть бути питання + відповіді, які можуть допомогти у вирішенні цього питання.
Radu Murzea

10
Яке питання тесту Джоела сказало б вам, що компанія зловживає філіями?
SpaceTrucker

2
@SpaceTrucker: Ну, "Ви робите щоденні побудови?" можливо, допомогло б. Маючи 500 гілок, вони, мабуть, їх не мали, або, можливо, згадували, що вони роблять це лише для деяких гілок.
sleske

17

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

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

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


3
Якщо ви це зробите, зробіть собі прихильність і постарайтеся максимально використовувати шаблон Стратегії . Це значно полегшить підтримання коду, ніж якщо ви просто робите в if(getFeature(FEATURE_X).isEnabled())усьому світі.
TMN

13

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

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

Тоді різні налаштування для клієнтів можуть або просто розрізняти один одного за допомогою зовнішньо налаштованого стану (наприклад, бази даних), або, якщо необхідно, жити як окремі сховища, які додають ядро ​​як підмодуль.


6
Ви забули про відділення технічного обслуговування, які в основному протилежні гілкам, які ви описали у своїй відповіді. :)
Гонки легкості по орбіті

7

Усі важливі речі були запропоновані хорошими відповідями тут. Я хотів би додати свої п’ять пенсів як пропозицію щодо процесу.

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

Що означає:

  1. Уточнити обов'язки щодо управління змінами: якщо клієнту потрібні певні адаптації, хто їх продає, хто дозволяє та хто вирішує, як змінити код? Куди потрібно закрутити гвинти, якщо деякі речі потрібно змінити?
  2. Уточнюйте роль, хто у вашій команді має право робити нові репости, а хто ні.
  3. Постарайтеся переконатися, що всі члени вашої команди бачать необхідність моделей, що дозволяють гнучкості до програмного забезпечення.
  4. Уточнити свій інструмент управління: як швидко дізнатися, який клієнт має, який код прийняв. Я знаю, якийсь "список із 500" звучить прикро, але ось "емоційна економія", якщо ви хочете. Якщо ви не можете швидко повідомити про зміни клієнта, ви відчуваєте себе ще більше втраченим і тягнеться так, ніби вам доведеться починати список. Потім скористайтеся цим списком, щоб згрупувати функції, як показали вам відповіді інших людей:
    • групувати клієнтів шляхом незначних / великих змін
    • групувати за тематичними змінами
    • групувати за змінами легко злиття та зміни, які важко об'єднати
    • знайти групи рівних змін, внесених до декількох репостів (о так, їх буде кілька).
    • можливо, найголовніше для того, щоб поговорити з вашим менеджером / інвестором: згрупуйте дорогі зміни та дешеві зміни.

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

Потім спробуйте встановити вікно тривалого часу, де ви готуєте цю річ на маленькому вогні. Пропозиція: спробуйте злити щонайменше два репости та видалити принаймні одну . Ви можете дізнатися, що часто ви можете об'єднати більше двох гілок, коли у вас є рутина і нагляд. Таким чином, за один рік ви можете вирішити найгірші (найдорожчі?) Гілки, а через два роки ви можете зменшити цю проблему, щоб мати явно краще програмне забезпечення. Але не чекайте більше, адже врешті-решт ніхто не «встигне» на це, але ви такий, хто більше не дозволить цього, оскільки ви архітектор програмного забезпечення.

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


2
Гарні моменти щодо вирішення соціальних / організаційних питань, що стоять за технічними проблемами. Це занадто часто не помічається.
sleske

5

Протиставляючи всіх наймовців, припустимо, реальна потреба в бізнесі.

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

Крім того, припустимо, що у вашої компанії є інструменти для підтримки всіх галузей, тобто чисельність персоналу (скажімо, 100 розробників, присвячених об'єднанню, припускаючи 5-денну затримку випуску; або 10 розробок, за умови, що 50-денний затримка випуску нормальна), або таке дивовижне автоматизоване тестування, що автоматичні злиття справді випробовуються як до основних специфікацій, так і до специфікацій розширень у кожній галузі, і, отже, лише зміни, які не зливаються «чисто», вимагають втручання людини. Якщо ваші клієнти платять не тільки за налаштування, але за їх обслуговування, це може бути дійсною діловою моделлю.

Моє (і най-кажуть) питання: чи є у вас віддана особа, відповідальна за доставку до кожного замовника? Якщо ви, скажімо, компанія з 10 000 осіб, це може бути так.

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

Плагіни можуть бути завантажені під час виконання або вбудовані під час компіляції.

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

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

В ідеалі це вирішуватиметься орієнтоване на аспекти програмування , де магістраль - це основний код, а гілки - це аспекти (тобто додатковий код та інструкції, як підключити додатки до ядра)

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

Для цього є маса бібліотек, однак проблема конфліктів злиття не минає - чисті злиття вирішуються АОП, і конфлікти все ще потребують втручання людини.

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


3

Ви не вирішуєте першопричину захворювання, дивлячись на симптом. Використання підходу «управління кодом» є симптоматичним, але не вирішить вас надовго. Першопричиною є відсутність "добре керованих" можливостей продукту, особливостей та їх розширень та варіацій.

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

Наскільки широкі користувацькі функції, наскільки різні, як контекстуально схожі чи ні, будуть грати багато в «оздоровлення» кодової бази вашого продукту.

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

Тому що, нарешті, код - це не що інше, як пропонування ділових та товарних функцій / послуг своїм клієнтам. Саме це і отримує вашу компанію.

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

Ви, ваша компанія та продукт не може бути усім для всіх. Тепер, коли у вас є пристойна база доходу в 500 клієнтів, настав час продукувати, яким ви маєте бути.

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

Наскільки широкими та глибокими будуть ваші продукти? Інакше це призведе до питань якості обслуговування та «розбавлення та роздроблення продукту», коли ви йдете вниз.

Чи будете ви CRM чи ERP чи замовите обробку / відправлення або Microsoft Excel?

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

Вам потрібно буде мати чітке управління продуктом та архітектурою даних :

  • Основна галузь, її продуктові можливості та база даних
  • Особливості, типи та варіанти розширення
  • Значення та варіація "користувацьких полів"

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

PS: Зв'яжіться зі мною, я знаю людину, яка може допомогти вам це виправити :)


-5

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

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

Я особисто імпортував сховище з GitHub з 40 гілками до Bitbucket і створив 40 сховищ. Минуло лише чотири години. Це були варіанти WordPress, тому натискання та перетягування було швидким.

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


16
Як би кілька сховищ спростили обслуговування?
Математика

У деяких випадках, таких як наш, клієнти повинні мати доступ до кожного репо і керувати своїми проблемами, коли це стає індивідуальним рішенням, щоб у них було власне репо, що полегшує управління, і, як я сказав, це варіації теми Wordpress, це добре працювало. Це може не спрацювати у багатьох випадках.
Фаррух Субхані
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.