Pergunta

Eu uso o Mercurial há um tempo, e há um "fato" que é dado muitas vezes.

De fato, me atingiu enquanto assistia a um vídeo feito por Fogcreek ontem, Este vídeo: Fog Creek Kiln: Desbloqueie o poder dos DVCs para sua empresa Que parece haver algo que não funciona para mim aqui.

Por volta de 1:39 naquele vídeo e em diante, ele faz questão de dizer que, enquanto outros sistemas de controle de versão rastreiam revisões (ou seja, instantâneos), os DVCs, como o Mercurial Track, troca (ou seja, o que aconteceu entre os instantâneos.)

Isso lhes dá uma vantagem na fusão de cenários e depois mostra um exemplo. Se você mover uma função em uma ramificação e alterar a mesma função em outro ramo, o Mercurial poderá mesclar isso.

E eu já vi isso mencionado em outro lugar, embora não consiga encontrar links diretos agora.

Isso não parece funcionar para mim.


EDIT: Este é um problema com a configuração padrão da ferramenta de mesclagem "BeyondCompare3" para o TortoiseHG. Adicionei a configuração abaixo no meu arquivo mercurial.ini e agora ele funciona como esperado. Claro, ele irá para a ferramenta GUI, se não puder automatizar, mas agora a mescla

[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

Para testar isso, comprometi esse arquivo a um repositório:

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");
}

Então, em duas alterações paralelas diferentes se ramificando a partir deste, fiz as duas mudanças a seguir:

  1. Eu movi a função1 função1 para a parte inferior do arquivo
  2. Eu mudei a mensagem dentro da função1

Eu então tentei se fundir, e Mercurial me dá uma janela de conflito de mesclagem, tentando descobrir o que fiz.

Basicamente, ele tenta alterar o texto na função2, que agora está na posição em que a função1 estava antes de ser movida.

Isso não deveria acontecer!


Aqui estão os arquivos de origem para reproduzir meu exemplo:

Arquivo em lote para produzir repositório:

@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"

As 3 versões do arquivo, exemplo1.linq, exemplo2.linq e exemplo3.linq:

Exemplo1.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");
}

Exemplo2.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);
}

Exemplo3.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");
}
Foi útil?

Solução

Bem, você está atualmente atingindo uma das limitações de, basicamente, qualquer VCS atual (DVCs ou não, isso não importa).

O fato é que os VCs são atualmente agnósticos de idioma, a base do algoritmo de mesclagem é um diferencial textual. Isso significa que eles estão procurando qual mudança e qual é o relacionado contexto.
A parte importante aqui é o contexto. Não é mais nada do que algumas linhas antes e depois das mudanças que você fez.

Isso significa que eles são muito ruins em lidar com a reorganização do código dentro de um mesmo arquivo, porque você está basicamente ferindo todo o contexto em que pode confiar.
Normalmente, no seu exemplo, alternando as duas funções, você não apenas inverteu completamente o contexto entre as duas mudanças, mas pior, por não ter linhas extras após a função mais recente, você reduziu implicitamente o contexto da última mudança, diminuindo as chances Que um algoritmo de mesclagem conseguiu descobrir o que você realmente fez.

Atualmente, conheço apenas uma ferramenta diff, de MSFT, para XML, que está tentando lidar com o semântico da sua mudança e não apenas sua representação textual.
Eu também sei que os caras do PLASTICSCM estão tentando implementar esse recurso para alguns idiomas convencionais, mas é realmente um lugar onde há espaço para melhorias.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top