Mesclar (controle de versão) - Merge (version control)

Exemplo de gráfico de histórico de um projeto controlado por versão, com mesclagens como setas vermelhas

No controle de versão , a fusão (também chamada de integração) é uma operação fundamental que reconcilia várias alterações feitas em uma coleção de arquivos controlada por versão. Na maioria das vezes, é necessário quando um arquivo é modificado em duas ramificações independentes e subsequentemente mesclado. O resultado é uma única coleção de arquivos que contém os dois conjuntos de alterações.

Em alguns casos, a mesclagem pode ser executada automaticamente, porque há informações de histórico suficientes para reconstruir as alterações e as alterações não entram em conflito . Em outros casos, uma pessoa deve decidir exatamente o que os arquivos resultantes devem conter. Muitas ferramentas de software de controle de revisão incluem recursos de mesclagem.

Tipos de mesclagem

Existem dois tipos de mesclagem: automática e manual.

Mesclagem automática

A mesclagem automática é o que o software de controle de versão faz quando reconcilia as alterações que ocorreram simultaneamente (em um sentido lógico). Além disso, outras peças de software implantam mesclagem automática se permitirem a edição do mesmo conteúdo simultaneamente. Por exemplo, a Wikipedia permite que duas pessoas editem o mesmo artigo ao mesmo tempo; quando o último colaborador salva, suas alterações são mescladas no artigo em vez de sobrescrever o conjunto de alterações anterior.

Mesclagem manual

A mesclagem manual é o que as pessoas precisam recorrer (possivelmente com a ajuda de ferramentas de mesclagem) quando precisam reconciliar arquivos diferentes. Por exemplo, se dois sistemas têm versões ligeiramente diferentes de um arquivo de configuração e um usuário deseja ter o que há de bom em ambos, isso geralmente pode ser feito mesclando os arquivos de configuração manualmente, escolhendo as alterações desejadas de ambas as fontes (isso também é chamada de fusão bidirecional). A mesclagem manual também é necessária quando a mesclagem automática resulta em um conflito de mudança; por exemplo, muito poucas ferramentas de mesclagem automática podem mesclar duas alterações na mesma linha de código (digamos, uma que altera o nome de uma função e outra que adiciona um comentário). Nestes casos, os sistemas de controle de revisão recorrem ao usuário para especificar o resultado pretendido da fusão.

Algoritmos de mesclagem

Existem muitas abordagens diferentes para a mesclagem automática, com diferenças sutis. Os algoritmos de mesclagem mais notáveis ​​incluem mesclagem de três vias, mesclagem de três vias recursiva, aplicação de patch difuso, mesclagem de tecelagem e comutação de patch.

Mesclagem de três vias

Diagrama de uma fusão de três vias
C é a origem, A e B são derivados de C e D é a nova versão de saída

Uma mesclagem de três vias é realizada após uma análise automática de diferença entre um arquivo "A" e um arquivo "B", considerando também a origem, ou ancestral comum, de ambos os arquivos "C". É um método de mesclagem aproximado, mas amplamente aplicável, uma vez que requer apenas um ancestral comum para reconstruir as mudanças que devem ser mescladas.

A mesclagem de três vias procura seções que são iguais em apenas dois dos três arquivos. Nesse caso, há duas versões da seção, e a versão que está no ancestral comum "C" é descartada, enquanto a versão que difere é preservada na saída. Se "A" e "B" concordarem, isso é o que aparece na saída. Uma seção que é a mesma em "A" e "C" produz a versão alterada em "B", e da mesma forma uma seção que é a mesma em "B" e "C" produz a versão em "A".

As seções que são diferentes em todos os três arquivos são marcadas como uma situação de conflito e deixadas para o usuário resolver.

A fusão de três vias é implementada pelo onipresente programa diff3 e foi a inovação central que permitiu a troca de sistemas de controle de revisão baseados em bloqueio de arquivos para sistemas de controle de revisão baseados em fusão. É amplamente utilizado pelo Concurrent Versions System (CVS).

Mesclagem recursiva de três vias

As ferramentas de controle de revisão baseadas em mesclagem de três vias são amplamente difundidas, mas a técnica depende fundamentalmente de encontrar um ancestral comum das versões a serem mescladas.

Existem casos estranhos, particularmente a "mesclagem cruzada", onde um último ancestral comum único das versões modificadas não existe.

O problema de "mesclagem cruzada" no controle de versão do software. Na metade esquerda 2 áreas estão sendo modificadas, e . e são versões modificadas sucessivamente. A solução é mostrada na metade direita: um ancestral virtual (o círculo tracejado) é criado.

Felizmente, neste caso, pode-se mostrar que há no máximo dois candidatos a ancestrais, e a mesclagem tripla recursiva constrói um ancestral virtual mesclando primeiro os ancestrais não únicos. Essa mesclagem pode ter o mesmo problema, portanto, o algoritmo os mescla recursivamente . Como existe um número finito de versões no histórico, o processo tem a garantia de terminar. Essa técnica é usada pela ferramenta de controle de revisão Git .

(A implementação de mesclagem recursiva do Git também lida com outros casos estranhos, como um arquivo sendo modificado em uma versão e renomeado em outra, mas essas são extensões para sua implementação de mesclagem de três vias; não faz parte da técnica para encontrar três versões para mesclar.)

A mesclagem tripla recursiva só pode ser usada em situações em que a ferramenta tem conhecimento sobre o grafo acíclico direcionado por ancestralidade total (DAG) das derivadas a serem mescladas. Conseqüentemente, não pode ser usado em situações em que os derivativos ou fusões não especificam totalmente sua (s) controladora (s).

Aplicação de patch difuso

Um patch é um arquivo que contém uma descrição das alterações em um arquivo. No mundo Unix, existe uma tradição de disseminar as alterações em arquivos de texto como patches no formato que é produzido por " diff -u". Esse formato pode então ser usado pelo programa de patch para reaplicar (ou remover) as alterações em (ou de) um arquivo de texto ou uma estrutura de diretório contendo arquivos de texto.

No entanto, o programa de patch também possui alguns recursos para aplicar o patch em um arquivo que não é exatamente semelhante ao arquivo de origem que foi usado para produzir o patch. Esse processo é chamado de aplicação de patch fuzzy e resulta em uma espécie de mesclagem de três vias assimétrica, em que as alterações no patch são descartadas se o programa de patch não encontrar um lugar para aplicá-las.

Como o CVS começou como um conjunto de scripts no diff3 , o GNU arch começou como um conjunto de scripts no patch. No entanto, a aplicação de patch difuso é um método relativamente não confiável, às vezes aplicando mal os patches que têm muito pouco contexto (especialmente aqueles que criam um novo arquivo), às vezes se recusando a aplicar exclusões que ambos os derivados fizeram.

Comutação de patch

A comutação de patch é usada no Darcs para mesclar mudanças e também é implementada no git (mas chamada de "rebasing"). A fusão de comutação do patch significa alterar a ordem dos patches (ou seja, descrições das alterações) de forma que formem um histórico linear. Com efeito, quando dois patches são feitos no contexto de uma situação comum, após a fusão, um deles é reescrito de forma que pareça ter sido feito no contexto do outro.

A comutação de patch requer que as mudanças exatas que fizeram os arquivos derivados sejam armazenadas ou possam ser reconstruídas. A partir dessas mudanças exatas, é possível calcular como um deles deve ser alterado para rebase no outro. Por exemplo, se o patch A adiciona a linha "X" após a linha 7 do arquivo F e o patch B adiciona a linha "Y" após a linha 310 do arquivo F, B deve ser reescrito se for realocado em A: a linha deve ser adicionada em linha 311 do arquivo F, porque a linha adicionada em A compensa os números da linha em um.

A comutação de patch foi muito estudada formalmente, mas os algoritmos para lidar com conflitos de mesclagem na comutação de patch ainda permanecem como questões de pesquisa em aberto. No entanto, pode-se comprovar que a comutação de patch produz resultados de mesclagem "corretos", em que outras estratégias de mesclagem são, em sua maioria, heurísticas que tentam produzir o que os usuários desejam ver.

O programa Unix flipdiff do pacote "patchutils" implementa a comutação de patch para patches tradicionais produzidos por diff -u.

Tecer mesclagem

Weave merge é um algoritmo que não usa um ancestral comum para dois arquivos. Em vez disso, ele rastreia como linhas únicas são adicionadas e excluídas em versões derivadas de arquivos e produz o arquivo mesclado com essas informações.

Para cada linha nos arquivos derivados, weave merge coleta as seguintes informações: quais linhas a precedem, quais a seguem e se ela foi excluída em algum estágio do histórico de qualquer derivada. Se alguma das derivadas teve a linha excluída em algum ponto, ela não deve estar presente na versão mesclada. Para outras linhas, eles devem estar presentes na versão mesclada.

As linhas são classificadas em uma ordem em que cada linha está depois de todas as linhas que a precederam em algum ponto da história e antes de todas as linhas que a seguiram em algum ponto da história. Se essas restrições não fornecem uma ordem total para todas as linhas, então as linhas que não têm uma ordem em relação umas às outras são adições conflitantes.

O Weave merge foi aparentemente usado pela ferramenta de controle de revisão comercial BitKeeper e pode lidar com alguns dos casos problemáticos em que uma fusão de três vias produz resultados errados ou ruins. É também uma das opções de mesclagem da ferramenta de controle de revisão GNU Bazaar e é usada no Codeville .

Veja também

Referências