З мого розуміння, SVN - це «Легко відділитись». Важко злитися '. Чому так? Чи є різниця, як вони зливаються?
З мого розуміння, SVN - це «Легко відділитись». Важко злитися '. Чому так? Чи є різниця, як вони зливаються?
Відповіді:
Будь ласка, дивіться моєї відповіді на переповнення стека щодо дуже конкретної ситуації, коли Mercurial (і Git) зливаються без проблем і де Subversion представляє вам нерівний конфлікт. Ситуація - це простий рефакторинг, зроблений на гілці, де ви перейменовуєте деякі файли.
Що стосується відповіді тадмерів, то тут є низка непорозумінь:
Знімки, що належать до Subversion, Mercurial та Git, усіма треками, схожими на сховища проекту. Називання їх версій , редакцій чи наборів змін не має ніякого значення. Всі вони є логічно атомними знімками набору файлів.
Розмір ваших комісій не має значення, коли мова йде про об'єднання. Усі три системи зливаються зі стандартним алгоритмом тристороннього злиття, і вхід до цього алгоритму є
Не має значення, як були створені дві версії. Ви можете використати 1000 невеликих комітетів з моменту версії предків, або ви можете використати 1 фіксацію. Важливо лише остання версія файлів. (Так, це дивно! Так, багато посібників DVCS мають це жахливо неправильно.)
Він також підкреслює деякі хороші моменти щодо відмінностей:
Subversion має деякі «вуду» , де ви можете об'єднати з /trunk
, скажімо, на /branches/foo
. Mercurial і Git не використовують цю модель - натомість гілки моделюються безпосередньо в історії. Отже історія стає спрямованим ациклічним графіком, а не лінійним. Це набагато простіша модель, ніж та, яку використовує Subversion, і це відрізає ряд кутових випадків.
Ви можете легко затримати злиття або навіть дозволити комусь іншому впоратися. Якщо у hg merge
вас виникає багато конфліктів, ви можете попросити свого колегу hg pull
від вас, і тоді він має такий самий стан. Тож він може hg merge
і, можливо, він краще вирішує конфлікти, ніж ти.
Це дуже складно з Subversion, коли вам потрібно буде оновити, перш ніж ви зможете зробити це. Ви не можете просто ігнорувати зміни на сервері та продовжувати здійснювати свої власні анонімні відділення. Взагалі Subversion змушує вас грати з брудною робочою копією, коли ви svn update
. Це щось ризиковано, оскільки ви не зберігали свої зміни в безпечному місці. Git і Mercurial дозволяє спочатку здійснити виконання, а потім оновити та об'єднати за необхідності.
Справжня причина, по якій Git і Mercurial є кращими для злиття, ніж Subversion - це питання реалізації. Існують конфлікти з перейменовуванням, які Subversion просто не може впоратися, навіть думаючи, що зрозуміло, що правильна відповідь. Mercurial і Git справляються з ними легко. Але немає ніяких причин, чому Subversion не впорається з ними, а централізація - це точно не причина.
trunk
в SVN. За допомогою DVCS ви можете скористатися без спільного використання, але в SVN ваша svn commit
воля безпосередньо вплине на інших, хто працює в одній галузі. Навіть якщо ми вдвох працюємо у філії в SVN, я не можу зробити свою роботу без негайного злиття з вашою роботою. Це робить вчинки дещо страшними - що є страшною властивістю для системи управління версіями! :-)
Основна проблема полягає в тому, що ці системи представляють структуру версій каталогів.
Основна концепція Subversion, навколо якої обертається вся система, - це версія (або, у svn lingo, "перегляд"): знімок файлу в певний момент. Поки історія ідеально лінійна, все добре, але якщо вам потрібно об'єднати зміни з двох незалежних ліній розробки, svn повинен порівняти поточні версії обох, а потім зробити тристоронне порівняння між останньою спільною версією і дві головні версії. Рядки, які з’являються зміненими в одній із голов, а не в іншій, легко вирішити; лінії, які точно однаково відхиляються в обох головах, складніші, але зазвичай виконані; рядки, що відхиляються по-різному, - це те, що змушує svn сказати: "Я не можу цього зрозуміти, людино, будь ласка, виріши це для мене".
На відміну від цього мерзотника і ртутних трекових ревізіями , а не версії. Весь сховище - це дерево наборів змін, кожне з яких залежить від батьків, де батьківський набір змін може мати будь-яку кількість дітей, а корінь дерева представляє порожній каталог. Іншими словами, git / hg говорить "спочатку у мене нічого не було, потім цей патч застосований, потім той патч тощо". Коли вам потрібно об'єднати дві лінії розвитку, git / hg не тільки знає, як виглядає кожна голова в даний момент, і як виглядала остання поширена версія, вона також знає, як відбувся перехід, що дозволяє набагато розумніше об'єднатись.
Інша річ, яка полегшує злиття в DVCS - це опосередкований наслідок розділення понять " фіксація" та " push", а також дозволяти в будь-який час будь-які перехресні злиття між будь-якими двома клонами одного і того ж сховища. За допомогою svn люди, як правило, здійснюють великі набори змін із часто незв'язаними змінами, оскільки фіксація - це також оновлення центрального сховища, яке впливає на всіх інших членів команди; якщо ви скоїте ламану версію, всі будуть гніватися на вас. Оскільки більшість налаштувань передбачає мережевий сервер svn, виконування також передбачає перекачування даних по мережі, а це означає, що вчинення призводить до значної затримки робочого процесу (особливо коли ваша робоча копія застаріла і вам доведеться витягнути спочатку). За допомогою git та mercurial, фіксація відбувається локально, і оскільки обидві дуже ефективні в роботі з локальними файловими системами, вони зазвичай закінчуються миттєво. Як результат, люди (коли вони звикають) здійснюють невеликі додаткові зміни, а потім, коли це працює, натиснути дюжину або близько цього здійснює за один рух. Тоді, коли настає час злиття, СКМ має набагато більш детальну інформацію, яка може пройти, і може зробити кращу роботу щодо вирішення конфліктів безпечно та автоматично.
А потім є приємні деталі, які роблять речі ще простішими:
hg mv
або hg addremove --similarity...
), тоді як Git використовує евристичні, але обидва обробляють переймена . Я можу отримати конфлікт із деревами навіть з різницею 1 рядка в об'єднаних файлах! Ви повинні знову вивчити деякі аспекти Subversion, вибачте.
rename a b
як copy a b; remove a
і обидві роблять це за один атомний запис. Різниця в поведінці злиття випливає з різного поводження з кутовими справами і від Subversion, що дозволяє більше злиття, ніж Mercurial і Git. Нарешті, Git виявляє перейменування під час злиття та журналу - ми також думаємо додати це в Mercurial.