Что упрощает слияние в DVCS?

Я читал в Joel on Software:

При распределенном управлении версиями распределенная часть на самом деле не является самая интересная часть.

Интересная часть состоит в том, что эти системы думают с точки зрения изменений, а не с точки зрения версий.

и HgInit:

Когда нам нужно объединиться, Subversion пытается взглянуть на оба пересмотра - мой измененный код и измененный кода, и он пытается угадать, как разбить их вместе в одном большом нечестивом беспорядок. Обычно это терпит неудачу, производя страниц и страниц "конфликтов слияния" этот arent действительно конфликтует, просто места, где Subversion не удалось выяснить, что мы сделали.

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

Изучая папку SVN-репозитория, у меня создается впечатление, что Subversion поддерживает каждую ревизию как набор изменений. И из того, что я знаю, Hg использует оба набора изменений и моментальный снимок, а Git использует только моментальный снимок для хранения данных.

Если мое предположение верно, тогда должны быть другие способы, которые упрощают слияние в DVCS. Что это такое?

* Обновление:

  • Меня больше интересует техническая перспектива, но ответы с нетехнической точки зрения приемлемы.
  • Исправления:
    • Концептуальная модель
    • Git основана исключительно на моментальных снимках. Снимки могут храниться как отличия от других снимков, а именно, что различия предназначены исключительно для оптимизации хранилища. - Rafał Dowgird comment
  • С нетехнической точки зрения:
    • Это просто культурно: DVCS не работает вообще, если слияние было трудным, поэтому разработчики DVCS вкладывают много времени и усилий в упрощение слияния. Пользователи CVCS OTOH используются для дрянной слияния, поэтому нет стимулов для разработчиков, чтобы они работали. (Зачем делать что-то хорошее, когда ваши пользователи платят вам одинаково хорошо за что-то дерьмо?)
      ...
      Напомним: вся суть DVCS состоит в том, чтобы иметь много децентрализованных репозиториев и постоянно сливать изменения взад и вперед. Без хорошего слияния DVCS просто бесполезен. CVCS, тем не менее, все еще может выжить с дерьмовым слиянием, особенно если поставщик может заставить своих пользователей избегать ветвления. - Jörg W Mittag ответ
  • С технической точки зрения:
    • Запись реальной DAG истории помогает! Я думаю, что основное различие заключается в том, что CVCS не всегда записывал слияние в качестве набора изменений с несколькими родителями, теряя некоторую информацию. - tonfa comment
    • из-за отслеживания слияния и тем более фундаментальным фактом, что каждая ревизия знает своих родителей.... Когда каждая ревизия (каждая фиксация), в том числе слияние, знает своих родителей (для фиксации слияния, что означает наличие/запоминание более одного родителя, т.е. Отслеживание слиянием), вы можете восстановить диаграмму (DAG = Direct Acyclic Graph) ревизии история. Если вы знаете график изменений, вы можете найти общего предка коммитов, которые хотите объединить. И когда ваш DVCS знает, как найти общий предок, вам не нужно указывать его как аргумент, например, в CVS.
      .
      Обратите внимание, что может существовать более одного общего предка из двух (или более) коммитов. Git использует так называемую "рекурсивную" стратегию слияния, которая объединяет базы слияния (общий предок) до тех пор, пока вы не останетесь с одним виртуальным/эффективным общим предком (в некотором упрощении) и сможете сделать простой трехсторонний слияние. - Jakub Narębski ответить

Проверьте также Как и/или почему слияние в Git лучше, чем в SVN?

Ответ 1

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

Когда каждая ревизия (каждая фиксация), в том числе слияние, знает своих родителей (для фиксации слияния, что означает наличие/запоминание более одного родителя, т.е. отслеживание слияния), вы можете восстановить диаграмму (DAG = Direct Acyclic Graph) ревизии история. Если вы знаете график изменений, вы можете найти общего предка коммитов, которые хотите объединить. И когда ваш DVCS знает, как найти общий предок, вам не нужно указывать его в качестве аргумента, как, например, в CVS.

Обратите внимание, что может существовать более одного общего предка из двух (или более) коммитов. Git использует так называемую "рекурсивную" стратегию слияния, которая объединяет базы слияния (общий предок) до тех пор, пока вы не останетесь с одним виртуальным/эффективным общим предком (в некотором упрощении) и сможете сделать простой трехсторонний слияние.

Git было создано использование определения переименования, чтобы иметь возможность обрабатывать слияния, включающие переименования файлов. (Это поддерживает аргумент Jörg W Mittag о том, что DVCS лучше поддерживает слияние, потому что они должны были иметь его, поскольку слияния гораздо более распространены, чем в CVCS с его слиянием, скрытым в 'update 'в рабочем процессе update-then-commit, cf Общие сведения о контроле версий (WIP) Эрик С. Раймонд).

Ответ 2

В DVCS нет ничего особенного, упрощающего слияние. Это просто культурно: DVCS вообще не работает, если слияние было сложным, поэтому разработчики DVCS вкладывают много времени и усилий в упрощение слияния. Пользователи CVCS OTOH используются для дрянной слияния, поэтому нет стимулов для разработчиков, чтобы они работали. (Зачем делать что-то хорошее, когда ваши пользователи платят вам одинаково хорошо за что-то дерьмо?)

Линус Торвальдс сказал в одном из своих интервью Git, что, когда он использовал CVS в Transmeta, они отложили целую неделю в течение цикла разработки для слияния. И все просто приняли это как нормальное положение дел. В настоящее время, во время окна слияния, Linus делает сотни слияний всего за несколько часов.

CVCS могут иметь столь же хорошие возможности слияния, как и DVCS, если пользователи CVCS просто отправились к своим поставщикам и сказали, что это дерьмо неприемлемо. Но они попадаются в парадоксе Blub: они просто не знают, что это неприемлемо, потому что они никогда не видели рабочей системы слияния. Они не знают, что там что-то лучше.

И когда они пробуют DVCS, они магически приписывают всю доброту части "D".

Теоретически, из-за централизованного характера CVCS должен обладать лучшими возможностями слияния, поскольку они имеют глобальный взгляд на всю историю, в отличие от DVCS, каждый репозиторий имеет только крошечный фрагмент.

Напомним: вся точка DVCS состоит в том, чтобы иметь много децентрализованных репозиториев и постоянно сменять изменения взад и вперед. Без хорошего слияния DVCS просто бесполезен. CVCS, однако, все еще может выживать с дрянным слиянием, особенно если поставщик может заставить своих пользователей избегать ветвления.

Итак, как и все остальное в разработке программного обеспечения, это вопрос усилий.

Ответ 3

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

Однако, возможно, еще более важным отличием является то, что, поскольку у вас есть локальный репозиторий, вы можете совершать частые мелкие коммиты, а также часто вытягивать и объединять входящие изменения. Это вызвано более "человеческим фактором", различиями в том, как человек работает с централизованным VCS по сравнению с DVCS.

С SVN, если вы обновляете и возникают конфликты, SVN объединит то, что может, и вставляет маркеры в ваш код, где он не может. Большая проблема заключается в том, что ваш код больше не будет работать в работоспособном состоянии, пока вы не разрешите все конфликты.

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

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

И если возникнет конфликт, вы можете отложить слияние и сделать это на свой досуг. Это, в частности, делает слияние настолько менее раздражающим.

Ответ 4

Эй, атака эссе с 5 пунктами!

Короче говоря, ничто не облегчает. Это сложно, и мой опыт показывает, что ошибки происходят. Но:

  • DVCS заставляет вас иметь дело с слиянием, а это означает, что вы потратите несколько минут, чтобы ознакомиться с инструментами, которые существуют, чтобы помочь вам. Это само по себе помогает.

  • DVCS рекомендует вам часто объединяться, что тоже помогает.

Фрагмент hginit, который вы цитировали, утверждая, что Subversion не может выполнить трехсторонние слияния и что Mercurial сливается, просматривая все изменения в обеих ветвях, просто ошибочен в обоих подсчетах.

Ответ 5

Один момент заключается в том, что слияние svn тонко нарушается; см. http://blogs.open.collab.net/svn/2008/07/subversion-merg.html Я подозреваю, что это связано с svn record mergeinfo даже при слиянии вишни. Добавьте несколько простых ошибок при обработке пограничных случаев и svn, поскольку текущий ребенок плаката CVCS делает их плохо выглядящими, в отличие от всех DVCS, которые только что получили его.

Ответ 6

Я думаю, что DAG наборов изменений, как упоминалось другими, имеет большое значение. DVCS: es требуют разбиения истории (и слияния) на фундаментальном уровне, тогда как я полагаю, CVCS: es (которые старше), когда они построены с первого дня, чтобы сначала отслеживать версии и файлы, при этом добавление поддержки слияния добавляется в качестве запоздалой мысли.

Итак:

  • Слияние легко выполнять и отслеживать, когда теги/ветки отслеживаются отдельно от дерева каталогов источников, поэтому все репо можно объединить за один раз.
  • Поскольку у DVCS: es есть локальные репозитории, их легко создать, поэтому легко поддерживать разные модули в разных репозиториях, а не отслеживать их все в большом репо. (поэтому объединения в репо не приводят к тем же нарушениям, что и в svn/cvs, где одно репо часто содержит множество несвязанных модулей, которые должны иметь отдельные истории слияния.)
  • CVS/SVN позволяет различным файлам в рабочем каталоге поступать из разных версий, в то время как DVCS: обычно имеет одну ревизию для всего WC, всегда (т.е. даже если файл будет возвращен к более ранней версии, он покажет как изменено в статусе, так как оно отличается от файла в проверенной ревизии. SVN/CVS не показывает это всегда.)

Смешение этих понятий (как это делает Subversion) - это, я считаю, большая ошибка. Например, имеет ветки/теги внутри исходного дерева, поэтому вам нужно отслеживать, какие изменения файлов были объединены с другими файлами. Это явно более сложно, чем просто отслеживать, какие изменения были объединены.

Итак, подводя итог:

  • DVCS: нужны простые слияния, на их основе есть набор функций. Решение по дизайну, в котором сделано так, что эти слияния легко выполнять и отслеживать (через DAG), и другие функции (ветки/метки/подмодули) реализованы в соответствии с этим, а не наоборот.
  • CVCS: es имел некоторые функции с самого начала (например, модули), которые делали некоторые вещи легкими, но сделать слияния репо очень сложными для реализации.

По крайней мере, это то, что я чувствую из своего опыта с cvs, svn, git и hg. (Вероятно, есть и другие CVCS: es, которые тоже получили эту вещь.)

Ответ 7

Одна вещь, которую я нахожу проще с DVCS, заключается в том, что каждый разработчик может объединить свои собственные изменения, в которые когда-либо захоронен репозиторий. Гораздо проще обрабатывать конфликты слияния, когда вы объединяете свой собственный код. Я работал в тех местах, где у какой-то бедной души возникали конфликты слияния, когда они находили каждого разработчика.

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

Довольно классный материал.

Ответ 8

Как историческая заметка, теперь архаичная система PRCS также знает об общих предках и может эффективно сливаться, хотя это не было (он был построен поверх файлов RCS!). Это означало, что его можно было эффективно перенести на git, сохранив при этом историю.

Ответ 9

Возможно, пользователи DVCS никогда не будут делать то, что сильно сливается, как рефакторинг, которые меняют и переименовывают/копируют большинство файлов в проекте или перепроектируют из интерфейсов stratch API, которые используются в файлах hundrends.