Почему в 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)

Обратите внимание, что у 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. Все это достаточно сложно при работе в тесном сотрудничестве, но просто невозможно в распределенной среде.

Связанная с этим проблема заключается в том, что нет способа ответить на вопрос: «содержит ли X B?» где B - потенциально важное исправление ошибки. Так почему бы просто не записать эту информацию в коммит, поскольку она известна во время слияния!

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

Дэмиен Дидерен
источник
6
SVN 1.5+ действительно помещает свойство SVN в коммит слияния M, в котором перечислены слитые коммиты, которые он содержит, другими словами AB. Значит, у вас такая же информация.
Simon D
Вроде. Технически, отслеживание слияния SVN сродни тому, что Git называет «подбором вишен», с дополнительным волшебством, упрощающим работу пользователя; он семантически отличается от того, что делают Git, Hg и Bzr при слиянии. Думаю, на практике это не имеет большого значения, если вы не заботитесь о DAG ( eagain.net/articles/git-for-computer-scientists ).
Дэмиен Дидерен,
2
Горе, что нет кнопки +100. Спасибо.
Чарли Флауэрс
Я предполагаю, что функция 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.

RedWolves
источник