Чому розгалуження та злиття простіше у Mercurial, ніж у Subversion?


92

Обробка кількох злиттів на гілках у Subversion або CVS - це лише одна з тих речей, яку потрібно випробувати. Надзвичайно простіше відстежувати гілки та злиття в Mercurial (і, можливо, будь-якій іншій розподіленій системі), але я не знаю чому. Хтось ще знає?

Моє запитання випливає з того, що з Mercurial ви можете застосувати робочу практику, подібну до практики центрального сховища Subversions / CVS, і все буде працювати нормально. Ви можете зробити кілька об’єднань на одній гілці, і вам не знадобляться нескінченні клаптики паперу з номерами комітів та іменами тегів.

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

У тому, як це все працює, має бути принципова різниця.

Відповіді:


115

У Subversion (і CVS) сховище - це перш за все. У git та mercurial насправді не існує поняття сховища однаково; тут зміни є центральною темою.

+1

Хлопоти в CVS / SVN походять від того, що ці системи не пам’ятають батьківство змін. У Git та Mercurial не тільки коміт може мати декількох дітей, але й кілька батьків!

Це можна легко спостерігати за допомогою одного з графічних інструментів, gitkабо hg view. У наступному прикладі гілка №2 була розгалужена від # 1 при коміті A, і з тих пір була об’єднана один раз (у M, об’єднана з комітом B):

o---A---o---B---o---C         (branch #1)
     \       \
      o---o---M---X---?       (branch #2)

Зверніть увагу, як у А та В двоє дітей, тоді як у М - двоє батьків . Ці відносини реєструються у сховищі. Скажімо, супровідник гілки №2 тепер хоче об’єднати останні зміни з гілки №1, він може виконати таку команду, як:

$ git merge branch-1

і інструмент автоматично дізнається, що базою є B - оскільки це було записано в коміті M, предком кінчика №2 - і що він повинен об'єднати все, що сталося між B і C. CVS не записує цю інформацію , а також SVN до версії 1.5. У цих системах графік буде виглядати так:

o---A---o---B---o---C         (branch #1)
     \    
      o---o---M---X---?       (branch #2)

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

Що ще гірше, виконуючи другу злиття перетворюється в кошмар: один повинен з'ясувати , що злиття база була в момент першого злиття (і один має в знати , що відбулося злиття в першу чергу!), То уявіть , що інформацію до інструменту, щоб він не намагався відтворити A..B поверх M. Усе це досить складно при роботі в тісній співпраці, але просто неможливо в розподіленому середовищі.

(Пов’язана) проблема полягає в тому, що немає можливості відповісти на питання: "чи X містить B?" де B - потенційно важливе виправлення помилки. То чому б просто не записати цю інформацію у коміті, адже вона відома під час злиття!

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


6
SVN 1.5+ дійсно містив би властивість SVN у коміті злиття M із переліком об’єднаних комітів, які він містить, іншими словами AB. Отже, у вас однакова інформація.
Саймон Д

Типу. Технічно, відстеження злиття SVN є подібним до того, що Git називає "збиранням вишні", з додатковою магією, щоб полегшити користувачеві; воно семантично відрізняється від того, що роблять Git, Hg та Bzr при злитті. Думаю, це не сильно впливає на практику, поки ви не дбаєте про DAG ( eagain.net/articles/git-for-computer-scientists ).
Damien Diederen

2
Горе, що немає кнопки +100. Дякую.
Charlie Flowers

Я припускаю, що функція SVN 1.5, про яку ви говорите, полягає у використанні svn:mergeinfoвластивості?
MatrixFrog

@MatrixFrog: Так, це саме те, що svn:mergeinfoробить.
sleske

12

Оскільки Subversion (принаймні, версія 1.4 та старіші) не відстежує об’єднане. Для Subversion злиття в основному те саме, що будь-який коміт, тоді як на інших версіях управління, таких як Git, пам'ятаються всі об'єднані.


7

Не зворушений жодною з уже наданих відповідей, Hg запропонував чудові можливості злиття, оскільки використовує більше інформації при об’єднанні змін ( hginit.com ):

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

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

Обидва вдосконалення, однак, сумнівні, оскільки subversion 1.5+ зберігає додаткову інформацію про злиття у вигляді властивостей subversion: ця інформація доступна, немає очевидної причини, чому злиття subversion не могло реалізувати злиття так успішно, як Hg або Git. Хоча я не знаю, чи так, але це, звичайно, схоже на те, що розробники диверсій збираються обійти цю проблему.


4

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


3

У Subversion (і CVS) сховище - це перш за все. У git та mercurial насправді не існує поняття сховища однаково; тут зміни є центральною темою.

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


1

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

Якщо Mercurial може спростити конфігурацію злиття, то я можу сказати, що це зробило б злиття на 100% простішим, ніж Subversion.

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