Что делает некоторые системы контроля версий лучше при слиянии?

Я слышал, что многие из распределенных VCS (git, mercurial и т. Д.) Лучше объединяются, чем традиционные, такие как Subversion. Что это значит? Какие вещи они делают, чтобы сделать слияние лучше? Могут ли эти вещи быть сделаны в традиционных VCS?

Бонусный вопрос: отслеживает ли слияние SVN 1.5 уровень игры вообще?

5 ответов

Решение

Большинство ответов, кажется, о Subversion, так что здесь у вас есть один о Git (и других DVCS).

В распределенной системе управления версиями, когда вы объединяете одну ветку в другую, вы создаете новый коммит слияния, который запоминает, как вы разрешили слияние, и помнит всех родителей слияния. Эта информация просто отсутствовала в Subversion до версии 1.5; для этого вам пришлось использовать дополнительные инструменты, такие как SVK или svnmerge. Эта информация очень важна при повторном объединении.

Благодаря этой информации распределенные системы контроля версий (DVCS) могут автоматически находить общего предка (или общих предков), также известного как база слияния, для любых двух ветвей. Посмотрите на схему изменений ASCII-арт ниже (я надеюсь, что она не стала слишком ужасно искаженной),

--- O --- * --- * ---- М ---*---*---1
     \                /
       \---*--- А /- *----2

Если мы хотим объединить ветвь "2" в ветвь "1", общим предком, который мы хотели бы использовать для создания слияния, была бы версия (commit), помеченная "A". Однако, если система контроля версий не записывает информацию о родителях слияния ("M" - это предыдущее слияние тех же ветвей), она не сможет найти коммит "A" и найдет коммит "O". как общий предок (база слияния) вместо этого... который повторял бы уже включенные изменения и приводил к большому конфликту слияния.

Распределенная система контроля версий должна была делать это правильно, то есть они должны были сделать слияние очень простым (без необходимости отмечать / помечать родителей слияния и предоставлять информацию о слиянии вручную) с самого начала, потому что это был способ заставить кого-то другого получить код В проект входило не предоставление ему / ей доступа к коммитам, а извлечение из его / ее репозитория: получение коммитов из другого репозитория и выполнение слияния.

Вы можете найти информацию о слиянии в Subversion 1.5. в примечаниях к выпуску Subversion 1.5. Замечания: вам нужны другие (!) Опции для слияния ветки с транком, чем слияние транка с веткой, иначе. не все ветви равны (в распределенных системах контроля версий они [обычно] технически эквивалентны).

Возможности слияния SVN достойны, и простые сценарии слияния работают нормально - например, ветвь релиза и транк, где транк отслеживает коммиты на RB.

Более сложные сценарии усложняются быстро. Например, давайте начнем со стабильной ветви (stable) а также trunk,

Вы хотите продемонстрировать новую функцию и предпочитаете использовать ее stable как это, ну, более стабильно, чем trunk, но вы хотите, чтобы все ваши коммиты распространялись на trunk а остальные разработчики все еще исправляют stable и развитие вещей на trunk,

Итак, вы создаете demo ветвь, и график слияния выглядит так:

  • stable -> demo -> trunk (вы)
  • stable -> trunk (другие разработчики)

Но что происходит, когда вы объединяете изменения из stable в demoзатем объединить demo в trunkв то время как другие разработчики все время также объединяются stable в trunk? SVN путается с слияниями из stable будучи дважды объединенным в trunk,

Есть способы обойти это, но с git/Bazaar/Mercurial это просто не происходит - они понимают, были ли коммиты уже объединены, потому что они идентифицируют каждый коммит по путям слияния, которые он принимает.

Отслеживание слияния в 1.5 лучше, чем отсутствие отслеживания слияний, но это все еще очень ручной процесс. Мне нравится, как он записывает, какие обороты есть, а какие нет, но его нет почти идеально.

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

Если вы сделаете это по частям, SVN запомнит то, что вы ранее сказали о слиянии, что позволит вам слиться. Я нашел процесс и результат некоторых слияний странным, если не сказать больше...

Эти системы контроля версий могут работать лучше, потому что у них больше информации.

SVN pre-1.5, наряду с большинством VCS до последнего поколения, на самом деле не помнит, что вы где-то слили два коммита. Он помнит, что две ветви имеют общего предка, когда они впервые разветвились, но он не знает ни о каких недавних слияниях, которые могли бы использоваться в качестве точки соприкосновения.

Я ничего не знаю о SVN post 1.5, поэтому, возможно, они улучшили это.

Непростой ответ: почему некоторые языки программирования лучше в тексте / математике, чем другие?

Реальный ответ: потому что они должны быть. Распределенные VCS делают большую часть этого слияния в точке, где ни один из авторов конфликтующего кода не может настроить слияние вручную, потому что слияние выполняется третьей стороной. В результате инструмент слияния должен делать это правильно большую часть времени.

В контракте с SVN вы делаете что-то напуганное (и неправильное?), Если вы когда-нибудь сливаетесь с тем, что не написали ни с одной, ни с другой стороны.

IIRC большинство VCS могут выложить слияние на то, что вы просите их использовать, поэтому (теоретически) ничто не мешает SVN использовать механизмы слияния GIT/mercurial. YMMV

Другие вопросы по тегам