Подтвердить что ты не робот

Когда SVN не сливается, и Mercurial преуспевает

Прежде чем он появится, я уже рассмотрел несколько тем по этой теме, включая следующие:

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

Две вещи:

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

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

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