Почему ветвление и слияние легче в Mercurial, чем в Subversion?
Обработка множественных слияний в ветвях в Subversion или CVS - это только одна из тех вещей, которые нужно испытать. В Mercurial (и, вероятно, в любой другой распределенной системе) очень легко отслеживать ветки и слияния, но я не знаю почему. Кто-нибудь еще знает?
Мой вопрос проистекает из того факта, что с Mercurial вы можете использовать рабочую практику, аналогичную той, которая используется в центральном репозитории Subversions/CVS, и все будет работать нормально. Вы можете сделать несколько слияний в одной ветви, и вам не понадобятся бесконечные клочки бумаги с номерами коммитов и именами тегов.
Я знаю, что последняя версия Subversion имеет возможность отслеживать слияния с ветками, так что вы не получите такой же степени хлопот, но это была огромная и серьезная разработка с их стороны, и она все еще не делает все, что могла бы сделать команда разработчиков нравится это делать.
Там должно быть принципиальное различие в том, как все это работает.
6 ответов
В 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)
Обратите внимание, что у A и B двое детей, а у M два родителя. Эти отношения записываются в хранилище. Допустим, сопровождающий ветви № 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)
где M - просто гигантский "сдавленный" коммит всего, что произошло между A и B, примененного сверху M. Обратите внимание, что после того, как дело сделано, не осталось никакого следа (кроме потенциально читабельных комментариев) того, где M не происходило из того, сколько коммитов было свернуто вместе, что делало историю гораздо более непроницаемой.
Хуже того, выполнение второго слияния становится кошмаром: нужно выяснить, какой была база слияния во время первого слияния (и нужно знать, что слияние было в первую очередь!), А затем представить, что информация для инструмента, чтобы он не пытался воспроизвести A..B поверх M. Все это достаточно сложно при работе в тесном сотрудничестве, но просто невозможно в распределенной среде.
(Связанная) проблема заключается в том, что нет способа ответить на вопрос: "содержит ли Х В?" где B- потенциально важное исправление ошибки. Так почему бы просто не записать эту информацию в коммит, поскольку она известна во время слияния!
P.-S. - У меня нет опыта работы с записями слияний SVN 1.5+, но рабочий процесс кажется гораздо более надуманным, чем в распределенных системах. Если это действительно так, то, вероятно, потому, что, как упоминалось в приведенном выше комментарии, основное внимание уделяется организации хранилища, а не самим изменениям.
Потому что Subversion (по крайней мере, версия 1.4 и ниже) не отслеживает то, что было объединено. Для Subversion слияние в основном такое же, как и для любого коммита, в то время как на другом контроле версий, таком как Git, запоминается то, что было слито.
Не тронутый ни одним из уже предоставленных ответов, Hg предложил превосходные возможности слияния, потому что он использует больше информации при слиянии изменений ( hginit.com):
Например, если я немного изменил функцию, а затем переместил ее куда-то еще, Subversion на самом деле не помнит эти шаги, поэтому, когда приходит время слияния, может показаться, что новая функция только что появилась на ровном месте., Принимая во внимание, что Mercurial будет помнить эти вещи отдельно: функция изменена, функция перемещена, что означает, что если вы также немного изменили эту функцию, гораздо более вероятно, что Mercurial успешно объединит наши изменения.
Конечно, запоминание того, что было слито в последний раз (пункт, который рассматривается в большинстве ответов, представленных здесь), также является огромной победой.
Оба усовершенствования, однако, сомнительны, так как Subversion 1.5+ хранит дополнительную информацию о слиянии в форме свойств Subversion: у этой информации нет очевидной причины, почему слияние в Subversion не могло реализовать слияние так же успешно, как Hg или Git. Хотя я не знаю, так ли это, но, похоже, разработчики Subversion уже пытаются обойти эту проблему.
Я предполагаю, что это может быть частично потому, что Subversion имеет идею центрального сервера вместе с абсолютной временной шкалой ревизий. Mercurial действительно распространяется и не имеет такой ссылки на абсолютную временную шкалу. Это позволяет проектам Mercurial формировать более сложные иерархии ветвей для добавления функций и циклов тестирования по подпроектам, однако теперь командам нужно гораздо активнее следить за слияниями, чтобы оставаться в курсе, поскольку они не могут просто выполнить обновление и выполнить его.,
В Subversion (и CVS) хранилище - это прежде всего. В git и mercurial концепция хранилища на самом деле не одинакова; Здесь изменения являются центральной темой.
Я не особо задумывался о том, как бы вы это реализовали, но у меня сложилось впечатление (основываясь на горьком опыте и большом количестве чтения), что именно это различие делает слияние и ветвление намного проще в системах без репозитория.
У меня есть только опыт работы с Subversion, но я могу вам сказать, что экран слияния в TortoiseSVN ужасно сложен. К счастью, они включают кнопку пробного запуска, чтобы вы могли видеть, правильно ли вы это делаете. Сложность заключается в конфигурации того, что вы хотите объединить и куда. После того, как вы настроили слияние, слияние обычно происходит нормально. Затем вам нужно разрешить все конфликты, а затем зафиксировать вашу объединенную рабочую копию в хранилище.
Если Mercurial может упростить настройку слияния, то я могу сказать, что это сделает слияние на 100% легче, чем Subversion.