Consequências do uso de enxerto no Mercurial

98

Houve várias perguntas recentemente sobre pular mudanças ao manter ramos de lançamento no Mercurial. Por exemplo:

Desde que foi introduzido no 2.0, tenho pensado em como usá-lo graftpara evitar esse problema. Dada uma árvore de revisão como esta:

A---B---C---D---E---F---G---H---I---J

Suponha que precisemos criar um branch de lançamento que ignore a mudança do Mal E.

hg update -r D
hg graft "F::J"

dando-nos:

A---B---C---D---E---F---G---H---I---J
             \
              --F'--G'--H'--I'--J'
  • Q1: O que aconteceu aqui? Eu posso entender que transplantisso teria gerado patches F::Je depois aplicado D, mas graftdizem que usa mesclagem de 3 vias em vez de patches. Então, como isso funciona? Por que está melhor?

Digamos que agora eu conserte Ee mescle isso em meu branch de lançamento.

                  --E2-----------------
                 /                     \
A---B---C---D---E---F---G---H---I---J---M1
             \                            \
              --F'--G'--H'--I'--J'---------M2--

M1 é uma fusão direta; nada de especial aí. M2 está mesclando ramos que têm "o mesmo" (ou pelo menos equivalente) alterações ativadas.

  • Q2: É este o merge apenas um normal, 3-way merge usando D, J'e M1?
  • P3: O mercurial armazenou / usou informações extras sobre a operação de enxerto para ajudá-lo na fusão?

E finalmente...

  • Q4: Quais são os problemas potenciais com um fluxo como este?
Paul S
fonte

Respostas:

119

Quando você atualiza De enxerta F::J, o Mercurial executa uma série de mesclagens. Vai começar com esta fusão:

M = three_way_merge(local=D, other=F, base=E)

Se escrevermos +dpara o delta entre os estados Ce D, começaremos com:

        +d     +e     +f
---- C ---- D ---- E ---- F ----

Gire o gráfico 90 graus no sentido horário e a mesclagem de três vias acima ficará assim:

    -e  
  .---- D
 /
E
 \
  '---- F
    +f

Ou seja, fingimos que começamos Ee aplicamos o oposto de -echegar a D. Eu penso em como o patch reverso de +e. Começando Etambém fomos para o estado Fcom o delta normal +f. Não há nada de estranho aqui - temos todos os estados ( D, Ee F) no repositório já. Visto assim, fica claro que podemos mesclar De F.

A fusão é uma questão de "completar o diamante". Assim, encontramos um novo estado Mque é uma mistura de De Fonde a diferença de Da Mé semelhante a +fe a diferença de Fa Mé semelhante a -e. Se parece com isso:

    -e     +f'
  .---- D ----.
 /             \
E               M
 \             /
  '---- F ----'
    +f     -e'

O +fdelta se tornou +f'e o -edelta se tornou -e'. Esta é apenas uma mesclagem de três vias normal, mas o efeito é interessante: aplicamos Fem em Dvez de E!

Após a fusão, o segundo pai de Mto Fé eliminado:

    -e     +f'
  .---- D ----.
 /             \
E               M
 \
  '---- F
    +f

Para reiterar: copiamos o "efeito" de Fpara D, ou seja, encontramos um delta ( +f') que se aplica para Ddar o mesmo efeito de quando +ffoi aplicado a E. Podemos endireitar o gráfico um pouco para obter:

       +f'
--- D ---- M
     \
      '---- E ---- F
        +e     +f

O resultado é que Fé enxertado Dusando o maquinário de três vias completo.

  • Q1: O que aconteceu aqui? Então, como isso funciona? Por que está melhor?

    R1: Usar mesclagens é melhor do que patches, pois o mecanismo de mesclagem leva em conta coisas como renomeações.

  • P2: Esta mesclagem é apenas uma mesclagem de 3 vias normal usando D, J 'e M1?

    A2: Sim, o enxerto não altera a topologia do gráfico.

  • P3: O mercurial armazenou / usou informações extras sobre a operação de enxerto para ajudá-lo na fusão?

    A3: Não.

  • Q4: Quais são os problemas potenciais com um fluxo como este?

    A4: De uma perspectiva de mesclagem, deve funcionar bem. Vai duplicar alguma história que pode ser confusa para as pessoas.

Martin Geisler
fonte
4
Ótima pergunta, ótima resposta :). +1 para ambos!
Laurens Holst
Obrigado Martin. Esse é um pensamento muito estranho de quem veio com isso. Tive a ideia, mas preciso resolver o caso geral. Eu estou supondo que isso se aplica, não importa o caminho entre os nós que você está enxertando de / para?
Paul S,
3
@PaulS: Acho que tudo o que você precisa saber é que o enxerto pode copiar os changesets de uma maneira mais robusta do que o transplante. Robusto no sentido de que renomeações são tratadas e que você pode resolver conflitos em uma ferramenta de mesclagem. Os detalhes estão nas estranhas mesclagens que existem, mas isso não é essencial para entender para o uso diário de enxerto! :-)
Martin Geisler
3
Não, mas sou um idiota por tentar entender coisas que não preciso ;-) De qualquer forma, trabalhei em um exemplo mais geral usando o seu como base.
Paul S,
@PaulS Se for assim, estou quase com medo de mencionar isso para você ... mas você pode procurar Darcs e sua teoria de patch. O truque acima sobre girar o gráfico 90 graus me lembra muito de como eles falam sobre patches de deslocamento ao mesclar. Coisas bem cabeludas :-)
Martin Geisler
6

Q1: Ajuda quando há conflitos. Você pode usar sua ferramenta de mesclagem usual então (para mim são marcadores de conflito embutidos, que edito com o modo de mesclagem do Emacs).

P2: É uma mesclagem normal.

Q3: Não.

P4: Acho feio ter dois ramos quase idênticos.

Tocando
fonte