Почему ветвление и слияние проще в Mercurial, чем в Subversion?

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

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

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

Должно быть фундаментальное различие в том, как все это работает.

Ответ 1

В Subversion (и CVS) репозиторий - это прежде всего. В gitи mercurial на самом деле нет концепции репозитория в так же; здесь изменения являются центральной темой.

+ 1

Сложность в CVS/SVN возникает из-за того, что эти системы не помните родительские изменения. В Git и Mercurial, он может не только иметь несколько детей, но и иметь несколько родители!

Это можно легко увидеть с помощью одного из графических инструментов gitk или hg view. В следующем примере ветка # 2 была разветвлена ​​из # 1 в commit A, и с тех пор был объединен один раз (в M, объединен с commit 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 происходят от того, сколько коммитов было свернуто вместе - создание история гораздо более непроницаема.

Хуже того, выполнение второго слияния становится кошмаром: нужно выяснить что база слияния находилась во время первого слияния (и нужно знать что произошло слияние в первую очередь!), то представить эту информацию в инструмент, чтобы он не пытался воспроизвести A..B на вершина М. Все это достаточно сложно при работе в тесном сотрудничестве, но просто невозможно в распределенной среде.

A (связанная) проблема заключается в том, что нет способа ответить на вопрос: "делает ли X содержат B? ", где B является потенциально важное исправление ошибок. Итак, почему бы просто не записать эту информацию в фиксации, поскольку это известно во время слияния!

П.-S. - У меня нет опыта с возможностями записи слияния SVN 1.5+, но рабочий процесс кажется намного более чем в распределенных системах. Если это действительно так, вероятно, потому, что, как упоминалось в приведенном выше комментарии - основное внимание уделяется организации репозитория, а не самим изменениям.

Ответ 2

Поскольку Subversion (по крайней мере, версия 1.4 и ниже) не отслеживает, что было объединено. Для Subversion слияние в основном такое же, как и любое фиксация, в то время как в другом управлении версиями, например Git, то, что было объединено, запоминается.

Ответ 3

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

Например, если я изменяю функцию a немного, а затем переместите его где-нибудь еще, Subversion не действительно помните эти шаги, поэтому, когда это произойдет время, чтобы слиться, может показаться, что новая функция только что появилась из синий. В то время как Mercurial будет помнить эти вещи отдельно: функция изменено, функция перемещена, что означает что если вы также изменили эту функцию немного, это гораздо более вероятно что Mercurial успешно объединит наши изменения.

Конечно, помня о том, что было в прошлом объединено (точка, на которую ссылается большинство ответов, представленных здесь), также является огромной победой.

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

Ответ 4

Я предполагаю, что это может быть частично связано с тем, что Subversion имеет идею центрального сервера вместе с абсолютной временной строкой ревизий. Mercurial действительно распределен и не имеет такой ссылки на абсолютную линию времени. Это позволяет проектам Mercurial создавать более сложные иерархии веток для добавления функций и циклов тестирования по субпроекту, однако командам теперь нужно гораздо активнее удерживать верх над слияниями, чтобы оставаться в силе, поскольку они не могут просто нажать обновление и сделать с ним.

Ответ 5

В Subversion (и CVS) репозиторий - это прежде всего. В git и mercurial на самом деле не существует понятия репозитория таким же образом; здесь изменения являются центральной темой.

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

Ответ 6

У меня есть опыт работы с Subversion, но могу сказать, что экран слияния в TortoiseSVN ужасно сложный. К счастью, они включают кнопку сухого хода, чтобы вы могли видеть, правильно ли вы это делаете. Усложнение заключается в настройке того, что вы хотите слить туда. Как только вы получите настройку для слияния, слияние обычно прекращается. Затем вам необходимо разрешить любые конфликты и затем скопировать их в рабочую копию в репозиторий.

Если Mercurial может упростить конфигурацию слияния, я могу сказать, что слияние на 100% проще, чем Subversion.