Що так важко у злиттях SVN?


28

Можливий дублікат:
Я підривник, чому я повинен вважати або не вважати Mercurial або Git чи будь-яким іншим DVCS?

Раз у раз ви чуєте, як хтось каже, що розподілений контроль над версіями (Git, HG) за своєю суттю кращий, ніж централізований контроль над версіями (як SVN), оскільки об’єднання у SVN є складним та болісним. Справа в тому, що я ніколи не мав жодних проблем зі злиттям у SVN, і оскільки ви коли-небудь чуєте про те, що претензії висувають захисники DVCS, а не фактичні користувачі SVN, це, як правило, нагадує мені про ті неприємні рекламні ролики на телебаченні, де вони спробуйте продати вам щось, що вам не потрібно, змусивши дрімаючих акторів робити вигляд, що те, що у вас вже є і працює добре, користуватися неймовірно складно.

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

Отож, дисконтуючи випадкові випадки використання смішного солом’яника, що тут є у злитті SVN, що по суті складніше, ніж об'єднання в систему DVCS?


6
Я ще не працюю в середовищі, коли у них є місячні гілки, які об'єднуються, і вони використовують розподілений контроль версій. Єдині місця, в яких я працював, робили такі довгоживучі гілки, використовували TFS / Subversion. Я очікую, що такі довгоживучі гілки було б важко об'єднати і з DVCS.
Oded

13
@MasonWheeler Я спантеличений. Тоді для чого ви використовуєте VCS? Я бачив і читав, що однією (із багатьох) рекомендованих практик є наявність гілок функцій. Злиття спини до багажника є обов'язковим у такому випадку. Або я щось неправильно зрозумів? (так, метафора дерева ламається, але починати з ІМО було не все корисно)
Андрес Ф.

9
@MasonWheeler: Я думаю, що ти сприймаєш аналогію дерева занадто буквально.
whatsisname


8
@MasonWheeler, скільки різних середовищ розробки у вас є досвід, якщо ви ніколи не чули про злиття спини до магістралі? У деяких магазинах є стабільні стовбури та експериментальні відділення, і в такому випадку збирання вишні з успішними ознаками повертається до стайні - це регулярний захід.
йогобрюс

Відповіді:


25

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

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


47

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

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

Ви кажете, що злиття гілок - «принципово неправильне і нерозумне». Ну, саме в цьому проблема: ви думаєте про гілки як про речі, які не слід об'єднувати. Чому? Тому що ви користувач SVN, який знає, що об’єднувати гілки важко . Тому ти ніколи цього не робиш, а ти заохочуєш інших не робити цього. Ви пройшли навчання, щоб уникнути злиття; Ви розробили методи, якими користуєтесь, щоб уникнути злиття.

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

Якби я використовував SVN, я прийняв би зовсім іншу структуру бази коду. Чому? Оскільки SVN робить злиття важкими, і тому ви розробляєте ідіоми та методи, щоб не робити складних зливань.

DVCS спрощує комплексні злиття, оскільки вони є станом за замовчуванням . Все - це галузь, більш-менш, в DVCS. Тому вся структура їх будується з нуля, щоб полегшити злиття. Це дозволяє розробити робочий процес, який використовує злиття щодня, а не SVN робочий процес, де ви ніколи не використовуєте злиття.

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

Правильний інструмент для правильної роботи.

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

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


15
@Mason: Як це не тренування? Вас навчали використовувати SVN у стилі SVN. І стиль SVN - не використовувати злиття. Таким чином, ви були навчені не використовувати або навіть розглянути речі, що об'єднуються. Ось чому вам ніколи не спадало на думку; тому що ви використовували систему, яка ускладнює.
Нікол Болас

5
Існує велика різниця між "не навченим" і "навченим не".
Мейсон Уілер

8
@MasonWheeler: Ні, немає. Якщо вас не правильно навчають, як щось робити, то ви неявно навчаєтеся цього не робити. Це не ваш репертуар ідіом, який ви можете використовувати для вирішення проблеми. Тому ви не можете використовувати його для вирішення проблем. Ефект нічим не відрізняється від того, щоб сказати не зливатися, адже навіть якщо ви цього хотіли, ви не знаєте як. Те, як ви безтурботно відкидаєте хороший аргумент як "той самий стомлений старий ґрунт", є свідченням цього. Ви не думаєте про злиття як інструмент; ви вважаєте це винятком або чимось незвичним. Щось потрібно сумніватися, а не використовувати.
Нікол Болас

9
@MasonWheeler: Хто ти, щоб вирішити " вони роблять неправильно "? Ви не використовуєте DVCS, тому у вас немає досвіду роботи з робочим процесом DVCS. Ви не маєте поняття, корисна вона програмістам чи ні, так як ви не маєте з цим досвіду. То який авторитет ви повинні сказати, що це "неправильно" лише тому, що SVN цього не дозволяє? Це як би сказати, що класи, віртуальні функції та шаблони неправильні, оскільки їх немає.
Нікол Болас

3
@MasonWheeler: як це? : P . Розгалуження та злиття SVN робить те саме - метафора вже порушена. Я насправді не бачу, як щось подібне - це важко зрозуміти, особливо якщо воно включає в себе якісь обґрунтовані коментарі до вчинення ..
naught101

21

У злитті SVN немає нічого надто складного ... більше ... якщо слідувати правильній філософії

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

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

Хоча я досить добре знав SVN, а тим часом пробував Mercurial для особистих проектів, тим часом я ніколи не робив багато розгалужень у SVN перед цим проектом. Було досить багато спроб і помилок, і у мене виникло багато несподіваних конфліктів злиття, коли я починав.

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

Ось речі, які я помітив, - це настійні рекомендації, якщо не вимоги, щодо чистого використання злиття:

  • Використовуйте останню версію SVN (на мою думку 1.6 і вище). Все більше і більше автоматизації та перевірок робиться для вас.
  • Використовуйте структуру "стовбур, гілки, теги" за замовчуванням і застосуйте її філософію (не зобов'язуйтесь до тегів). SVN нічого для вас не перевірить. Якщо ви використовуєте тег як гілку (саме такий стан я знайшов у сховищі проектів), він все ще може працювати, але вам потрібно бути послідовним.
  • Знайте, що таке гілки та коли їх створити. Те саме з тегами.
  • Слідкуйте за тим, щоб бічні гілки були в курсі останніх гілок (зазвичай стовбур, але ви можете гілками з будь-якої гілки технічно). Це обов'язково, якщо ви хочете, щоб SVN робив автоматичні злиття. SVN 1.8 насправді перешкоджає автоматичному злиттю, якщо речі не оновлюються, а також якщо ви маєте зміни в робочій копії (ця поведінка, схоже, знову зникла в 1.8.5).
  • Робіть "належні" вчинки. Вони повинні містити лише модифікації щодо дуже конкретної концепції. Наскільки це можливо, вони повинні містити невелику кількість змін. Ви не хочете, щоб одна комісія містила зміни, наприклад, про дві незалежні помилки. Якщо ви вже виправили обидва, і вони знаходяться в одному файлі, вам слід зберегти зміни однієї помилки, щоб ви могли здійснити лише зміни другого першого, а потім здійснити другий набір змін. Зверніть увагу, що TortoiseSVN дозволяє це легко через "Відновити після фіксації".
    • Це дає можливість повернути певний незалежний набір змін І дає змогу лише об'єднати такий набір в іншу гілку. Так, SVN дозволяє об'єднати вишневі версії.
  • Якщо ви коли-небудь використовуєте підгалузі (відгалужуючи стовбур, то відгалужуючи цю нову гілку), дотримуйтесь ієрархію. Якщо ви оновлюєте підгалузь із стовбуром або навпаки, ви відчуваєте біль. Злиття повинні бути каскадно вниз або вгору за ієрархією.
    • Після кількох місяців експериментів я можу поручитися, що це може бути найважливіша частина. Спробували створити дві підгалузі з одного стовбура, а потім об'єднати біти між підгалузями або іноді між підгалузями з будь-якої сторони. Це може вимкнути SVN (або користувача). Це може спрацювати нормально, якщо ви об'єднуєте конкретні зміни. Автоматичне злиття може мати проблеми з цим.
    • У мене виникли проблеми, зокрема, коли синхронізували підгалузь A з магістраллю, а потім намагалися об'єднати щось із підрозділу А в підгалузь B. SVN, здається, вважає, що перегляд "синхронізувати з магістралі" слід законно об'єднати в підгалузь. Б і це призводить до маси конфліктів.
  • Максимально зливайтеся з кореня гілки. В іншому випадку, SVN буде тримати тільки слід в злиттях зроблено для папки і коли ви робите спробу до Автоустановка від кореня, ви можете отримати попередження про відсутність неслітих змін. Це можна виправити, просто об'єднавши їх із коренем, але найкраще уникати плутанини.
  • Будьте уважні, в якій галузі ви берете на себе зобов’язання. Якщо ви використовуєте Switch, щоб через час ваша робоча копія вказувала на різні відділення, будьте впевнені, куди ви збираєтеся.
    • Особливо погано, якщо ви дійсно не хотіли змін у цій галузі. Мені все ще незрозуміло, але залежно від того, як ви його позбудетесь / перенесите у потрібну гілку (повернення, злиття), ви можете отримати щось безладне. Це можна виправити, але вам доведеться або злити ревізію шляхом перегляду, щоб уникнути або негайно вирішити потенційні конфлікти, або вам доведеться виправити можливий складніший конфлікт після автоматичного злиття.
  • Не тримайте гілки недоторканими занадто довго. Насправді справа не в часі, а в тому, скільки ревізій було здійснено для гілки та стовбура та скільки змінилося в них. Злиття між двома гілками, тристоронні злиття, завжди порівнюються з останніми загальними переглядами між гілками. Чим більше змін між ними, тим більше змін буде автоматичним злиттям. Це, звичайно, набагато гірше, якщо ви тим часом змінили структуру свого коду (перемістили або перейменували файли).

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

О, ще одна річ, що стосується об'єднання, де з усього, що я читав і намагався, SVN справді смокче: видалені / переміщені / перейменовані файли / папки. Мабуть , SVN все ще не може мати справу з перейменованим, видаленим або переміщеним файлом в одній гілці, а його оригінальну версію змінено в іншій гілці ... і потім об'єднати їх разом. Він просто не знатиме, куди пішов файл в один бік, і "забуде" зміни в інший бік. Одне зміна, очевидно, нерозв’язане (ви видаляєте або змінюєте файл, не можете зробити і те й інше), але застосування змін до переміщених / перейменованих файлів має працювати, і це не відбувається. Сподіваємось, це скоро виправиться.

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

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


Конфлікти з деревами - так, SVN має труднощі з цим, хоча TBH так робить і кожен інший СКМ. У Git є якась евристика, щоб спробувати зрозуміти, чи перейменовані або переміщені файли однакові, але це не завжди (не може!) Завжди це правильно. Я думаю, що SVN повинен докласти певних зусиль, щоб вирішити ці конфлікти легше зрозуміти.
gbjbaanb

@gbjbaanb: Він пропонує "Ремонт руху", як це робить Mercurial, хоча він не пропонує евристики. Вам потрібно сказати, які видалені та додані файли насправді однакові. Однозначно місце для вдосконалення.
leokhorn

Все це чудово звучить, коли ви єдина людина, яка працює над проектом ... Але якщо у вас є хороша команда за розмірами, і вони всі використовують її, "SVN шлях" (який, здається, ніхто не погоджується з тим, що це таке) зливається все ще є ПДФА. Справа в тому, що svn насправді не так добре підтримує розгалужений робочий процес. "Шлях SVN" був би навіть не створювати гілки та використовувати SDLC водоспаду. Враховуючи це, у мене були проблеми з об'єднанням Git у минулому щодо великих проектів, де кілька людей працювали над ним. Але, здавалося, вони все ще були набагато менш болісними.
ryoung

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

5

Внутрішні моделі даних принципово відрізняються.

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

У перших версіях SVN, якщо вам довелося ще раз об'єднати гілку Bв гілку A, вам довелося вручну вказати, який діапазон редагування гілки Bви хочете об'єднати, щоб уникнути об'єднання одних і тих же ревізій двічі. Розумний розробник звичайно використовує повідомлення про фіксацію типу "Об'єднано в B: 1234".

SVN 1.5 "зафіксував" це. Але це не змінило того, як принципово застосовуються злиття. Це просто додало кілька додаткових метаданих до гілки A, даючи SVN знати, що редакція 1234 була об'єднана, що дозволяє SVN автоматично вибирати правильний діапазон редагування.

Але це рішення є принциповим рішенням для моделі даних, яка принципово не підтримує відстежувати об'єднане.

Об’єднання двох гілок - порівняно простий приклад. Але уявити цей складніший сценарій

  1. Створіть відділення Aз trunkі зробіть тут кілька комісій
  2. Створіть відділення Bз Aі зробіть тут кілька комісій
  3. Зробіть кілька комісій у trunkтаA
  4. Об'єднайтесь Bуtrunk
  5. Об'єднайтесь AуB
  6. Об'єднайтесь Aуtrunk
  7. Об'єднайтесь Bу trunk(це насправді нічого не повинно робити)

Правильне поводження з цим за допомогою моделі метаданих стає надзвичайно складним (я не знаю, чи SVN справді справляється з цим сценарієм правильно, і я не схильний перевірити його).

Поводження з цим сценарієм в git надзвичайно просте.

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

Тому, коли ви вивчаєте історію одного комітету в git, ви можете бачити всю історію, ви можете бачити, коли вона була розгалужена, коли вона була об'єднана, і ви можете бачити історію обох гілок між розгалуженням і злиттям.

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

Я не маю досвіду роботи з Mercurial, але я підозрюю, що його внутрішня робота схожа на git.

Тож принципово для SVN це було дизайнерською метою зробити розгалуження дешевим. Але в git це було дизайнерською метою зробити злиття дешевим.

Нарешті, востаннє, коли я використовував SVN, він не зміг обробити злиття, де файл був перейменований в одну гілку та змінено в іншу.


1

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


Екстраполяція на предмет повільного з'єднання, робота з віддаленого сервера на зовнішньому веб-сайті створює і помилкові помилки підключення під час великих оновлень> <Не весело взагалі.
jxramos

-1

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

Тут лежить одна з дуже приємних речей про git. Це не успадковується про DVCS, це лише щось, що git перевершує. Ви можете об'єднати конкретні зміни з будь-якої гілки в іншу гілку. По суті, він просто приймає diff і застосовує його до іншої гілки, але робить відстеження і набагато більш автоматичним.

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

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


Крім того, я б міг уявити, що mercurial має подібну функціональність
Earlz

2
Власне, у SVN ви можете зробити те саме. Я роблю це постійно. Команда SVN Merge може витягнути ревізію (або діапазон версій) з іншої гілки та застосувати її до вашої робочої копії, а потім ви виконаєте її.
Мейсон Уілер

2
@MasonWheeler Майте на увазі, що багато настроїв анти-svn було спрямовано до версій до 1.5 (коли svn отримало відстеження злиття). І звичайно багато з цього просто безглуздий фанбоїзм ...
yannis

3
@MasonWheeler Дивись також stackoverflow.com/a/4215199/69742 Це повідомлення зводиться до DVCS відстежує зміни наборів НЕ версії . Набори змін за своєю суттю легкі для
збору

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