Насколько я понимаю, SVN «Легко разветвляться. Сложно объединить ». Это почему? Есть ли разница, как они сливаются?
Насколько я понимаю, SVN «Легко разветвляться. Сложно объединить ». Это почему? Есть ли разница, как они сливаются?
Ответы:
Пожалуйста, смотрите мой ответ Переполнение стека для очень конкретной ситуации, когда Mercurial (и Git) сливается без проблем, и где Subversion представляет вам фиктивный конфликт. Ситуация - это простой рефакторинг, выполняемый в ветке, где вы переименовываете некоторые файлы.
Что касается ответа tdammers, то здесь есть ряд недоразумений:
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, «revision»): снимок файла в определенной точке. Пока история совершенно линейна, все в порядке, но если вам нужно объединить изменения из двух независимых линий разработки, svn должен сравнить текущие версии обеих версий, а затем провести трехстороннее сравнение между последней общей версией и две версии головы. Линии, которые кажутся измененными в одной из голов, но не в другой, могут быть легко решены; линии, которые одинаково отклоняются в обеих головках, более жесткие, но обычно выполнимые; линии, которые отличаются по-разному, заставляют svn сказать: «Я не могу понять это, человек, пожалуйста, разреши это для меня».
Напротив, git и mercurial отслеживают изменения, а не версии. Весь репозиторий представляет собой дерево наборов изменений, каждое из которых зависит от родителя, где родительский набор изменений может иметь любое количество дочерних элементов, а корень дерева представляет собой пустой каталог. Другими словами, git / hg говорит: «сначала у меня ничего не было, затем был применен этот патч, затем этот патч и т. Д.». Когда вам нужно объединить две линии разработки, git / hg не только знает, как выглядит каждая голова в данный момент и как выглядела последняя распространенная версия, но и знает, как произошел переход, что позволяет осуществлять более умное слияние.
Еще одна вещь, которая облегчает объединение в DVCS, является косвенным следствием разделения концепций коммита и толчкаи разрешать всевозможные перекрестные слияния между любыми двумя клонами одного и того же хранилища в любое время. С svn люди, как правило, фиксируют большие наборы изменений с часто не связанными изменениями, потому что фиксация также является обновлением в центральном хранилище, которое затрагивает всех остальных членов команды; если вы совершите испорченную версию, все будут сердиться на вас. Поскольку в большинстве установок используется сетевой svn-сервер, фиксация также включает в себя перекачку данных по сети, что означает, что фиксация вносит значительную задержку в рабочий процесс (особенно, когда ваша рабочая копия устарела, и вы должны сначала извлечь). В git и mercurial фиксация происходит локально, и поскольку обе они очень эффективны при работе с локальными файловыми системами, обычно они завершаются мгновенно. В результате люди (как только они привыкнут к этому) совершают небольшие постепенные изменения, а затем, когда это работает, толкать дюжину или около того совершает за один раз. Затем, когда наступит время слияния, SCM будет иметь гораздо более подробную информацию и сможет лучше и эффективнее решать конфликты безопасно и автоматически.
И еще есть приятные детали, которые делают вещи еще проще:
hg mv
или hg addremove --similarity...
), в то время как Git использует эвристику, но обе обрабатывают переименования . Я могу получить конфликт дерева даже с разницей в 1 строку в объединенных файлах! Вы должны заново изучить некоторые аспекты Subversion, извините.
rename a b
как copy a b; remove a
и обе делают это за один атомный коммит. Различие в поведении слияния связано с различной обработкой угловых случаев и с Subversion, допускающим больше слияний, чем Mercurial и Git. Наконец, Git обнаруживает переименования во время слияния и регистрации - мы думаем добавить это и в Mercurial.