Что делает некоторые системы контроля версий лучше при слиянии? - PullRequest
29 голосов
/ 20 января 2009

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

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

Ответы [ 5 ]

26 голосов
/ 20 января 2009

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

Более сложные сценарии усложняются быстро. Например, давайте начнем со стабильной ветви (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 это просто не происходит - они понимают, были ли коммиты уже объединены, потому что они идентифицируют каждый коммит по путям слияния, которые он принимает.

19 голосов
/ 28 января 2009

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

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

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

---O---*---*----M---*---*---1
     \                /
       \---*---A/--*----2

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

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

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

4 голосов
/ 20 января 2009

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

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

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

3 голосов
/ 20 января 2009

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

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

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

2 голосов
/ 20 января 2009

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

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

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

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

...