Вопрос

Я использую Mercurial некоторое время, и есть один «факт», который приводится много раз.

На самом деле, меня осенило, когда я вчера смотрел видео, сделанное Fogcreek, это видео:Печь Фог-Крик:Раскройте возможности DVCS для своей компании что, кажется, что-то у меня здесь не работает.

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

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

Я видел упоминание об этом где-то еще, но сейчас не могу найти прямых ссылок.

Кажется, это не работает для меня.


Редактировать:Это проблема стандартной конфигурации инструмента слияния «beyondcompare3» для TortoiseHg.Я добавил приведенную ниже конфигурацию в свой файл Mercurial.ini, и теперь она работает как положено.Конечно, он перейдет к инструменту с графическим интерфейсом, если не сможет автоматически объединиться, но теперь слияние, описанное в этом вопросе здесь, запускается без каких-либо подсказок и просто делает правильные вещи из коробки.

[ui]
merge = bc3

[merge-tools]
bc3.executable = C:\Program Files (x86)\Beyond Compare 3\bcomp.exe
bc3.args = $local $other $base $output /automerge /reviewconflicts /closescript
bc3.priority = 1
bc3.premerge = True
bc3.gui = True

Чтобы проверить это, я зафиксировал этот файл в репозитории:

void Main()
{
    Function1();
    Function2();
}

public void Function1()
{
    Debug.WriteLine("Function 1");
    for (int index = 0; index < 10; index++)
        Debug.WriteLine("f1: " + index);
}

public void Function2()
{
    Debug.WriteLine("Function 1");
}

Затем в двух разных параллельных наборах изменений, вытекающих из этого, я внес следующие два изменения:

  1. Я переместил функцию Function1 в конец файла.
  2. Я изменил сообщение внутри Function1

Затем я попытался выполнить слияние, и Mercurial выдает мне окно конфликта слияния, пытаясь понять, что я сделал.

По сути, он пытается изменить текст в функции 2, который теперь находится в том же положении, в котором была функция 1 до ее перемещения.

Этого не должно было случиться!


Вот исходные файлы для воспроизведения моего примера:

Пакетный файл для создания репозитория:

@echo off

setlocal

if exist repo rd /s /q repo
hg init repo
cd repo

copy ..\example1.linq example.linq
hg commit -m "initial commit" --addremove --user "Bob" --date "2010-01-01 18:00:00"

copy ..\example2.linq example.linq
hg commit -m "moved function" --user "Bob" --date "2010-01-01 19:00:00"

hg update 0
copy ..\example3.linq example.linq
hg commit -m "moved function" --user "Alice" --date "2010-01-01 20:00:00"

Три версии файла: example1.linq, example2.linq и example3.linq:

Пример1.linq:

<Query Kind="Program" />

void Main()
{
    Function1();
    Function2();
}

public void Function1()
{
    Debug.WriteLine("Function 1");
    for (int index = 0; index < 10; index++)
        Debug.WriteLine("f1: " + index);
}

public void Function2()
{
    Debug.WriteLine("Function 1");
}

Пример2.linq:

<Query Kind="Program" />

void Main()
{
    Function1();
    Function2();
}

public void Function2()
{
    Debug.WriteLine("Function 1");
}

public void Function1()
{
    Debug.WriteLine("Function 1");
    for (int index = 0; index < 10; index++)
        Debug.WriteLine("f1: " + index);
}

Пример3.linq:

<Query Kind="Program" />

void Main()
{
    Function1();
    Function2();
}

public void Function1()
{
    Debug.WriteLine("Function 1b");
    for (int index = 0; index < 10; index++)
        Debug.WriteLine("f1: " + index);
}

public void Function2()
{
    Debug.WriteLine("Function 1");
}
Это было полезно?

Решение

Что ж, в настоящее время вы сталкиваетесь с одним из ограничений, по сути, ЛЮБОЙ текущей VCS (DVCS или нет, это не имеет значения).

Дело в том, что системы VCS в настоящее время не зависят от языка, в основе их алгоритма слияния лежит текстовый дифф.Это означает, что они ищут, какие изменения и что с этим связано. контекст.
Важная часть здесь — контекст.Это не более чем несколько строк до и после внесенных вами изменений.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top