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

StackOverflow https://stackoverflow.com/questions/43995

Вопрос

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

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

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

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

Это было полезно?

Решение

В 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 - потому что это было записано в commit 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 , ни о сколько их было коммиты были свернуты вместе, что сделало историю намного более непроницаемой.

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

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

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

Другие советы

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

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

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

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

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

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

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

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

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

Если Mercurial может упростить настройку слияния, то я могу сказать, что это сделало бы слияние на 100% проще, чем Subversion.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top