Когда SVN не удается объединить и Mercurial успешно - PullRequest
19 голосов
/ 12 февраля 2011

До его появления я уже просмотрел несколько тем на эту тему, в том числе:

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

Один из моих "плюсов" в том, что в Mercurial слияние лучше, но пока я не могу найти убедительных доказательств этого. А именно, на HgInit.com есть заявление, которое я не смог проверить:

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

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

Я создал хранилище Mercurial, создал Hello World, а затем клонировал его. В одном я изменил функцию, зафиксировал ее, затем переместил, а затем зафиксировал. В другой я просто добавил еще одну строку вывода в функцию и зафиксировал.

Когда я сливаюсь, я получаю тот же самый конфликт слияния, который я получаю, используя Subversion.

Я понял, что mercurial может отслеживать переименования файлов лучше, и что у DVCS есть и другие преимущества, кроме слияния, но мне интересен этот пример. Джоэл Спольски находится за пределами базы или я что-то упустил?

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

Однако слияние Mercurial, похоже, не использует преимущества добавленной информации и, по-видимому, работает так же, как Subversion. Это правильно?

Ответы [ 3 ]

6 голосов
/ 13 февраля 2011

Насколько я знаю, любой, кто говорит, что Mercurial отслеживает перемещение кода меньше, чем куски размером с файл, просто неправ.Он делает отслеживание переименования файла независимо от изменений кода, поэтому, если Дейв переименовывает файл, а Хелен что-то меняет в файле, он может это автоматически объединить, но, насколько я знаю, Subversion тоже может это сделать!(CVS не может.)

Но - это способ, которым логика слияния Mercurial значительно лучше, чем у Subversion: она запоминает разрешение конфликтов.Рассмотрим этот исторический график:

base ---> HELEN1 ---> merge1 --> HELEN2 -> merge2
     \--> DAVE1 ---/                    /
                   \--> DAVE2 ---------/

Хелен и Дейв внесли изменения независимо.Хелен вытащила дерево Дейва и слилась, затем внесла еще одно изменение.Тем временем Дейв продолжал кодировать, не удосужившись оторваться от Хелен.Затем Хелен снова дернула дерево Дэйва.(Возможно, Дейв работает над основной веткой разработки, а Хелен отключена от ветви функций, но она хочет периодически синхронизироваться с изменениями ствола.) При построении «merge2», Mercurial запоминает все разрешения конфликтов, выполненные в «merge1».и только показывает, что Хелен новые конфликты, но Subversion заставит Хелен снова и снова выполнять слияние с нуля.(Есть способы, которыми вы можете избежать этого с Subversion, но все они включают дополнительные ручные шаги. Mercurial справится с этим за вас.)

Для получения дополнительной информации прочитайте об алгоритме mark-merge , который был разработан для Monotone и AFAIK, теперь используется и Mercurial, и Git.

1 голос
/ 22 февраля 2011

Две вещи:

  1. Mercurial имеет внутренний код для слияния, и он будет вызывать внешний инструмент слияния только в случае сбоя внутреннего "предварительного слияния".

    Вы ссылаетесь на Книгу HG , и там говорится, что нет встроенного инструмента для обработки конфликтов (не то же самое, что встроенное слияние) и Mercurial wiki где указано, что Mercurial попытается выполнить слияния внутри перед вызовом внешних программ.

  2. Вы ссылаетесь на вопрос, где мой ответ приводит явный случай, когда Mercurials успешно завершается, а Subversion завершается неудачно при слиянии. Это стандартное сравнение с использованием внутреннего кода слияния в Mercurial и Subversion.

1 голос
/ 14 февраля 2011

AFAIK, SVN выполняет все слияния внутри себя - инструменты слияния существуют только для случаев, когда существует конфликт, поскольку (очевидно) он должен сообщить вам об этом и заставить вас исправить его.

Бесконфликтные случаи основаны на применении исправлений - то есть svn примет изменения, внесенные вами в ревизию, и применит их к цели. Последние версии SVN (начиная с 1.5) запоминают слияния, которые вы делали ранее, сохраняя эту информацию в свойстве, связанном с каталогом. 1.6 намного лучше справляется с этими свойствами по сравнению с 1.5.

SVN не объединяется путем сравнения двух деревьев и их различий - см. Книгу - за исключением случаев, когда деревья для объединения не связаны, только тогда он выполнит введите операцию слияния (или вы указываете опцию --ignore-ancestry). Вот краткое описание того, что происходит. Вы можете увидеть это при слиянии прошлых конфликтов - после того, как вы решили сложное слияние ревизий, svn запомнит, какие ревизии были слиты, и применит эти изменения снова. Вы можете доказать это, попробовав это - разветвить, отредактировать 2 файла, объединить, чтобы получить конфликт. Отредактируйте разветвленный файл только в той же строке, затем объедините - он вызовет конфликт, даже если целевой файл не изменился, а потому, что объединение применяет изменение в строке, которая была изменена по сравнению с ожидаемой разветвленным файлом ( то есть точно так же, как патч, который показывает то, что, по его мнению, должна была быть линия, которую он собирается изменить) На практике вы этого не видите, поскольку не склонны неоднократно отклонять изменения слияния.

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

...